Skip to contentSkip to conversation

Fix ppc64 tcg issues

PATCH In review Anton Blanchard 2 participants 11 messages Jun 2, 2013 – Jun 11, 2013

lore
Share & tools
lore
#0 lore raw

cover Fix ppc64 tcg issues

Hi,

qemu is currently broken on ppc64. After applying the following patches I am able to boot a ppc64 and x86-64 image successfully.

Anton

#1 lore raw

PATCH 1/4 tcg-ppc64: Fix RLDCL opcode

The rldcl instruction doesn't have an sh field, so the minor opcode of 8 is actually 4 when using the XO30 macro.

---

tcg/ppc64/tcg-target.c +1 -1
Index: b/tcg/ppc64/tcg-target.c
===================================================================
@@ -357,7 +357,7 @@ static int tcg_target_const_match (tcg_t
 #define RLDICL XO30(  0)
 #define RLDICR XO30(  1)
 #define RLDIMI XO30(  3)
-#define RLDCL  XO30(  8)
+#define RLDCL  XO30(  4)
 
 #define BCLR   XO19( 16)
 #define BCCTR  XO19(528)
#2 lore raw

Re: [Qemu-devel] [PATCH 1/4] tcg-ppc64: Fix RLDCL opcode

Quoted 12 lines · Anton Blanchard

The rldcl instruction doesn't have an sh field, so the minor opcode of 8 is actually 4 when using the XO30 macro.

---

Index: b/tcg/ppc64/tcg-target.c
===================================================================

tcg/ppc64/tcg-target.c static int tcg_target_const_match (tcg_t · line 360

Quoted 5 lines
tcg/ppc64/tcg-target.c +1 -1
@@ -357,7 +357,7 @@ static int tcg_target_const_match (tcg_t
 #define RLDICL XO30(  0)
 #define RLDICR XO30(  1)
 #define RLDIMI XO30(  3)
-#define RLDCL  XO30(  8)
+#define RLDCL  XO30(  4)

Oops.

But that suggests then that we ought not be using XO30. Or at least adding a comment.

r~

#3 lore raw

Re: [Qemu-devel] [PATCH 1/4] tcg-ppc64: Fix RLDCL opcode

Hi Richard,

Quoted 2 lines

But that suggests then that we ought not be using XO30. Or at least adding a comment.

Good idea, how does this look?

Anton
--

The rldcl instruction doesn't have an sh field, so the minor opcode is shifted 1 bit. We were using the XO30 macro which shifted the minor opcode 2 bits.

Remove XO30 and add MD30 and MDS30 macros which match the Power ISA categories.

---

tcg/ppc64/tcg-target.c +6 -5
Index: b/tcg/ppc64/tcg-target.c
===================================================================
@@ -308,7 +308,8 @@ static int tcg_target_const_match (tcg_t
 
 #define OPCD(opc) ((opc)<<26)
 #define XO19(opc) (OPCD(19)|((opc)<<1))
-#define XO30(opc) (OPCD(30)|((opc)<<2))
+#define MD30(opc) (OPCD(30)|((opc)<<2))
+#define MDS30(opc) (OPCD(30)|((opc)<<1))
 #define XO31(opc) (OPCD(31)|((opc)<<1))
 #define XO58(opc) (OPCD(58)|(opc))
 #define XO62(opc) (OPCD(62)|(opc))
@@ -354,10 +355,10 @@ static int tcg_target_const_match (tcg_t
 #define RLWINM OPCD( 21)
 #define RLWNM  OPCD( 23)
 
-#define RLDICL XO30(  0)
-#define RLDICR XO30(  1)
-#define RLDIMI XO30(  3)
-#define RLDCL  XO30(  8)
+#define RLDICL MD30(  0)
+#define RLDICR MD30(  1)
+#define RLDIMI MD30(  3)
+#define RLDCL  MDS30( 8)
 
 #define BCLR   XO19( 16)
 #define BCCTR  XO19(528)
Reviewed-by
#4 lore raw

Re: [Qemu-devel] [PATCH 1/4] tcg-ppc64: Fix RLDCL opcode

Quoted 9 lines · Anton Blanchard

The rldcl instruction doesn't have an sh field, so the minor opcode is shifted 1 bit. We were using the XO30 macro which shifted the minor opcode 2 bits.

Remove XO30 and add MD30 and MDS30 macros which match the Power ISA categories.

r~

#5 lore raw

PATCH 2/4 tcg-ppc64: bswap64 rotates output 32 bits

In reply to Anton Blanchard

If our input and output is in the same register, bswap64 tries to undo a rotate of the input. This just ends up rotating the output.

---

tcg/ppc64/tcg-target.c +0 -2
index 0fcf2b5..64fb0af 100644
@@ -1922,8 +1922,6 @@ static void tcg_out_op (TCGContext *s, TCGOpcode opc, const TCGArg *args,
 
         if (a0 == 0) {
             tcg_out_mov(s, TCG_TYPE_I64, args[0], a0);
-            /* Revert the source rotate that we performed above.  */
-            tcg_out_rld(s, RLDICL, a1, a1, 32, 0);
         }
         break;
 
#7 lore raw

PATCH 3/4 tcg-ppc64: Fix add2_i64

In reply to Anton Blanchard

add2_i64 was adding the lower double word to the upper double word of each input. Fix this so we add the lower double words, then the upper double words with carry propagation.

---

sub2 has similar issues, I haven't fixed it because I don't have a testcase yet.

tcg/ppc64/tcg-target.c +7 -7
Index: b/tcg/ppc64/tcg-target.c
===================================================================
@@ -1958,18 +1958,18 @@ static void tcg_out_op (TCGContext *s, T
            environment.  So in 64-bit mode it's always carry-out of bit 63.
            The fallback code using deposit works just as well for 32-bit.  */
         a0 = args[0], a1 = args[1];
-        if (a0 == args[4] || (!const_args[5] && a0 == args[5])) {
+        if (a0 == args[3] || (!const_args[5] && a0 == args[5])) {
             a0 = TCG_REG_R0;
         }
-        if (const_args[3]) {
-            tcg_out32(s, ADDIC | TAI(a0, args[2], args[3]));
+        if (const_args[4]) {
+            tcg_out32(s, ADDIC | TAI(a0, args[2], args[4]));
         } else {
-            tcg_out32(s, ADDC | TAB(a0, args[2], args[3]));
+            tcg_out32(s, ADDC | TAB(a0, args[2], args[4]));
         }
         if (const_args[5]) {
-            tcg_out32(s, (args[5] ? ADDME : ADDZE) | RT(a1) | RA(args[4]));
+            tcg_out32(s, (args[5] ? ADDME : ADDZE) | RT(a1) | RA(args[3]));
         } else {
-            tcg_out32(s, ADDE | TAB(a1, args[4], args[5]));
+            tcg_out32(s, ADDE | TAB(a1, args[3], args[5]));
         }
         if (a0 != args[0]) {
             tcg_out_mov(s, TCG_TYPE_I64, args[0], a0);
@@ -2147,7 +2147,7 @@ static const TCGTargetOpDef ppc_op_defs[
     { INDEX_op_deposit_i32, { "r", "0", "rZ" } },
     { INDEX_op_deposit_i64, { "r", "0", "rZ" } },
 
-    { INDEX_op_add2_i64, { "r", "r", "r", "rI", "r", "rZM" } },
+    { INDEX_op_add2_i64, { "r", "r", "r", "r", "rI", "rZM" } },
     { INDEX_op_sub2_i64, { "r", "r", "rI", "r", "rZM", "r" } },
     { INDEX_op_muls2_i64, { "r", "r", "r", "r" } },
     { INDEX_op_mulu2_i64, { "r", "r", "r", "r" } },
#9 lore raw

PATCH 4/4 tcg-ppc64: rotr_i32 rotates wrong amount

In reply to Anton Blanchard

rotr_i32 calculates the amount to left shift and puts it into a temporary, but then doesn't use it when doing the shift.

---

tcg/ppc64/tcg-target.c +1 -1
Index: b/tcg/ppc64/tcg-target.c
===================================================================
@@ -1661,7 +1661,7 @@ static void tcg_out_op (TCGContext *s, T
             tcg_out_rlw(s, RLWINM, args[0], args[1], 32 - args[2], 0, 31);
         } else {
             tcg_out32(s, SUBFIC | TAI(0, args[2], 32));
-            tcg_out32(s, RLWNM | SAB(args[1], args[0], args[2])
+            tcg_out32(s, RLWNM | SAB(args[1], args[0], 0)
                          | MB(0) | ME(31));
         }
         break;