From 8a94cfb05ea9a8991c832236b4174d354025a7b7 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Tue, 11 Jun 2013 21:19:35 +1000 Subject: [PATCH 1/4] tcg-ppc64: Fix RLDCL opcode 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. Cc: qemu-stable@nongnu.org Signed-off-by: Anton Blanchard Signed-off-by: Richard Henderson --- tcg/ppc64/tcg-target.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c index 0fcf2b5daa..c7c0b8f94d 100644 --- a/tcg/ppc64/tcg-target.c +++ b/tcg/ppc64/tcg-target.c @@ -308,7 +308,8 @@ static int tcg_target_const_match (tcg_target_long val, #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_target_long val, #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) From 82e0f9170ac9307de4fc15bfb4d12d5534550322 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Sun, 2 Jun 2013 22:28:27 +1000 Subject: [PATCH 2/4] tcg-ppc64: bswap64 rotates output 32 bits 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. Cc: qemu-stable@nongnu.org Signed-off-by: Anton Blanchard Signed-off-by: Richard Henderson --- tcg/ppc64/tcg-target.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c index c7c0b8f94d..1d065300f8 100644 --- a/tcg/ppc64/tcg-target.c +++ b/tcg/ppc64/tcg-target.c @@ -1923,8 +1923,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; From 84247357104044b8c4ec4a634e84769f432cbe52 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Sun, 2 Jun 2013 22:29:39 +1000 Subject: [PATCH 3/4] tcg-ppc64: Fix add2_i64 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. Cc: qemu-stable@nongnu.org Signed-off-by: Anton Blanchard Signed-off-by: Richard Henderson --- tcg/ppc64/tcg-target.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c index 1d065300f8..5cdff36393 100644 --- a/tcg/ppc64/tcg-target.c +++ b/tcg/ppc64/tcg-target.c @@ -1959,18 +1959,18 @@ static void tcg_out_op (TCGContext *s, TCGOpcode opc, const TCGArg *args, 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); @@ -2148,7 +2148,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" } }, From d1bdd3af49f227dd4a4b03b90cb020c55cbed440 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Sun, 2 Jun 2013 22:30:18 +1000 Subject: [PATCH 4/4] tcg-ppc64: rotr_i32 rotates wrong amount rotr_i32 calculates the amount to left shift and puts it into a temporary, but then doesn't use it when doing the shift. Cc: qemu-stable@nongnu.org Signed-off-by: Anton Blanchard Signed-off-by: Richard Henderson --- tcg/ppc64/tcg-target.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c index 5cdff36393..606b73defc 100644 --- a/tcg/ppc64/tcg-target.c +++ b/tcg/ppc64/tcg-target.c @@ -1662,7 +1662,7 @@ static void tcg_out_op (TCGContext *s, TCGOpcode opc, const TCGArg *args, 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;