qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH][SPARC] Fix the shift instructions for the SPARC tar


From: Aurelien Jarno
Subject: [Qemu-devel] [PATCH][SPARC] Fix the shift instructions for the SPARC target
Date: Sun, 25 Mar 2007 16:05:39 +0200
User-agent: Mutt/1.5.13 (2006-08-11)

Hi all,

The shift instructions on the SPARC target currently take into account
the whole register as the shift count. According to the SPARC v8 and v9
manuals, only the lower 5 bits should be taken into account for 32-bit 
instructions (SLL, SRL, SRA), and only the lower 6 bits for 64-bit 
instructions (SLLX, SRLX, SRAX).

The patch below fixes that. Note that SLL and SLLX are now different, as 
they don't take into account the same number of bits. Please apply.

Thanks,
Aurelien


Index: target-sparc/op.c
===================================================================
RCS file: /sources/qemu/qemu/target-sparc/op.c,v
retrieving revision 1.26
diff -u -d -p -r1.26 op.c
--- target-sparc/op.c   23 Mar 2007 20:01:20 -0000      1.26
+++ target-sparc/op.c   25 Mar 2007 13:50:45 -0000
@@ -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 & 0x2f);
+}
+
 void OPPROTO op_srl(void)
 {
-    T0 = (T0 & 0xffffffff) >> T1;
+    T0 = (T0 & 0xffffffff) >> (T1 & 0x1f);
 }
 
 void OPPROTO op_srlx(void)
 {
-    T0 >>= T1;
+    T0 >>= (T1 & 0x2f);
 }
 
 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 & 0x2f);
 }
 #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
 
Index: target-sparc/translate.c
===================================================================
RCS file: /sources/qemu/qemu/target-sparc/translate.c,v
retrieving revision 1.38
diff -u -d -p -r1.38 translate.c
--- target-sparc/translate.c    25 Mar 2007 07:55:52 -0000      1.38
+++ target-sparc/translate.c    25 Mar 2007 13:50:45 -0000
@@ -1693,7 +1693,7 @@ static void disas_sparc_insn(DisasContex
                }
 #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 */
@@ -1703,7 +1703,10 @@ static void disas_sparc_insn(DisasContex
                     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);
 

-- 
  .''`.  Aurelien Jarno             | GPG: 1024D/F1BCDB73
 : :' :  Debian developer           | Electrical Engineer
 `. `'   address@hidden         | address@hidden
   `-    people.debian.org/~aurel32 | www.aurel32.net




reply via email to

[Prev in Thread] Current Thread [Next in Thread]