On Tue, 18 Sep 2012, Richard Henderson wrote: > On 09/18/2012 12:52 PM, malc wrote: > > case INDEX_op_shl_i32: > > if (const_args[2]) { > > + if (args[2] > 31) { > > + tcg_out_movi (s, TCG_TYPE_I32, 0, args[2]); > > + tcg_out32 (s, SLW | SAB (args[1], args[0], 0)); > > + } > > What's this bit for?
This bit is to offset for the fact that i haven't slept in a while, and... > > AFAIK all you should need are the added & 31 below. > Not really - due to the 0 corner case, following should be better: diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c index 26c4b33..784b157 100644 --- a/tcg/ppc/tcg-target.c +++ b/tcg/ppc/tcg-target.c @@ -409,6 +409,7 @@ static int tcg_target_const_match(tcg_target_long val, #define TW XO31(4) #define TRAP (TW | TO (31)) +#define NOP 0x60000000 #define RT(r) ((r)<<21) #define RS(r) ((r)<<21) @@ -1306,10 +1307,10 @@ void ppc_tb_set_jmp_target (unsigned long jmp_addr, unsigned long addr) *ptr = 0x48000000 | (disp & 0x03fffffc); /* b disp */ patch_size = 4; } else { - ptr[0] = 0x60000000; /* nop */ - ptr[1] = 0x60000000; - ptr[2] = 0x60000000; - ptr[3] = 0x60000000; + ptr[0] = NOP; + ptr[1] = NOP; + ptr[2] = NOP; + ptr[3] = NOP; patch_size = 16; } } @@ -1330,7 +1331,10 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args, /* direct jump method */ s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf; - s->code_ptr += 16; + tcg_out32 (s, NOP); + tcg_out32 (s, NOP); + tcg_out32 (s, NOP); + tcg_out32 (s, NOP); } else { tcg_abort (); @@ -1565,35 +1569,54 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args, case INDEX_op_shl_i32: if (const_args[2]) { - tcg_out32 (s, (RLWINM - | RA (args[0]) - | RS (args[1]) - | SH (args[2]) - | MB (0) - | ME (31 - args[2]) - ) - ); + int sh = args[2] & 31; + if (!sh) { + tcg_out_mov (s, TCG_TYPE_I32, args[0], args[1]); + } + else { + tcg_out32 (s, (RLWINM + | RA (args[0]) + | RS (args[1]) + | SH (sh) + | MB (0) + | ME (31 - sh) + ) + ); + } } else tcg_out32 (s, SLW | SAB (args[1], args[0], args[2])); break; case INDEX_op_shr_i32: if (const_args[2]) { - tcg_out32 (s, (RLWINM - | RA (args[0]) - | RS (args[1]) - | SH (32 - args[2]) - | MB (args[2]) - | ME (31) - ) - ); + int sh = args[2] & 31; + if (!sh) { + tcg_out_mov (s, TCG_TYPE_I32, args[0], args[1]); + } + else { + tcg_out32 (s, (RLWINM + | RA (args[0]) + | RS (args[1]) + | SH (32 - sh) + | MB (sh) + | ME (31) + ) + ); + } } else tcg_out32 (s, SRW | SAB (args[1], args[0], args[2])); break; case INDEX_op_sar_i32: - if (const_args[2]) - tcg_out32 (s, SRAWI | RS (args[1]) | RA (args[0]) | SH (args[2])); + if (const_args[2]) { + int sh = args[2] & 31; + if (!sh) { + tcg_out_mov (s, TCG_TYPE_I32, args[0], args[1]); + } + else { + tcg_out32 (s, SRAWI | RS (args[1]) | RA (args[0]) | SH (sh)); + } + } else tcg_out32 (s, SRAW | SAB (args[1], args[0], args[2])); break; @@ -1604,7 +1627,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args, | RS (args[1]) | MB (0) | ME (31) - | (const_args[2] ? RLWINM | SH (args[2]) + | (const_args[2] ? RLWINM | SH (args[2] & 31) : RLWNM | RB (args[2])) ; tcg_out32 (s, op); This expects deposit/rotr constant arguments to be sane, i'm no longer certain this assumption is a sane one though... -- mailto:av1...@comtv.ru