Commit 8a08f9a809f8613bb7d6c3e9389812f1b043c846
1 parent
d4218d99
Fix Sparc shift ops (Aurelien Jarno)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2569 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
17 additions
and
9 deletions
target-sparc/op.c
... | ... | @@ -965,38 +965,43 @@ void OPPROTO op_logic_T0_cc(void) |
965 | 965 | |
966 | 966 | void OPPROTO op_sll(void) |
967 | 967 | { |
968 | - T0 <<= T1; | |
968 | + T0 <<= (T1 & 0x1f); | |
969 | 969 | } |
970 | 970 | |
971 | 971 | #ifdef TARGET_SPARC64 |
972 | +void OPPROTO op_sllx(void) | |
973 | +{ | |
974 | + T0 <<= (T1 & 0x3f); | |
975 | +} | |
976 | + | |
972 | 977 | void OPPROTO op_srl(void) |
973 | 978 | { |
974 | - T0 = (T0 & 0xffffffff) >> T1; | |
979 | + T0 = (T0 & 0xffffffff) >> (T1 & 0x1f); | |
975 | 980 | } |
976 | 981 | |
977 | 982 | void OPPROTO op_srlx(void) |
978 | 983 | { |
979 | - T0 >>= T1; | |
984 | + T0 >>= (T1 & 0x3f); | |
980 | 985 | } |
981 | 986 | |
982 | 987 | void OPPROTO op_sra(void) |
983 | 988 | { |
984 | - T0 = ((int32_t) (T0 & 0xffffffff)) >> T1; | |
989 | + T0 = ((int32_t) (T0 & 0xffffffff)) >> (T1 & 0x1f); | |
985 | 990 | } |
986 | 991 | |
987 | 992 | void OPPROTO op_srax(void) |
988 | 993 | { |
989 | - T0 = ((int64_t) T0) >> T1; | |
994 | + T0 = ((int64_t) T0) >> (T1 & 0x3f); | |
990 | 995 | } |
991 | 996 | #else |
992 | 997 | void OPPROTO op_srl(void) |
993 | 998 | { |
994 | - T0 >>= T1; | |
999 | + T0 >>= (T1 & 0x1f); | |
995 | 1000 | } |
996 | 1001 | |
997 | 1002 | void OPPROTO op_sra(void) |
998 | 1003 | { |
999 | - T0 = ((int32_t) T0) >> T1; | |
1004 | + T0 = ((int32_t) T0) >> (T1 & 0x1f); | |
1000 | 1005 | } |
1001 | 1006 | #endif |
1002 | 1007 | ... | ... |
target-sparc/translate.c
... | ... | @@ -1703,7 +1703,7 @@ static void disas_sparc_insn(DisasContext * dc) |
1703 | 1703 | } |
1704 | 1704 | #endif |
1705 | 1705 | #ifdef TARGET_SPARC64 |
1706 | - } else if (xop == 0x25) { /* sll, V9 sllx ( == sll) */ | |
1706 | + } else if (xop == 0x25) { /* sll, V9 sllx */ | |
1707 | 1707 | rs1 = GET_FIELD(insn, 13, 17); |
1708 | 1708 | gen_movl_reg_T0(rs1); |
1709 | 1709 | if (IS_IMM) { /* immediate */ |
... | ... | @@ -1713,7 +1713,10 @@ static void disas_sparc_insn(DisasContext * dc) |
1713 | 1713 | rs2 = GET_FIELD(insn, 27, 31); |
1714 | 1714 | gen_movl_reg_T1(rs2); |
1715 | 1715 | } |
1716 | - gen_op_sll(); | |
1716 | + if (insn & (1 << 12)) | |
1717 | + gen_op_sllx(); | |
1718 | + else | |
1719 | + gen_op_sll(); | |
1717 | 1720 | gen_movl_T0_reg(rd); |
1718 | 1721 | } else if (xop == 0x26) { /* srl, V9 srlx */ |
1719 | 1722 | rs1 = GET_FIELD(insn, 13, 17); | ... | ... |