diff mbox

[086/111] m68k: correct bfins instruction

Message ID 1313614076-28878-87-git-send-email-blanham@gmail.com
State New
Headers show

Commit Message

Bryce Lanham Aug. 17, 2011, 8:47 p.m. UTC
From: Laurent Vivier <laurent@vivier.eu>

correctly update generated condition code.

seen with gcc testsuite,
gcc-4.1.2/gcc/testsuite/gcc.c-torture/execute/960301-1.c

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
 target-m68k/translate.c |   34 +++++++++++++++++++++++++++++-----
 tests/m68k/Makefile     |    3 ++-
 tests/m68k/bfins.S      |   23 +++++++++++++++++++++++
 3 files changed, 54 insertions(+), 6 deletions(-)
 create mode 100644 tests/m68k/bfins.S
diff mbox

Patch

diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index d4445fe..96ea93f 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -3091,9 +3091,22 @@  DISAS_INSN(bitfield_reg)
 
     tmp1 = tcg_temp_new_i32();
     gen_helper_rol32(tmp1, tmp, offset);
-    gen_logic_cc(s, tmp1, OS_LONG);
 
     reg2 = DREG(ext, 12);
+    if (op == 7) {
+        TCGv tmp2;
+
+        tmp2 = tcg_temp_new_i32();
+        tcg_gen_sub_i32(tmp2, tcg_const_i32(32), width);
+        tcg_gen_shl_i32(tmp2, reg2, tmp2);
+        tcg_gen_and_i32(tmp2, tmp2, mask);
+        gen_logic_cc(s, tmp2, OS_LONG);
+
+        tcg_temp_free_i32(tmp1);
+    } else {
+        gen_logic_cc(s, tmp1, OS_LONG);
+    }
+
     switch (op) {
     case 0: /* bftst */
         break;
@@ -3157,11 +3170,7 @@  static TCGv gen_bitfield_cc(DisasContext *s,
     tcg_gen_shri_i64(tmp64, tmp64, 32ULL);
     dest = tcg_temp_new_i32();
     tcg_gen_trunc_i64_i32(dest, tmp64);
-
-    /* compute cc */
-
     tcg_gen_and_i32(dest, dest, mask_cc);
-    gen_logic_cc(s, dest, OS_LONG);
 
     return dest;
 }
@@ -3283,6 +3292,21 @@  DISAS_INSN(bitfield_mem)
     /* execute operation */
 
     reg = DREG(ext, 12);
+
+    if (op == 7) {
+        TCGv tmp1;
+
+        tmp1 = tcg_temp_new_i32();
+        tcg_gen_sub_i32(tmp1, tcg_const_i32(32), width);
+        tcg_gen_shl_i32(tmp1, reg, tmp1);
+        tcg_gen_and_i32(tmp1, tmp1, mask_cc);
+        gen_logic_cc(s, tmp1, OS_LONG);
+
+        tcg_temp_free_i32(tmp1);
+    } else {
+        gen_logic_cc(s, val, OS_LONG);
+    }
+
     switch (op) {
     case 0: /* bftst */
         break;
diff --git a/tests/m68k/Makefile b/tests/m68k/Makefile
index 8e90986..d043aeb 100644
--- a/tests/m68k/Makefile
+++ b/tests/m68k/Makefile
@@ -1,4 +1,5 @@ 
-TESTS=fmovecr fmove fmovem fsub fdiv fmul fabs fgetexp fscale flogn fetox
+TESTS=fmovecr fmove fmovem fsub fdiv fmul fabs fgetexp fscale flogn fetox \
+      bfins
 
 all: $(TESTS)
 
diff --git a/tests/m68k/bfins.S b/tests/m68k/bfins.S
new file mode 100644
index 0000000..a0b27f9
--- /dev/null
+++ b/tests/m68k/bfins.S
@@ -0,0 +1,23 @@ 
+	.include "trap.i"
+
+	.data
+.A:	.long 0
+	.text
+	.globl _start
+_start:
+	move.l #0,%d1
+	move.l #1,%d0
+	bfins %d0,%d1,4,4
+	move.l #3,%d0
+	bfins %d0,%d1,8,2
+	move.l #0,%d0
+	bfins %d0,%d1,8,16
+
+	move.l #1,%d0
+	lea .A,%a0
+	bfins %d0,(%a0),4,4
+	move.l #3,%d0
+	bfins %d0,(%a0),8,2
+	move.l #0,%d0
+	bfins %d0,(%a0),8,16
+	exit 0