Add support for the lbarx, lharx, stbcx and sthcs instructions.

The instructions are part of the ISA 2.06 but were not implemented
in all versions of hardware.  The four instructions are all supported
in ISA 2.07.  The instructions were put under the ISA 2.07 category
of supported instructions in this patch.

The VEX commit for this fix is r3137.

The bugzilla for this issue is 346324.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15106 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/memcheck/tests/ppc32/Makefile.am b/memcheck/tests/ppc32/Makefile.am
index bd70eea..e5f52fd 100644
--- a/memcheck/tests/ppc32/Makefile.am
+++ b/memcheck/tests/ppc32/Makefile.am
@@ -5,10 +5,23 @@
 
 EXTRA_DIST = $(noinst_SCRIPTS) \
 	power_ISA2_05.stderr.exp power_ISA2_05.stdout.exp power_ISA2_05.vgtest \
-	power_ISA2_05.stdout.exp_Without_FPPO
+	power_ISA2_05.stdout.exp_Without_FPPO \
+	power_ISA2_07.stdout.exp  power_ISA2_07.stdout.exp-LE \
+	power_ISA2_07.stderr.exp power_ISA2_07.vgtest
 
 check_PROGRAMS = \
-	power_ISA2_05
+	power_ISA2_05 power_ISA2_07
 
 power_ISA2_05_CFLAGS = $(AM_CFLAGS) $(WERROR) -Winline -Wall -Wshadow -g \
 		-I$(top_srcdir)/include @FLAG_M32@
+
+if HAS_ISA_2_07
+	BUILD_FLAGS_ISA_2_07 =  -mhtm -mcpu=power8
+	ISA_2_07_FLAG = -DHAS_ISA_2_07
+else
+	BUILD_FLAGS_ISA_2_07 =
+	ISA_2_07_FLAG =
+endif
+
+power_ISA2_07_CFLAGS = $(AM_CFLAGS) $(WERROR) -Winline -Wall -Wshadow -g \
+		$(ISA_2_07_FLAG)  -I$(top_srcdir)/include @FLAG_M32@
diff --git a/memcheck/tests/ppc64/Makefile.am b/memcheck/tests/ppc64/Makefile.am
index 96eb576..176d680 100644
--- a/memcheck/tests/ppc64/Makefile.am
+++ b/memcheck/tests/ppc64/Makefile.am
@@ -5,10 +5,24 @@
 
 EXTRA_DIST = $(noinst_SCRIPTS) \
 	power_ISA2_05.stderr.exp power_ISA2_05.stdout.exp power_ISA2_05.vgtest \
-	power_ISA2_05.stdout.exp_Without_FPPO
+	power_ISA2_05.stdout.exp_Without_FPPO \
+	power_ISA2_07.stdout.exp  power_ISA2_07.stdout.exp-LE \
+	power_ISA2_07.stderr.exp power_ISA2_07.vgtest
+
 
 check_PROGRAMS = \
-	power_ISA2_05
+	power_ISA2_05 power_ISA2_07
 
 power_ISA2_05_CFLAGS = $(AM_CFLAGS) $(WERROR) -Winline -Wall -Wshadow -g \
 		-I$(top_srcdir)/include @FLAG_M64@
+
+if HAS_ISA_2_07
+        BUILD_FLAGS_ISA_2_07 =  -mhtm -mcpu=power8
+        ISA_2_07_FLAG = -DHAS_ISA_2_07
+else
+        BUILD_FLAGS_ISA_2_07 =
+        ISA_2_07_FLAG =
+endif
+
+power_ISA2_07_CFLAGS = $(AM_CFLAGS) $(WERROR) -Winline -Wall -Wshadow -g \
+               $(ISA_2_07_FLAG)  -I$(top_srcdir)/include @FLAG_M64@
diff --git a/none/tests/ppc32/Makefile.am b/none/tests/ppc32/Makefile.am
index b38efd0..366f5b0 100644
--- a/none/tests/ppc32/Makefile.am
+++ b/none/tests/ppc32/Makefile.am
@@ -40,7 +40,8 @@
 	test_dfp5.stderr.exp test_dfp5.stdout.exp test_dfp5.vgtest \
 	jm_vec_isa_2_07.stderr.exp jm_vec_isa_2_07.stdout.exp jm_vec_isa_2_07.vgtest \
 	jm_fp_isa_2_07.stderr.exp jm_fp_isa_2_07.stdout.exp jm_fp_isa_2_07.vgtest \
-	jm_int_isa_2_07.stderr.exp jm_int_isa_2_07.stdout.exp jm_int_isa_2_07.vgtest \
+	jm_int_isa_2_07.stdout.exp jm_int_isa_2_07.stdout.exp-LE \
+	jm_int_isa_2_07.stderr.exp jm_int_isa_2_07.vgtest \
 	test_isa_2_07_part2.stderr.exp test_isa_2_07_part2.stdout.exp test_isa_2_07_part2.vgtest \
 	test_tm.stderr.exp test_tm.stdout.exp test_tm.vgtest \
 	test_touch_tm.stderr.exp test_touch_tm.stdout.exp test_touch_tm.vgtest \
diff --git a/none/tests/ppc32/jm_int_isa_2_07.stdout.exp b/none/tests/ppc32/jm_int_isa_2_07.stdout.exp
index 21e9af7..ef3b4cf 100644
--- a/none/tests/ppc32/jm_int_isa_2_07.stdout.exp
+++ b/none/tests/ppc32/jm_int_isa_2_07.stdout.exp
@@ -2,8 +2,16 @@
 
 lq (0xaaccee0011335577, 0xabcdef0123456789) =>  (reg_pair = 11335577,23456789)
 
+lbarx (0xaaccee0011335577, 0xabcdef0123456789) =>  (reg_pair = 0x000000aa, 0x00000000)
+
+lharx (0xaaccee0011335577, 0xabcdef0123456789) =>  (reg_pair = 0x0000aacc, 0x00000000)
+
 lqarx (0xaaccee0011335577, 0xabcdef0123456789) =>  (reg_pair = 0x11335577, 0x23456789)
 
+stbcx. 45236789,44226688, =>  8900000000000000,0000000000000001; CR=20000000
+
+sthcx. 45236789,44226688, =>  6789000000000000,0000000000000001; CR=20000000
+
 stqcx. 45236789,44226688, =>  0000000045236789,0000000044226688; CR=20000000
 
-All done. Tested 4 different instructions
+All done. Tested 8 different instructions
diff --git a/none/tests/ppc64/Makefile.am b/none/tests/ppc64/Makefile.am
index 68baacf..d1faca6 100644
--- a/none/tests/ppc64/Makefile.am
+++ b/none/tests/ppc64/Makefile.am
@@ -28,7 +28,8 @@
 	test_dfp5.stderr.exp test_dfp5.stdout.exp test_dfp5.vgtest \
 	jm_vec_isa_2_07.stderr.exp jm_vec_isa_2_07.stdout.exp jm_vec_isa_2_07.vgtest \
 	jm_fp_isa_2_07.stderr.exp jm_fp_isa_2_07.stdout.exp jm_fp_isa_2_07.vgtest \
-	jm_int_isa_2_07.stderr.exp jm_int_isa_2_07.stdout.exp jm_int_isa_2_07.vgtest \
+	jm_int_isa_2_07.stderr.exp jm_int_isa_2_07.vgtest \
+	jm_int_isa_2_07.stdout.exp  jm_int_isa_2_07.stdout.exp-LE \
 	test_isa_2_07_part2.stderr.exp test_isa_2_07_part2.stdout.exp test_isa_2_07_part2.vgtest \
 	test_tm.stderr.exp test_tm.stdout.exp test_tm.vgtest \
 	test_touch_tm.stderr.exp test_touch_tm.stdout.exp test_touch_tm.vgtest \
diff --git a/none/tests/ppc64/jm_int_isa_2_07.stdout.exp b/none/tests/ppc64/jm_int_isa_2_07.stdout.exp
index 0900bdd..e31b973 100644
--- a/none/tests/ppc64/jm_int_isa_2_07.stdout.exp
+++ b/none/tests/ppc64/jm_int_isa_2_07.stdout.exp
@@ -2,8 +2,16 @@
 
 lq (0xaaccee0011335577, 0xabcdef0123456789) =>  (reg_pair = 0xaaccee0011335577, 0xabcdef0123456789)
 
+lbarx (0xaaccee0011335577, 0xabcdef0123456789) =>  (reg_pair = 0x00000000000000aa, 0x0000000000000000)
+
+lharx (0xaaccee0011335577, 0xabcdef0123456789) =>  (reg_pair = 0x000000000000aacc, 0x0000000000000000)
+
 lqarx (0xaaccee0011335577, 0xabcdef0123456789) =>  (reg_pair = 0xaaccee0011335577, 0xabcdef0123456789)
 
+stbcx. abefcd0145236789,1155337744226688 => 8900000000000000,0000000000000001; CR=20000000
+
+sthcx. abefcd0145236789,1155337744226688 => 6789000000000000,0000000000000001; CR=20000000
+
 stqcx. abefcd0145236789,1155337744226688 => abefcd0145236789,1155337744226688; CR=20000000
 
-All done. Tested 4 different instructions
+All done. Tested 8 different instructions
diff --git a/none/tests/ppc64/test_isa_2_07_part1.c b/none/tests/ppc64/test_isa_2_07_part1.c
index 26b7ac2..be0a5ed 100644
--- a/none/tests/ppc64/test_isa_2_07_part1.c
+++ b/none/tests/ppc64/test_isa_2_07_part1.c
@@ -301,8 +301,31 @@
     { NULL,                   NULL,          },
 };
 
-
+#ifdef HAS_ISA_2_07
 Word_t * mem_resv;
+static void test_stbcx(void)
+{
+  /* Have to do the lbarx to the memory address to create the reservation
+   * or the store will not occur.
+   */
+  __asm__ __volatile__ ("lbarx  %0, %1, %2" : :"r" (r14), "r" (r16),"r" (r17));
+  r14 = (HWord_t) 0xABEFCD0145236789ULL;
+  r15 = (HWord_t) 0x1155337744226688ULL;
+  __asm__ __volatile__ ("stbcx. %0, %1, %2" : :"r" (r14), "r" (r16),"r" (r17));
+}
+
+static void test_sthcx(void)
+{
+  /* Have to do the lharx to the memory address to create the reservation
+   * or the store will not occur.
+   */
+  __asm__ __volatile__ ("lharx  %0, %1, %2" : :"r" (r14), "r" (r16),"r" (r17));
+  r14 = (HWord_t) 0xABEFCD0145236789ULL;
+  r15 = (HWord_t) 0x1155337744226688ULL;
+  __asm__ __volatile__ ("sthcx. %0, %1, %2" : :"r" (r14), "r" (r16),"r" (r17));
+}
+#endif
+
 static void test_stqcx(void)
 {
   /* Have to do the lqarx to the memory address to create the reservation
@@ -315,16 +338,34 @@
 }
 
 static test_t tests_stq_ops_three[] = {
+#ifdef HAS_ISA_2_07
+    { &test_stbcx           , "stbcx.", },
+    { &test_sthcx           , "sthcx.", },
+#endif
     { &test_stqcx           , "stqcx.", },
     { NULL,                   NULL,           },
 };
 
+#ifdef HAS_ISA_2_07
+static void test_lbarx(void)
+{
+  __asm__ __volatile__ ("lbarx  %0, %1, %2, 0" : :"r" (r14), "r" (r16),"r" (r17));
+}
+static void test_lharx(void)
+{
+  __asm__ __volatile__ ("lharx  %0, %1, %2, 0" : :"r" (r14), "r" (r16),"r" (r17));
+}
+#endif
 static void test_lqarx(void)
 {
   __asm__ __volatile__ ("lqarx  %0, %1, %2, 0" : :"r" (r14), "r" (r16),"r" (r17));
 }
 
 static test_t tests_ldq_ops_three[] = {
+#ifdef HAS_ISA_2_07
+    { &test_lbarx           , "lbarx", },
+    { &test_lharx           , "lharx", },
+#endif
     { &test_lqarx           , "lqarx", },
     { NULL,                   NULL,           },
 };