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,38 +965,43 @@ void OPPROTO op_logic_T0_cc(void) | ||
965 | 965 | ||
966 | void OPPROTO op_sll(void) | 966 | void OPPROTO op_sll(void) |
967 | { | 967 | { |
968 | - T0 <<= T1; | 968 | + T0 <<= (T1 & 0x1f); |
969 | } | 969 | } |
970 | 970 | ||
971 | #ifdef TARGET_SPARC64 | 971 | #ifdef TARGET_SPARC64 |
972 | +void OPPROTO op_sllx(void) | ||
973 | +{ | ||
974 | + T0 <<= (T1 & 0x3f); | ||
975 | +} | ||
976 | + | ||
972 | void OPPROTO op_srl(void) | 977 | void OPPROTO op_srl(void) |
973 | { | 978 | { |
974 | - T0 = (T0 & 0xffffffff) >> T1; | 979 | + T0 = (T0 & 0xffffffff) >> (T1 & 0x1f); |
975 | } | 980 | } |
976 | 981 | ||
977 | void OPPROTO op_srlx(void) | 982 | void OPPROTO op_srlx(void) |
978 | { | 983 | { |
979 | - T0 >>= T1; | 984 | + T0 >>= (T1 & 0x3f); |
980 | } | 985 | } |
981 | 986 | ||
982 | void OPPROTO op_sra(void) | 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 | void OPPROTO op_srax(void) | 992 | void OPPROTO op_srax(void) |
988 | { | 993 | { |
989 | - T0 = ((int64_t) T0) >> T1; | 994 | + T0 = ((int64_t) T0) >> (T1 & 0x3f); |
990 | } | 995 | } |
991 | #else | 996 | #else |
992 | void OPPROTO op_srl(void) | 997 | void OPPROTO op_srl(void) |
993 | { | 998 | { |
994 | - T0 >>= T1; | 999 | + T0 >>= (T1 & 0x1f); |
995 | } | 1000 | } |
996 | 1001 | ||
997 | void OPPROTO op_sra(void) | 1002 | void OPPROTO op_sra(void) |
998 | { | 1003 | { |
999 | - T0 = ((int32_t) T0) >> T1; | 1004 | + T0 = ((int32_t) T0) >> (T1 & 0x1f); |
1000 | } | 1005 | } |
1001 | #endif | 1006 | #endif |
1002 | 1007 |
target-sparc/translate.c
@@ -1703,7 +1703,7 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -1703,7 +1703,7 @@ static void disas_sparc_insn(DisasContext * dc) | ||
1703 | } | 1703 | } |
1704 | #endif | 1704 | #endif |
1705 | #ifdef TARGET_SPARC64 | 1705 | #ifdef TARGET_SPARC64 |
1706 | - } else if (xop == 0x25) { /* sll, V9 sllx ( == sll) */ | 1706 | + } else if (xop == 0x25) { /* sll, V9 sllx */ |
1707 | rs1 = GET_FIELD(insn, 13, 17); | 1707 | rs1 = GET_FIELD(insn, 13, 17); |
1708 | gen_movl_reg_T0(rs1); | 1708 | gen_movl_reg_T0(rs1); |
1709 | if (IS_IMM) { /* immediate */ | 1709 | if (IS_IMM) { /* immediate */ |
@@ -1713,7 +1713,10 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -1713,7 +1713,10 @@ static void disas_sparc_insn(DisasContext * dc) | ||
1713 | rs2 = GET_FIELD(insn, 27, 31); | 1713 | rs2 = GET_FIELD(insn, 27, 31); |
1714 | gen_movl_reg_T1(rs2); | 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 | gen_movl_T0_reg(rd); | 1720 | gen_movl_T0_reg(rd); |
1718 | } else if (xop == 0x26) { /* srl, V9 srlx */ | 1721 | } else if (xop == 0x26) { /* srl, V9 srlx */ |
1719 | rs1 = GET_FIELD(insn, 13, 17); | 1722 | rs1 = GET_FIELD(insn, 13, 17); |