diff --git a/target-sparc/op.c b/target-sparc/op.c index 5c6e5391d9ec80173e58e3a431e64f3d55de6fb8..2c8949048481c40c2441c8755cba72037395c774 100644 --- a/target-sparc/op.c +++ b/target-sparc/op.c @@ -965,38 +965,43 @@ void OPPROTO op_logic_T0_cc(void) void OPPROTO op_sll(void) { - T0 <<= T1; + T0 <<= (T1 & 0x1f); } #ifdef TARGET_SPARC64 +void OPPROTO op_sllx(void) +{ + T0 <<= (T1 & 0x3f); +} + void OPPROTO op_srl(void) { - T0 = (T0 & 0xffffffff) >> T1; + T0 = (T0 & 0xffffffff) >> (T1 & 0x1f); } void OPPROTO op_srlx(void) { - T0 >>= T1; + T0 >>= (T1 & 0x3f); } void OPPROTO op_sra(void) { - T0 = ((int32_t) (T0 & 0xffffffff)) >> T1; + T0 = ((int32_t) (T0 & 0xffffffff)) >> (T1 & 0x1f); } void OPPROTO op_srax(void) { - T0 = ((int64_t) T0) >> T1; + T0 = ((int64_t) T0) >> (T1 & 0x3f); } #else void OPPROTO op_srl(void) { - T0 >>= T1; + T0 >>= (T1 & 0x1f); } void OPPROTO op_sra(void) { - T0 = ((int32_t) T0) >> T1; + T0 = ((int32_t) T0) >> (T1 & 0x1f); } #endif diff --git a/target-sparc/translate.c b/target-sparc/translate.c index 50d0875d1600e5eff04e4483b5cf84c784ea04eb..70cf1bcdbc857cc17614ee29b6eb013734b909f3 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -1703,7 +1703,7 @@ static void disas_sparc_insn(DisasContext * dc) } #endif #ifdef TARGET_SPARC64 - } else if (xop == 0x25) { /* sll, V9 sllx ( == sll) */ + } else if (xop == 0x25) { /* sll, V9 sllx */ rs1 = GET_FIELD(insn, 13, 17); gen_movl_reg_T0(rs1); if (IS_IMM) { /* immediate */ @@ -1713,7 +1713,10 @@ static void disas_sparc_insn(DisasContext * dc) rs2 = GET_FIELD(insn, 27, 31); gen_movl_reg_T1(rs2); } - gen_op_sll(); + if (insn & (1 << 12)) + gen_op_sllx(); + else + gen_op_sll(); gen_movl_T0_reg(rd); } else if (xop == 0x26) { /* srl, V9 srlx */ rs1 = GET_FIELD(insn, 13, 17);