All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 00/16] 680x0 instruction set, part 1
@ 2016-10-26 16:35 Laurent Vivier
  2016-10-26 16:35 ` [Qemu-devel] [PATCH 01/16] target-m68k: add bkpt instruction Laurent Vivier
                   ` (15 more replies)
  0 siblings, 16 replies; 21+ messages in thread
From: Laurent Vivier @ 2016-10-26 16:35 UTC (permalink / raw)
  To: qemu-devel; +Cc: schwab, agraf, Richard Henderson, gerg, Laurent Vivier

This series is another subset of the series I sent in May:
https://lists.gnu.org/archive/html/qemu-devel/2016-05/msg00501.html

It must be applied on top of series:
"target-m68k: prepare to introduce 680x0 instruction set"

This subset contains:
- all the patches reviewed by Richard that needed no modification
- some patches where the fix was easy
- I've merged patches inlining addx/subx/negx and introducing their
  opcodes for 680x0.

This subset introduces:
- new instructions: bkpt, linkl, exg, dbCC
- new operand size (byte and word) for some instructions:
  or, eor, and, add, sub, cmp, and instruciont with immediate data
- add addressing modes to: not, neg, adda, suba
- remove helpers for: addx, subx, negx

I've checked it doesn't break coldfire support:
http://wiki.qemu.org/download/coldfire-test-0.1.tar.bz2
but it can't boot a 680x0 processor kernel.

Laurent Vivier (15):
  target-m68k: add bkpt instruction
  target-m68k: add linkl
  target-m68k: add exg ops
  target-m68k: add scc/dbcc
  target-m68k: add addressing modes to not
  target-m68k: eor can manage word and byte operands
  target-m68k: or can manage word and byte operands
  target-m68k: and can manage word and byte operands
  target-m68k: suba/adda can manage word operand
  target-m68k: some bit ops cleanup
  target-m68k: introduce byte and word cc_ops
  target-m68k: add addressing modes to neg
  target-m68k: add/sub manage word and byte operands
  target-m68k: cmp manages word and bytes operands
  target-m68k: immediate ops manage word and byte operands

Richard Henderson (1):
  target-m68k: Inline addx, subx, negx

 target-m68k/cpu.h       |   6 +-
 target-m68k/helper.c    |  65 ++---
 target-m68k/helper.h    |   2 -
 target-m68k/translate.c | 690 ++++++++++++++++++++++++++++++++++--------------
 4 files changed, 516 insertions(+), 247 deletions(-)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PATCH 01/16] target-m68k: add bkpt instruction
  2016-10-26 16:35 [Qemu-devel] [PATCH 00/16] 680x0 instruction set, part 1 Laurent Vivier
@ 2016-10-26 16:35 ` Laurent Vivier
  2016-10-26 21:38   ` Richard Henderson
  2016-10-26 16:35 ` [Qemu-devel] [PATCH 02/16] target-m68k: add linkl Laurent Vivier
                   ` (14 subsequent siblings)
  15 siblings, 1 reply; 21+ messages in thread
From: Laurent Vivier @ 2016-10-26 16:35 UTC (permalink / raw)
  To: qemu-devel; +Cc: schwab, agraf, Richard Henderson, gerg, Laurent Vivier

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
 target-m68k/translate.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 6c6173a..a128b67 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -1639,6 +1639,11 @@ DISAS_INSN(swap)
     gen_logic_cc(s, reg, OS_LONG);
 }
 
+DISAS_INSN(bkpt)
+{
+    gen_exception(s, s->pc - 2, EXCP_DEBUG);
+}
+
 DISAS_INSN(pea)
 {
     TCGv tmp;
@@ -3056,6 +3061,7 @@ void register_m68k_insns (CPUM68KState *env)
     INSN(move_to_sr, 46c0, ffc0, CF_ISA_A);
     BASE(pea,       4840, ffc0);
     BASE(swap,      4840, fff8);
+    INSN(bkpt,      4848, fff8, BKPT);
     BASE(movem,     48c0, fbc0);
     BASE(ext,       4880, fff8);
     BASE(ext,       48c0, fff8);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PATCH 02/16] target-m68k: add linkl
  2016-10-26 16:35 [Qemu-devel] [PATCH 00/16] 680x0 instruction set, part 1 Laurent Vivier
  2016-10-26 16:35 ` [Qemu-devel] [PATCH 01/16] target-m68k: add bkpt instruction Laurent Vivier
@ 2016-10-26 16:35 ` Laurent Vivier
  2016-10-26 16:35 ` [Qemu-devel] [PATCH 03/16] target-m68k: add exg ops Laurent Vivier
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 21+ messages in thread
From: Laurent Vivier @ 2016-10-26 16:35 UTC (permalink / raw)
  To: qemu-devel; +Cc: schwab, agraf, Richard Henderson, gerg, Laurent Vivier

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Richard Henderson <rth@twiddle.net>
---
 target-m68k/translate.c | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index a128b67..0d3111d 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -1733,21 +1733,36 @@ DISAS_INSN(mull)
     gen_logic_cc(s, dest, OS_LONG);
 }
 
-DISAS_INSN(link)
+static void gen_link(DisasContext *s, uint16_t insn, int32_t offset)
 {
-    int16_t offset;
     TCGv reg;
     TCGv tmp;
 
-    offset = cpu_ldsw_code(env, s->pc);
-    s->pc += 2;
     reg = AREG(insn, 0);
     tmp = tcg_temp_new();
     tcg_gen_subi_i32(tmp, QREG_SP, 4);
     gen_store(s, OS_LONG, tmp, reg);
-    if ((insn & 7) != 7)
+    if ((insn & 7) != 7) {
         tcg_gen_mov_i32(reg, tmp);
+    }
     tcg_gen_addi_i32(QREG_SP, tmp, offset);
+    tcg_temp_free(tmp);
+}
+
+DISAS_INSN(link)
+{
+    int16_t offset;
+
+    offset = read_im16(env, s);
+    gen_link(s, insn, offset);
+}
+
+DISAS_INSN(linkl)
+{
+    int32_t offset;
+
+    offset = read_im32(env, s);
+    gen_link(s, insn, offset);
 }
 
 DISAS_INSN(unlk)
@@ -3059,6 +3074,7 @@ void register_m68k_insns (CPUM68KState *env)
     INSN(not,       4600, ff00, M68000);
     INSN(undef,     46c0, ffc0, M68000);
     INSN(move_to_sr, 46c0, ffc0, CF_ISA_A);
+    INSN(linkl,     4808, fff8, M68000);
     BASE(pea,       4840, ffc0);
     BASE(swap,      4840, fff8);
     INSN(bkpt,      4848, fff8, BKPT);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PATCH 03/16] target-m68k: add exg ops
  2016-10-26 16:35 [Qemu-devel] [PATCH 00/16] 680x0 instruction set, part 1 Laurent Vivier
  2016-10-26 16:35 ` [Qemu-devel] [PATCH 01/16] target-m68k: add bkpt instruction Laurent Vivier
  2016-10-26 16:35 ` [Qemu-devel] [PATCH 02/16] target-m68k: add linkl Laurent Vivier
@ 2016-10-26 16:35 ` Laurent Vivier
  2016-10-26 22:07   ` Richard Henderson
  2016-10-26 16:35 ` [Qemu-devel] [PATCH 04/16] target-m68k: add scc/dbcc Laurent Vivier
                   ` (12 subsequent siblings)
  15 siblings, 1 reply; 21+ messages in thread
From: Laurent Vivier @ 2016-10-26 16:35 UTC (permalink / raw)
  To: qemu-devel; +Cc: schwab, agraf, Richard Henderson, gerg, Laurent Vivier

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
 target-m68k/translate.c | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 0d3111d..a07b6f5 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -2021,6 +2021,41 @@ DISAS_INSN(eor)
     DEST_EA(env, insn, OS_LONG, dest, &addr);
 }
 
+DISAS_INSN(exg)
+{
+    TCGv src;
+    TCGv reg;
+    TCGv dest;
+    int exg_mode;
+
+    exg_mode = insn & 0x1f8;
+
+    dest = tcg_temp_new();
+    switch (exg_mode) {
+    case 0x140:
+        /* exchange Dx and Dy */
+        src = DREG(insn, 9);
+        reg = DREG(insn, 0);
+        break;
+    case 0x148:
+        /* exchange Ax and Ay */
+        src = AREG(insn, 9);
+        reg = AREG(insn, 0);
+        break;
+    case 0x188:
+        /* exchange Dx and Ay */
+        src = DREG(insn, 9);
+        reg = AREG(insn, 0);
+        break;
+    default:
+        g_assert_not_reached();
+    }
+    tcg_gen_mov_i32(dest, src);
+    tcg_gen_mov_i32(src, reg);
+    tcg_gen_mov_i32(reg, dest);
+    tcg_temp_free(dest);
+}
+
 DISAS_INSN(and)
 {
     TCGv src;
@@ -3154,6 +3189,12 @@ void register_m68k_insns (CPUM68KState *env)
     INSN(cmpa,      b0c0, f0c0, M68000);
     INSN(eor,       b180, f1c0, CF_ISA_A);
     BASE(and,       c000, f000);
+    INSN(undef,     c140, f1f8, CF_ISA_A);
+    INSN(exg,       c140, f1f8, M68000);
+    INSN(undef,     c148, f1f8, CF_ISA_A);
+    INSN(exg,       c148, f1f8, M68000);
+    INSN(undef,     c188, f1f8, CF_ISA_A);
+    INSN(exg,       c188, f1f8, M68000);
     BASE(mulw,      c0c0, f0c0);
     BASE(addsub,    d000, f000);
     INSN(addx,      d180, f1f8, CF_ISA_A);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PATCH 04/16] target-m68k: add scc/dbcc
  2016-10-26 16:35 [Qemu-devel] [PATCH 00/16] 680x0 instruction set, part 1 Laurent Vivier
                   ` (2 preceding siblings ...)
  2016-10-26 16:35 ` [Qemu-devel] [PATCH 03/16] target-m68k: add exg ops Laurent Vivier
@ 2016-10-26 16:35 ` Laurent Vivier
  2016-10-26 22:12   ` Richard Henderson
  2016-10-26 16:35 ` [Qemu-devel] [PATCH 05/16] target-m68k: Inline addx, subx, negx Laurent Vivier
                   ` (11 subsequent siblings)
  15 siblings, 1 reply; 21+ messages in thread
From: Laurent Vivier @ 2016-10-26 16:35 UTC (permalink / raw)
  To: qemu-devel; +Cc: schwab, agraf, Richard Henderson, gerg, Laurent Vivier

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
 target-m68k/translate.c | 65 ++++++++++++++++++++++++++++++++++---------------
 1 file changed, 45 insertions(+), 20 deletions(-)

diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index a07b6f5..05efd29 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -1008,25 +1008,6 @@ static void gen_jmpcc(DisasContext *s, int cond, TCGLabel *l1)
   free_cond(&c);
 }
 
-DISAS_INSN(scc)
-{
-    DisasCompare c;
-    int cond;
-    TCGv reg, tmp;
-
-    cond = (insn >> 8) & 0xf;
-    gen_cc_cond(&c, s, cond);
-
-    tmp = tcg_temp_new();
-    tcg_gen_setcond_i32(c.tcond, tmp, c.v1, c.v2);
-    free_cond(&c);
-
-    reg = DREG(insn, 0);
-    tcg_gen_neg_i32(tmp, tmp);
-    tcg_gen_deposit_i32(reg, reg, tmp, 0, 8);
-    tcg_temp_free(tmp);
-}
-
 /* Force a TB lookup after an instruction that changes the CPU state.  */
 static void gen_lookup_tb(DisasContext *s)
 {
@@ -1106,6 +1087,48 @@ static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest)
     s->is_jmp = DISAS_TB_JUMP;
 }
 
+DISAS_INSN(scc)
+{
+    DisasCompare c;
+    int cond;
+    TCGv tmp;
+
+    cond = (insn >> 8) & 0xf;
+    gen_cc_cond(&c, s, cond);
+
+    tmp = tcg_temp_new();
+    tcg_gen_setcond_i32(c.tcond, tmp, c.v1, c.v2);
+    free_cond(&c);
+
+    tcg_gen_neg_i32(tmp, tmp);
+    DEST_EA(env, insn, OS_BYTE, tmp, NULL);
+    tcg_temp_free(tmp);
+}
+
+DISAS_INSN(dbcc)
+{
+    TCGLabel *l1;
+    TCGv reg;
+    TCGv tmp;
+    int16_t offset;
+    uint32_t base;
+
+    reg = DREG(insn, 0);
+    base = s->pc;
+    offset = (int16_t)read_im16(env, s);
+    l1 = gen_new_label();
+    gen_jmpcc(s, (insn >> 8) & 0xf, l1);
+
+    tmp = tcg_temp_new();
+    tcg_gen_ext16s_i32(tmp, reg);
+    tcg_gen_addi_i32(tmp, tmp, -1);
+    gen_partset_reg(OS_WORD, reg, tmp);
+    tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, -1, l1);
+    gen_jmp_tb(s, 1, base + offset);
+    gen_set_label(l1);
+    gen_jmp_tb(s, 0, s->pc);
+}
+
 DISAS_INSN(undef_mac)
 {
     gen_exception(s, s->pc - 2, EXCP_LINEA);
@@ -3144,7 +3167,9 @@ void register_m68k_insns (CPUM68KState *env)
     INSN(jump,      4ec0, ffc0, M68000);
     INSN(addsubq,   5000, f080, M68000);
     INSN(addsubq,   5080, f0c0, M68000);
-    INSN(scc,       50c0, f0f8, CF_ISA_A);
+    INSN(scc,       50c0, f0f8, CF_ISA_A); /* Scc.B Dx   */
+    INSN(scc,       50c0, f0c0, M68000);   /* Scc.B <EA> */
+    INSN(dbcc,      50c8, f0f8, M68000);
     INSN(addsubq,   5080, f1c0, CF_ISA_A);
     INSN(tpf,       51f8, fff8, CF_ISA_A);
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PATCH 05/16] target-m68k: Inline addx, subx, negx
  2016-10-26 16:35 [Qemu-devel] [PATCH 00/16] 680x0 instruction set, part 1 Laurent Vivier
                   ` (3 preceding siblings ...)
  2016-10-26 16:35 ` [Qemu-devel] [PATCH 04/16] target-m68k: add scc/dbcc Laurent Vivier
@ 2016-10-26 16:35 ` Laurent Vivier
  2016-10-26 16:35 ` [Qemu-devel] [PATCH 06/16] target-m68k: add addressing modes to not Laurent Vivier
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 21+ messages in thread
From: Laurent Vivier @ 2016-10-26 16:35 UTC (permalink / raw)
  To: qemu-devel; +Cc: schwab, agraf, Richard Henderson, gerg, Laurent Vivier

From: Richard Henderson <rth@twiddle.net>

And add opcodes for 680x0

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
 target-m68k/helper.c    |  40 ----------
 target-m68k/helper.h    |   2 -
 target-m68k/translate.c | 196 +++++++++++++++++++++++++++++++++++++++++++-----
 3 files changed, 178 insertions(+), 60 deletions(-)

diff --git a/target-m68k/helper.c b/target-m68k/helper.c
index 094a7e5..e838638 100644
--- a/target-m68k/helper.c
+++ b/target-m68k/helper.c
@@ -277,46 +277,6 @@ uint32_t HELPER(sats)(uint32_t val, uint32_t v)
     return val;
 }
 
-uint32_t HELPER(subx_cc)(CPUM68KState *env, uint32_t op1, uint32_t op2)
-{
-    uint32_t res, new_x;
-
-    if (env->cc_x) {
-        new_x = (op1 <= op2);
-        res = op1 - (op2 + 1);
-    } else {
-        new_x = (op1 < op2);
-        res = op1 - op2;
-    }
-    env->cc_x = new_x;
-    env->cc_c = new_x;
-    env->cc_n = res;
-    env->cc_z |= res; /* !Z is sticky */
-    env->cc_v = (res ^ op1) & (op1 ^ op2);
-
-    return res;
-}
-
-uint32_t HELPER(addx_cc)(CPUM68KState *env, uint32_t op1, uint32_t op2)
-{
-    uint32_t res, new_x;
-
-    if (env->cc_x) {
-        res = op1 + op2 + 1;
-        new_x = (res <= op2);
-    } else {
-        res = op1 + op2;
-        new_x = (res < op2);
-    }
-    env->cc_x = new_x;
-    env->cc_c = new_x;
-    env->cc_n = res;
-    env->cc_z |= res; /* !Z is sticky.  */
-    env->cc_v = (res ^ op1) & ~(op1 ^ op2);
-
-    return res;
-}
-
 void HELPER(set_sr)(CPUM68KState *env, uint32_t val)
 {
     env->sr = val & 0xffe0;
diff --git a/target-m68k/helper.h b/target-m68k/helper.h
index c868148..2697e32 100644
--- a/target-m68k/helper.h
+++ b/target-m68k/helper.h
@@ -3,8 +3,6 @@ DEF_HELPER_1(ff1, i32, i32)
 DEF_HELPER_FLAGS_2(sats, TCG_CALL_NO_RWG_SE, i32, i32, i32)
 DEF_HELPER_2(divu, void, env, i32)
 DEF_HELPER_2(divs, void, env, i32)
-DEF_HELPER_3(addx_cc, i32, env, i32, i32)
-DEF_HELPER_3(subx_cc, i32, env, i32, i32)
 DEF_HELPER_3(shl_cc, i32, env, i32, i32)
 DEF_HELPER_3(shr_cc, i32, env, i32, i32)
 DEF_HELPER_3(sar_cc, i32, env, i32, i32)
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 05efd29..59d7017 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -1536,11 +1536,44 @@ DISAS_INSN(move)
 
 DISAS_INSN(negx)
 {
-    TCGv reg;
+    TCGv z;
+    TCGv src;
+    TCGv addr;
+    int opsize;
 
-    gen_flush_flags(s);
-    reg = DREG(insn, 0);
-    gen_helper_subx_cc(reg, cpu_env, tcg_const_i32(0), reg);
+    opsize = insn_opsize(insn);
+    SRC_EA(env, src, opsize, 1, &addr);
+
+    gen_flush_flags(s); /* compute old Z */
+
+    /* Perform substract with borrow.
+     * (X, N) =  -(src + X);
+     */
+
+    z = tcg_const_i32(0);
+    tcg_gen_add2_i32(QREG_CC_N, QREG_CC_X, src, z, QREG_CC_X, z);
+    tcg_gen_sub2_i32(QREG_CC_N, QREG_CC_X, z, z, QREG_CC_N, QREG_CC_X);
+    tcg_temp_free(z);
+    gen_ext(QREG_CC_N, QREG_CC_N, opsize, 1);
+
+    tcg_gen_andi_i32(QREG_CC_X, QREG_CC_X, 1);
+
+    /* Compute signed-overflow for negation.  The normal formula for
+     * subtraction is (res ^ src) & (src ^ dest), but with dest==0
+     * this simplies to res & src.
+     */
+
+    tcg_gen_and_i32(QREG_CC_V, QREG_CC_N, src);
+
+    /* Copy the rest of the results into place.  */
+    tcg_gen_or_i32(QREG_CC_Z, QREG_CC_Z, QREG_CC_N); /* !Z is sticky */
+    tcg_gen_mov_i32(QREG_CC_C, QREG_CC_X);
+
+    set_cc_op(s, CC_OP_FLAGS);
+
+    /* result is in QREG_CC_N */
+
+    DEST_EA(env, insn, opsize, QREG_CC_N, &addr);
 }
 
 DISAS_INSN(lea)
@@ -1975,15 +2008,75 @@ DISAS_INSN(suba)
     tcg_gen_sub_i32(reg, reg, src);
 }
 
-DISAS_INSN(subx)
+static inline void gen_subx(DisasContext *s, TCGv src, TCGv dest, int opsize)
 {
-    TCGv reg;
+    TCGv tmp;
+
+    gen_flush_flags(s); /* compute old Z */
+
+    /* Perform substract with borrow.
+     * (X, N) = dest - (src + X);
+     */
+
+    tmp = tcg_const_i32(0);
+    tcg_gen_add2_i32(QREG_CC_N, QREG_CC_X, src, tmp, QREG_CC_X, tmp);
+    tcg_gen_sub2_i32(QREG_CC_N, QREG_CC_X, dest, tmp, QREG_CC_N, QREG_CC_X);
+    gen_ext(QREG_CC_N, QREG_CC_N, opsize, 1);
+    tcg_gen_andi_i32(QREG_CC_X, QREG_CC_X, 1);
+
+    /* Compute signed-overflow for substract.  */
+
+    tcg_gen_xor_i32(QREG_CC_V, QREG_CC_N, dest);
+    tcg_gen_xor_i32(tmp, dest, src);
+    tcg_gen_and_i32(QREG_CC_V, QREG_CC_V, tmp);
+    tcg_temp_free(tmp);
+
+    /* Copy the rest of the results into place.  */
+    tcg_gen_or_i32(QREG_CC_Z, QREG_CC_Z, QREG_CC_N); /* !Z is sticky */
+    tcg_gen_mov_i32(QREG_CC_C, QREG_CC_X);
+
+    set_cc_op(s, CC_OP_FLAGS);
+
+    /* result is in QREG_CC_N */
+}
+
+DISAS_INSN(subx_reg)
+{
+    TCGv dest;
     TCGv src;
+    int opsize;
 
-    gen_flush_flags(s);
-    reg = DREG(insn, 9);
-    src = DREG(insn, 0);
-    gen_helper_subx_cc(reg, cpu_env, reg, src);
+    opsize = insn_opsize(insn);
+
+    src = gen_extend(DREG(insn, 0), opsize, 1);
+    dest = gen_extend(DREG(insn, 9), opsize, 1);
+
+    gen_subx(s, src, dest, opsize);
+
+    gen_partset_reg(opsize, DREG(insn, 9), QREG_CC_N);
+}
+
+DISAS_INSN(subx_mem)
+{
+    TCGv src;
+    TCGv addr_src;
+    TCGv dest;
+    TCGv addr_dest;
+    int opsize;
+
+    opsize = insn_opsize(insn);
+
+    addr_src = AREG(insn, 0);
+    tcg_gen_subi_i32(addr_src, addr_src, opsize);
+    src = gen_load(s, opsize, addr_src, 1);
+
+    addr_dest = AREG(insn, 9);
+    tcg_gen_subi_i32(addr_dest, addr_dest, opsize);
+    dest = gen_load(s, opsize, addr_dest, 1);
+
+    gen_subx(s, src, dest, opsize);
+
+    gen_store(s, opsize, addr_dest, QREG_CC_N);
 }
 
 DISAS_INSN(mov3q)
@@ -2110,15 +2203,74 @@ DISAS_INSN(adda)
     tcg_gen_add_i32(reg, reg, src);
 }
 
-DISAS_INSN(addx)
+static inline void gen_addx(DisasContext *s, TCGv src, TCGv dest, int opsize)
 {
-    TCGv reg;
+    TCGv tmp;
+
+    gen_flush_flags(s); /* compute old Z */
+
+    /* Perform addition with carry.
+     * (X, N) = src + dest + X;
+     */
+
+    tmp = tcg_const_i32(0);
+    tcg_gen_add2_i32(QREG_CC_N, QREG_CC_X, QREG_CC_X, tmp, dest, tmp);
+    tcg_gen_add2_i32(QREG_CC_N, QREG_CC_X, QREG_CC_N, QREG_CC_X, src, tmp);
+    gen_ext(QREG_CC_N, QREG_CC_N, opsize, 1);
+
+    /* Compute signed-overflow for addition.  */
+
+    tcg_gen_xor_i32(QREG_CC_V, QREG_CC_N, src);
+    tcg_gen_xor_i32(tmp, dest, src);
+    tcg_gen_andc_i32(QREG_CC_V, QREG_CC_V, tmp);
+    tcg_temp_free(tmp);
+
+    /* Copy the rest of the results into place.  */
+    tcg_gen_or_i32(QREG_CC_Z, QREG_CC_Z, QREG_CC_N); /* !Z is sticky */
+    tcg_gen_mov_i32(QREG_CC_C, QREG_CC_X);
+
+    set_cc_op(s, CC_OP_FLAGS);
+
+    /* result is in QREG_CC_N */
+}
+
+DISAS_INSN(addx_reg)
+{
+    TCGv dest;
     TCGv src;
+    int opsize;
 
-    gen_flush_flags(s);
-    reg = DREG(insn, 9);
-    src = DREG(insn, 0);
-    gen_helper_addx_cc(reg, cpu_env, reg, src);
+    opsize = insn_opsize(insn);
+
+    dest = gen_extend(DREG(insn, 9), opsize, 1);
+    src = gen_extend(DREG(insn, 0), opsize, 1);
+
+    gen_addx(s, src, dest, opsize);
+
+    gen_partset_reg(opsize, DREG(insn, 9), QREG_CC_N);
+}
+
+DISAS_INSN(addx_mem)
+{
+    TCGv src;
+    TCGv addr_src;
+    TCGv dest;
+    TCGv addr_dest;
+    int opsize;
+
+    opsize = insn_opsize(insn);
+
+    addr_src = AREG(insn, 0);
+    tcg_gen_subi_i32(addr_src, addr_src, opsize_bytes(opsize));
+    src = gen_load(s, opsize, addr_src, 1);
+
+    addr_dest = AREG(insn, 9);
+    tcg_gen_subi_i32(addr_dest, addr_dest, opsize_bytes(opsize));
+    dest = gen_load(s, opsize, addr_dest, 1);
+
+    gen_addx(s, src, dest, opsize);
+
+    gen_store(s, opsize, addr_dest, QREG_CC_N);
 }
 
 /* TODO: This could be implemented without helper functions.  */
@@ -3117,6 +3269,8 @@ void register_m68k_insns (CPUM68KState *env)
     BASE(move,      3000, f000);
     INSN(strldsr,   40e7, ffff, CF_ISA_APLUSC);
     INSN(negx,      4080, fff8, CF_ISA_A);
+    INSN(negx,      4000, ff00, M68000);
+    INSN(undef,     40c0, ffc0, M68000);
     INSN(move_from_sr, 40c0, fff8, CF_ISA_A);
     INSN(move_from_sr, 40c0, ffc0, M68000);
     BASE(lea,       41c0, f1c0);
@@ -3187,7 +3341,10 @@ void register_m68k_insns (CPUM68KState *env)
     BASE(or,        8000, f000);
     BASE(divw,      80c0, f0c0);
     BASE(addsub,    9000, f000);
-    INSN(subx,      9180, f1f8, CF_ISA_A);
+    INSN(undef,     90c0, f0c0, CF_ISA_A);
+    INSN(subx_reg,  9180, f1f8, CF_ISA_A);
+    INSN(subx_reg,  9100, f138, M68000);
+    INSN(subx_mem,  9108, f138, M68000);
     INSN(suba,      91c0, f1c0, CF_ISA_A);
 
     BASE(undef_mac, a000, f000);
@@ -3222,7 +3379,10 @@ void register_m68k_insns (CPUM68KState *env)
     INSN(exg,       c188, f1f8, M68000);
     BASE(mulw,      c0c0, f0c0);
     BASE(addsub,    d000, f000);
-    INSN(addx,      d180, f1f8, CF_ISA_A);
+    INSN(undef,     d0c0, f0c0, CF_ISA_A);
+    INSN(addx_reg,      d180, f1f8, CF_ISA_A);
+    INSN(addx_reg,  d100, f138, M68000);
+    INSN(addx_mem,  d108, f138, M68000);
     INSN(adda,      d1c0, f1c0, CF_ISA_A);
     INSN(adda,      d0c0, f0c0, M68000);
     INSN(shift_im,  e080, f0f0, CF_ISA_A);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PATCH 06/16] target-m68k: add addressing modes to not
  2016-10-26 16:35 [Qemu-devel] [PATCH 00/16] 680x0 instruction set, part 1 Laurent Vivier
                   ` (4 preceding siblings ...)
  2016-10-26 16:35 ` [Qemu-devel] [PATCH 05/16] target-m68k: Inline addx, subx, negx Laurent Vivier
@ 2016-10-26 16:35 ` Laurent Vivier
  2016-10-26 16:35 ` [Qemu-devel] [PATCH 07/16] target-m68k: eor can manage word and byte operands Laurent Vivier
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 21+ messages in thread
From: Laurent Vivier @ 2016-10-26 16:35 UTC (permalink / raw)
  To: qemu-devel; +Cc: schwab, agraf, Richard Henderson, gerg, Laurent Vivier

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Richard Henderson <rth@twiddle.net>
---
 target-m68k/translate.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 59d7017..76432b4 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -1673,11 +1673,17 @@ DISAS_INSN(move_to_ccr)
 
 DISAS_INSN(not)
 {
-    TCGv reg;
+    TCGv src1;
+    TCGv dest;
+    TCGv addr;
+    int opsize;
 
-    reg = DREG(insn, 0);
-    tcg_gen_not_i32(reg, reg);
-    gen_logic_cc(s, reg, OS_LONG);
+    opsize = insn_opsize(insn);
+    SRC_EA(env, src1, opsize, 1, &addr);
+    dest = tcg_temp_new();
+    tcg_gen_not_i32(dest, src1);
+    DEST_EA(env, insn, opsize, dest, &addr);
+    gen_logic_cc(s, dest, opsize);
 }
 
 DISAS_INSN(swap)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PATCH 07/16] target-m68k: eor can manage word and byte operands
  2016-10-26 16:35 [Qemu-devel] [PATCH 00/16] 680x0 instruction set, part 1 Laurent Vivier
                   ` (5 preceding siblings ...)
  2016-10-26 16:35 ` [Qemu-devel] [PATCH 06/16] target-m68k: add addressing modes to not Laurent Vivier
@ 2016-10-26 16:35 ` Laurent Vivier
  2016-10-26 16:35 ` [Qemu-devel] [PATCH 08/16] target-m68k: or " Laurent Vivier
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 21+ messages in thread
From: Laurent Vivier @ 2016-10-26 16:35 UTC (permalink / raw)
  To: qemu-devel; +Cc: schwab, agraf, Richard Henderson, gerg, Laurent Vivier

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Richard Henderson <rth@twiddle.net>
---
 target-m68k/translate.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 76432b4..985bc58 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -2131,16 +2131,17 @@ DISAS_INSN(cmpa)
 DISAS_INSN(eor)
 {
     TCGv src;
-    TCGv reg;
     TCGv dest;
     TCGv addr;
+    int opsize;
 
-    SRC_EA(env, src, OS_LONG, 0, &addr);
-    reg = DREG(insn, 9);
+    opsize = insn_opsize(insn);
+
+    SRC_EA(env, src, opsize, 0, &addr);
     dest = tcg_temp_new();
-    tcg_gen_xor_i32(dest, src, reg);
-    gen_logic_cc(s, dest, OS_LONG);
-    DEST_EA(env, insn, OS_LONG, dest, &addr);
+    tcg_gen_xor_i32(dest, src, DREG(insn, 9));
+    gen_logic_cc(s, dest, opsize);
+    DEST_EA(env, insn, opsize, dest, &addr);
 }
 
 DISAS_INSN(exg)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PATCH 08/16] target-m68k: or can manage word and byte operands
  2016-10-26 16:35 [Qemu-devel] [PATCH 00/16] 680x0 instruction set, part 1 Laurent Vivier
                   ` (6 preceding siblings ...)
  2016-10-26 16:35 ` [Qemu-devel] [PATCH 07/16] target-m68k: eor can manage word and byte operands Laurent Vivier
@ 2016-10-26 16:35 ` Laurent Vivier
  2016-10-26 16:35 ` [Qemu-devel] [PATCH 09/16] target-m68k: and " Laurent Vivier
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 21+ messages in thread
From: Laurent Vivier @ 2016-10-26 16:35 UTC (permalink / raw)
  To: qemu-devel; +Cc: schwab, agraf, Richard Henderson, gerg, Laurent Vivier

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Richard Henderson <rth@twiddle.net>
---
 target-m68k/translate.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 985bc58..41994b3 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -1989,19 +1989,21 @@ DISAS_INSN(or)
     TCGv dest;
     TCGv src;
     TCGv addr;
+    int opsize;
 
-    reg = DREG(insn, 9);
+    opsize = insn_opsize(insn);
+    reg = gen_extend(DREG(insn, 9), opsize, 0);
     dest = tcg_temp_new();
     if (insn & 0x100) {
-        SRC_EA(env, src, OS_LONG, 0, &addr);
+        SRC_EA(env, src, opsize, 0, &addr);
         tcg_gen_or_i32(dest, src, reg);
-        DEST_EA(env, insn, OS_LONG, dest, &addr);
+        DEST_EA(env, insn, opsize, dest, &addr);
     } else {
-        SRC_EA(env, src, OS_LONG, 0, NULL);
+        SRC_EA(env, src, opsize, 0, NULL);
         tcg_gen_or_i32(dest, src, reg);
-        tcg_gen_mov_i32(reg, dest);
+        gen_partset_reg(opsize, DREG(insn, 9), dest);
     }
-    gen_logic_cc(s, dest, OS_LONG);
+    gen_logic_cc(s, dest, opsize);
 }
 
 DISAS_INSN(suba)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PATCH 09/16] target-m68k: and can manage word and byte operands
  2016-10-26 16:35 [Qemu-devel] [PATCH 00/16] 680x0 instruction set, part 1 Laurent Vivier
                   ` (7 preceding siblings ...)
  2016-10-26 16:35 ` [Qemu-devel] [PATCH 08/16] target-m68k: or " Laurent Vivier
@ 2016-10-26 16:35 ` Laurent Vivier
  2016-10-26 16:36 ` [Qemu-devel] [PATCH 10/16] target-m68k: suba/adda can manage word operand Laurent Vivier
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 21+ messages in thread
From: Laurent Vivier @ 2016-10-26 16:35 UTC (permalink / raw)
  To: qemu-devel; +Cc: schwab, agraf, Richard Henderson, gerg, Laurent Vivier

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Richard Henderson <rth@twiddle.net>
---
 target-m68k/translate.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 41994b3..28c6d93 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -2187,19 +2187,23 @@ DISAS_INSN(and)
     TCGv reg;
     TCGv dest;
     TCGv addr;
+    int opsize;
 
-    reg = DREG(insn, 9);
     dest = tcg_temp_new();
+
+    opsize = insn_opsize(insn);
+    reg = DREG(insn, 9);
     if (insn & 0x100) {
-        SRC_EA(env, src, OS_LONG, 0, &addr);
+        SRC_EA(env, src, opsize, 0, &addr);
         tcg_gen_and_i32(dest, src, reg);
-        DEST_EA(env, insn, OS_LONG, dest, &addr);
+        DEST_EA(env, insn, opsize, dest, &addr);
     } else {
-        SRC_EA(env, src, OS_LONG, 0, NULL);
+        SRC_EA(env, src, opsize, 0, NULL);
         tcg_gen_and_i32(dest, src, reg);
-        tcg_gen_mov_i32(reg, dest);
+        gen_partset_reg(opsize, reg, dest);
     }
-    gen_logic_cc(s, dest, OS_LONG);
+    tcg_temp_free(dest);
+    gen_logic_cc(s, dest, opsize);
 }
 
 DISAS_INSN(adda)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PATCH 10/16] target-m68k: suba/adda can manage word operand
  2016-10-26 16:35 [Qemu-devel] [PATCH 00/16] 680x0 instruction set, part 1 Laurent Vivier
                   ` (8 preceding siblings ...)
  2016-10-26 16:35 ` [Qemu-devel] [PATCH 09/16] target-m68k: and " Laurent Vivier
@ 2016-10-26 16:36 ` Laurent Vivier
  2016-10-26 16:36 ` [Qemu-devel] [PATCH 11/16] target-m68k: some bit ops cleanup Laurent Vivier
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 21+ messages in thread
From: Laurent Vivier @ 2016-10-26 16:36 UTC (permalink / raw)
  To: qemu-devel; +Cc: schwab, agraf, Richard Henderson, gerg, Laurent Vivier

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Richard Henderson <rth@twiddle.net>
---
 target-m68k/translate.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 28c6d93..557f671 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -2011,7 +2011,7 @@ DISAS_INSN(suba)
     TCGv src;
     TCGv reg;
 
-    SRC_EA(env, src, OS_LONG, 0, NULL);
+    SRC_EA(env, src, (insn & 0x100) ? OS_LONG : OS_WORD, 1, NULL);
     reg = AREG(insn, 9);
     tcg_gen_sub_i32(reg, reg, src);
 }
@@ -2211,7 +2211,7 @@ DISAS_INSN(adda)
     TCGv src;
     TCGv reg;
 
-    SRC_EA(env, src, OS_LONG, 0, NULL);
+    SRC_EA(env, src, (insn & 0x100) ? OS_LONG : OS_WORD, 1, NULL);
     reg = AREG(insn, 9);
     tcg_gen_add_i32(reg, reg, src);
 }
@@ -3359,6 +3359,7 @@ void register_m68k_insns (CPUM68KState *env)
     INSN(subx_reg,  9100, f138, M68000);
     INSN(subx_mem,  9108, f138, M68000);
     INSN(suba,      91c0, f1c0, CF_ISA_A);
+    INSN(suba,      90c0, f0c0, M68000);
 
     BASE(undef_mac, a000, f000);
     INSN(mac,       a000, f100, CF_EMAC);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PATCH 11/16] target-m68k: some bit ops cleanup
  2016-10-26 16:35 [Qemu-devel] [PATCH 00/16] 680x0 instruction set, part 1 Laurent Vivier
                   ` (9 preceding siblings ...)
  2016-10-26 16:36 ` [Qemu-devel] [PATCH 10/16] target-m68k: suba/adda can manage word operand Laurent Vivier
@ 2016-10-26 16:36 ` Laurent Vivier
  2016-10-26 16:36 ` [Qemu-devel] [PATCH 12/16] target-m68k: introduce byte and word cc_ops Laurent Vivier
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 21+ messages in thread
From: Laurent Vivier @ 2016-10-26 16:36 UTC (permalink / raw)
  To: qemu-devel; +Cc: schwab, agraf, Richard Henderson, gerg, Laurent Vivier

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Richard Henderson <rth@twiddle.net>
---
 target-m68k/translate.c | 34 +++++++++++++++-------------------
 1 file changed, 15 insertions(+), 19 deletions(-)

diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 557f671..1e473d8 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -1290,39 +1290,36 @@ DISAS_INSN(bitop_reg)
     else
         opsize = OS_LONG;
     op = (insn >> 6) & 3;
-
-    gen_flush_flags(s);
-
     SRC_EA(env, src1, opsize, 0, op ? &addr: NULL);
-    src2 = DREG(insn, 9);
-    dest = tcg_temp_new();
 
-    tmp = tcg_temp_new();
+    gen_flush_flags(s);
+    src2 = tcg_temp_new();
     if (opsize == OS_BYTE)
-        tcg_gen_andi_i32(tmp, src2, 7);
+        tcg_gen_andi_i32(src2, DREG(insn, 9), 7);
     else
-        tcg_gen_andi_i32(tmp, src2, 31);
+        tcg_gen_andi_i32(src2, DREG(insn, 9), 31);
 
-    src2 = tcg_const_i32(1);
-    tcg_gen_shl_i32(src2, src2, tmp);
-    tcg_temp_free(tmp);
+    tmp = tcg_const_i32(1);
+    tcg_gen_shl_i32(tmp, tmp, src2);
+    tcg_temp_free(src2);
 
-    tcg_gen_and_i32(QREG_CC_Z, src1, src2);
+    tcg_gen_and_i32(QREG_CC_Z, src1, tmp);
 
+    dest = tcg_temp_new();
     switch (op) {
     case 1: /* bchg */
-        tcg_gen_xor_i32(dest, src1, src2);
+        tcg_gen_xor_i32(dest, src1, tmp);
         break;
     case 2: /* bclr */
-        tcg_gen_andc_i32(dest, src1, src2);
+        tcg_gen_andc_i32(dest, src1, tmp);
         break;
     case 3: /* bset */
-        tcg_gen_or_i32(dest, src1, src2);
+        tcg_gen_or_i32(dest, src1, tmp);
         break;
     default: /* btst */
         break;
     }
-    tcg_temp_free(src2);
+    tcg_temp_free(tmp);
     if (op) {
         DEST_EA(env, insn, opsize, dest, &addr);
     }
@@ -1406,17 +1403,16 @@ DISAS_INSN(bitop_im)
         return;
     }
 
-    gen_flush_flags(s);
-
     SRC_EA(env, src1, opsize, 0, op ? &addr: NULL);
 
+    gen_flush_flags(s);
     if (opsize == OS_BYTE)
         bitnum &= 7;
     else
         bitnum &= 31;
     mask = 1 << bitnum;
 
-    tcg_gen_andi_i32(QREG_CC_Z, src1, mask);
+   tcg_gen_andi_i32(QREG_CC_Z, src1, mask);
 
     if (op) {
         tmp = tcg_temp_new();
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PATCH 12/16] target-m68k: introduce byte and word cc_ops
  2016-10-26 16:35 [Qemu-devel] [PATCH 00/16] 680x0 instruction set, part 1 Laurent Vivier
                   ` (10 preceding siblings ...)
  2016-10-26 16:36 ` [Qemu-devel] [PATCH 11/16] target-m68k: some bit ops cleanup Laurent Vivier
@ 2016-10-26 16:36 ` Laurent Vivier
  2016-10-26 22:26   ` Richard Henderson
  2016-10-26 16:36 ` [Qemu-devel] [PATCH 13/16] target-m68k: add addressing modes to neg Laurent Vivier
                   ` (3 subsequent siblings)
  15 siblings, 1 reply; 21+ messages in thread
From: Laurent Vivier @ 2016-10-26 16:36 UTC (permalink / raw)
  To: qemu-devel; +Cc: schwab, agraf, Richard Henderson, gerg, Laurent Vivier

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
 target-m68k/cpu.h       |   6 +--
 target-m68k/helper.c    |  25 ++++++---
 target-m68k/translate.c | 131 +++++++++++++++++++++++++++---------------------
 3 files changed, 93 insertions(+), 69 deletions(-)

diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h
index 48c5b81..6dfb54e 100644
--- a/target-m68k/cpu.h
+++ b/target-m68k/cpu.h
@@ -179,11 +179,11 @@ typedef enum {
     CC_OP_FLAGS,
 
     /* X in cc_x, C = X, N in cc_n, Z in cc_n, V via cc_n/cc_v.  */
-    CC_OP_ADD,
-    CC_OP_SUB,
+    CC_OP_ADDB, CC_OP_ADDW, CC_OP_ADDL,
+    CC_OP_SUBB, CC_OP_SUBW, CC_OP_SUBL,
 
     /* X in cc_x, {N,Z,C,V} via cc_n/cc_v.  */
-    CC_OP_CMP,
+    CC_OP_CMPB, CC_OP_CMPW, CC_OP_CMPL,
 
     /* X in cc_x, C = 0, V = 0, N in cc_n, Z in cc_n.  */
     CC_OP_LOGIC,
diff --git a/target-m68k/helper.c b/target-m68k/helper.c
index e838638..7aed9ff 100644
--- a/target-m68k/helper.c
+++ b/target-m68k/helper.c
@@ -584,32 +584,41 @@ void HELPER(mac_set_flags)(CPUM68KState *env, uint32_t acc)
     }
 }
 
+#define EXTSIGN(val, index) (     \
+    (index == 0) ? (int8_t)(val) : ((index == 1) ? (int16_t)(val) : (val)) \
+)
 
 #define COMPUTE_CCR(op, x, n, z, v, c) {                                   \
     switch (op) {                                                          \
     case CC_OP_FLAGS:                                                      \
         /* Everything in place.  */                                        \
         break;                                                             \
-    case CC_OP_ADD:                                                        \
+    case CC_OP_ADDB:                                                       \
+    case CC_OP_ADDW:                                                       \
+    case CC_OP_ADDL:                                                       \
         res = n;                                                           \
         src2 = v;                                                          \
-        src1 = res - src2;                                                 \
+        src1 = EXTSIGN(res - src2, op - CC_OP_ADDB);                       \
         c = x;                                                             \
         z = n;                                                             \
         v = (res ^ src1) & ~(src1 ^ src2);                                 \
         break;                                                             \
-    case CC_OP_SUB:                                                        \
+    case CC_OP_SUBB:                                                       \
+    case CC_OP_SUBW:                                                       \
+    case CC_OP_SUBL:                                                       \
         res = n;                                                           \
         src2 = v;                                                          \
-        src1 = res + src2;                                                 \
+        src1 = EXTSIGN(res + src2, op - CC_OP_SUBB);                       \
         c = x;                                                             \
         z = n;                                                             \
         v = (res ^ src1) & (src1 ^ src2);                                  \
         break;                                                             \
-    case CC_OP_CMP:                                                        \
+    case CC_OP_CMPB:                                                       \
+    case CC_OP_CMPW:                                                       \
+    case CC_OP_CMPL:                                                       \
         src1 = n;                                                          \
         src2 = v;                                                          \
-        res = src1 - src2;                                                 \
+        res = EXTSIGN(src1 - src2, op - CC_OP_CMPB);                       \
         n = res;                                                           \
         z = res;                                                           \
         c = src1 < src2;                                                   \
@@ -630,16 +639,16 @@ uint32_t cpu_m68k_get_ccr(CPUM68KState *env)
     uint32_t res, src1, src2;
 
     x = env->cc_x;
-    c = env->cc_c;
     n = env->cc_n;
     z = env->cc_z;
     v = env->cc_v;
+    c = env->cc_c;
 
     COMPUTE_CCR(env->cc_op, x, n, z, v, c);
 
     n = n >> 31;
-    v = v >> 31;
     z = (z == 0);
+    v = v >> 31;
 
     return x * CCF_X + n * CCF_N + z * CCF_Z + v * CCF_V + c * CCF_C;
 }
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 1e473d8..27bde2e 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -178,9 +178,9 @@ typedef void (*disas_proc)(CPUM68KState *env, DisasContext *s, uint16_t insn);
 
 static const uint8_t cc_op_live[CC_OP_NB] = {
     [CC_OP_FLAGS] = CCF_C | CCF_V | CCF_Z | CCF_N | CCF_X,
-    [CC_OP_ADD] = CCF_X | CCF_N | CCF_V,
-    [CC_OP_SUB] = CCF_X | CCF_N | CCF_V,
-    [CC_OP_CMP] = CCF_X | CCF_N | CCF_V,
+    [CC_OP_ADDB ... CC_OP_ADDL] = CCF_X | CCF_N | CCF_V,
+    [CC_OP_SUBB ... CC_OP_SUBL] = CCF_X | CCF_N | CCF_V,
+    [CC_OP_CMPB ... CC_OP_CMPL] = CCF_X | CCF_N | CCF_V,
     [CC_OP_LOGIC] = CCF_X | CCF_N
 };
 
@@ -454,6 +454,33 @@ static TCGv gen_lea_indexed(CPUM68KState *env, DisasContext *s, TCGv base)
     return add;
 }
 
+/* Sign or zero extend a value.  */
+
+static inline void gen_ext(TCGv res, TCGv val, int opsize, int sign)
+{
+    switch (opsize) {
+    case OS_BYTE:
+        if (sign) {
+            tcg_gen_ext8s_i32(res, val);
+        } else {
+            tcg_gen_ext8u_i32(res, val);
+        }
+        break;
+    case OS_WORD:
+        if (sign) {
+            tcg_gen_ext16s_i32(res, val);
+        } else {
+            tcg_gen_ext16u_i32(res, val);
+        }
+        break;
+    case OS_LONG:
+        tcg_gen_mov_i32(res, val);
+        break;
+    default:
+        g_assert_not_reached();
+    }
+}
+
 /* Evaluate all the CC flags.  */
 
 static void gen_flush_flags(DisasContext *s)
@@ -464,13 +491,16 @@ static void gen_flush_flags(DisasContext *s)
     case CC_OP_FLAGS:
         return;
 
-    case CC_OP_ADD:
+    case CC_OP_ADDB:
+    case CC_OP_ADDW:
+    case CC_OP_ADDL:
         tcg_gen_mov_i32(QREG_CC_C, QREG_CC_X);
         tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N);
         /* Compute signed overflow for addition.  */
         t0 = tcg_temp_new();
         t1 = tcg_temp_new();
         tcg_gen_sub_i32(t0, QREG_CC_N, QREG_CC_V);
+        gen_ext(t0, t0, s->cc_op - CC_OP_ADDB, 1);
         tcg_gen_xor_i32(t1, QREG_CC_N, QREG_CC_V);
         tcg_gen_xor_i32(QREG_CC_V, QREG_CC_V, t0);
         tcg_temp_free(t0);
@@ -478,13 +508,16 @@ static void gen_flush_flags(DisasContext *s)
         tcg_temp_free(t1);
         break;
 
-    case CC_OP_SUB:
+    case CC_OP_SUBB:
+    case CC_OP_SUBW:
+    case CC_OP_SUBL:
         tcg_gen_mov_i32(QREG_CC_C, QREG_CC_X);
         tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N);
         /* Compute signed overflow for subtraction.  */
         t0 = tcg_temp_new();
         t1 = tcg_temp_new();
         tcg_gen_add_i32(t0, QREG_CC_N, QREG_CC_V);
+        gen_ext(t0, t0, s->cc_op - CC_OP_SUBB, 1);
         tcg_gen_xor_i32(t1, QREG_CC_N, QREG_CC_V);
         tcg_gen_xor_i32(QREG_CC_V, QREG_CC_V, t0);
         tcg_temp_free(t0);
@@ -492,9 +525,12 @@ static void gen_flush_flags(DisasContext *s)
         tcg_temp_free(t1);
         break;
 
-    case CC_OP_CMP:
+    case CC_OP_CMPB:
+    case CC_OP_CMPW:
+    case CC_OP_CMPL:
         tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_C, QREG_CC_N, QREG_CC_V);
         tcg_gen_sub_i32(QREG_CC_Z, QREG_CC_N, QREG_CC_V);
+        gen_ext(QREG_CC_Z, QREG_CC_Z, s->cc_op - CC_OP_CMPB, 1);
         /* Compute signed overflow for subtraction.  */
         t0 = tcg_temp_new();
         tcg_gen_xor_i32(t0, QREG_CC_Z, QREG_CC_N);
@@ -526,34 +562,7 @@ static void gen_flush_flags(DisasContext *s)
     s->cc_op_synced = 1;
 }
 
-/* Sign or zero extend a value.  */
-
-static inline void gen_ext(TCGv res, TCGv val, int opsize, int sign)
-{
-    switch (opsize) {
-    case OS_BYTE:
-        if (sign) {
-            tcg_gen_ext8s_i32(res, val);
-        } else {
-            tcg_gen_ext8u_i32(res, val);
-        }
-        break;
-    case OS_WORD:
-        if (sign) {
-            tcg_gen_ext16s_i32(res, val);
-        } else {
-            tcg_gen_ext16u_i32(res, val);
-        }
-        break;
-    case OS_LONG:
-        tcg_gen_mov_i32(res, val);
-        break;
-    default:
-        g_assert_not_reached();
-    }
-}
-
-static TCGv gen_extend(TCGv val, int opsize, int sign)
+static inline TCGv gen_extend(TCGv val, int opsize, int sign)
 {
     TCGv tmp;
 
@@ -573,9 +582,9 @@ static void gen_logic_cc(DisasContext *s, TCGv val, int opsize)
     set_cc_op(s, CC_OP_LOGIC);
 }
 
-static void gen_update_cc_add(TCGv dest, TCGv src)
+static void gen_update_cc_add(TCGv dest, TCGv src, int opsize)
 {
-    tcg_gen_mov_i32(QREG_CC_N, dest);
+    gen_ext(QREG_CC_N, dest, opsize, 1);
     tcg_gen_mov_i32(QREG_CC_V, src);
 }
 
@@ -822,7 +831,7 @@ static void gen_cc_cond(DisasCompare *c, DisasContext *s, int cond)
     CCOp op = s->cc_op;
 
     /* The CC_OP_CMP form can handle most normal comparisons directly.  */
-    if (op == CC_OP_CMP) {
+    if (op == CC_OP_CMPB || op == CC_OP_CMPW || op == CC_OP_CMPL) {
         c->g1 = c->g2 = 1;
         c->v1 = QREG_CC_N;
         c->v2 = QREG_CC_V;
@@ -845,6 +854,7 @@ static void gen_cc_cond(DisasCompare *c, DisasContext *s, int cond)
             c->v2 = tcg_const_i32(0);
             c->v1 = tmp = tcg_temp_new();
             tcg_gen_sub_i32(tmp, QREG_CC_N, QREG_CC_V);
+            gen_ext(tmp, tmp, op - CC_OP_CMPB, 1);
             /* fallthru */
         case 12: /* GE */
         case 13: /* LT */
@@ -888,7 +898,9 @@ static void gen_cc_cond(DisasCompare *c, DisasContext *s, int cond)
     case 10: /* PL (!N) */
     case 11: /* MI (N) */
         /* Several cases represent N normally.  */
-        if (op == CC_OP_ADD || op == CC_OP_SUB || op == CC_OP_LOGIC) {
+        if (op == CC_OP_ADDB || op == CC_OP_ADDW || op == CC_OP_ADDL ||
+            op == CC_OP_SUBB || op == CC_OP_SUBW || op == CC_OP_SUBL ||
+            op == CC_OP_LOGIC) {
             c->v1 = QREG_CC_N;
             tcond = TCG_COND_LT;
             goto done;
@@ -897,7 +909,9 @@ static void gen_cc_cond(DisasCompare *c, DisasContext *s, int cond)
     case 6: /* NE (!Z) */
     case 7: /* EQ (Z) */
         /* Some cases fold Z into N.  */
-        if (op == CC_OP_ADD || op == CC_OP_SUB || op == CC_OP_LOGIC) {
+        if (op == CC_OP_ADDB || op == CC_OP_ADDW || op == CC_OP_ADDL ||
+            op == CC_OP_SUBB || op == CC_OP_SUBW || op == CC_OP_SUBL ||
+            op == CC_OP_LOGIC) {
             tcond = TCG_COND_EQ;
             c->v1 = QREG_CC_N;
             goto done;
@@ -906,7 +920,8 @@ static void gen_cc_cond(DisasCompare *c, DisasContext *s, int cond)
     case 4: /* CC (!C) */
     case 5: /* CS (C) */
         /* Some cases fold C into X.  */
-        if (op == CC_OP_ADD || op == CC_OP_SUB) {
+        if (op == CC_OP_ADDB || op == CC_OP_ADDW || op == CC_OP_ADDL ||
+            op == CC_OP_ADDB || op == CC_OP_ADDW || op == CC_OP_ADDL) {
             tcond = TCG_COND_NE;
             c->v1 = QREG_CC_X;
             goto done;
@@ -1252,13 +1267,13 @@ DISAS_INSN(addsub)
     if (add) {
         tcg_gen_add_i32(dest, tmp, src);
         tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, dest, src);
-        set_cc_op(s, CC_OP_ADD);
+        set_cc_op(s, CC_OP_ADDL);
     } else {
         tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, tmp, src);
         tcg_gen_sub_i32(dest, tmp, src);
-        set_cc_op(s, CC_OP_SUB);
+        set_cc_op(s, CC_OP_SUBL);
     }
-    gen_update_cc_add(dest, src);
+    gen_update_cc_add(dest, src, OS_LONG);
     if (insn & 0x100) {
         DEST_EA(env, insn, OS_LONG, dest, &addr);
     } else {
@@ -1459,23 +1474,23 @@ DISAS_INSN(arith_im)
         tcg_gen_mov_i32(dest, src1);
         tcg_gen_setcondi_i32(TCG_COND_LTU, QREG_CC_X, dest, im);
         tcg_gen_subi_i32(dest, dest, im);
-        gen_update_cc_add(dest, tcg_const_i32(im));
-        set_cc_op(s, CC_OP_SUB);
+        gen_update_cc_add(dest, tcg_const_i32(im), OS_LONG);
+        set_cc_op(s, CC_OP_SUBL);
         break;
     case 3: /* addi */
         tcg_gen_mov_i32(dest, src1);
         tcg_gen_addi_i32(dest, dest, im);
-        gen_update_cc_add(dest, tcg_const_i32(im));
+        gen_update_cc_add(dest, tcg_const_i32(im), OS_LONG);
         tcg_gen_setcondi_i32(TCG_COND_LTU, QREG_CC_X, dest, im);
-        set_cc_op(s, CC_OP_ADD);
+        set_cc_op(s, CC_OP_ADDL);
         break;
     case 5: /* eori */
         tcg_gen_xori_i32(dest, src1, im);
         gen_logic_cc(s, dest, OS_LONG);
         break;
     case 6: /* cmpi */
-        gen_update_cc_add(src1, tcg_const_i32(im));
-        set_cc_op(s, CC_OP_CMP);
+        gen_update_cc_add(src1, tcg_const_i32(im), OS_LONG);
+        set_cc_op(s, CC_OP_CMPL);
         break;
     default:
         abort();
@@ -1623,9 +1638,9 @@ DISAS_INSN(neg)
     src1 = tcg_temp_new();
     tcg_gen_mov_i32(src1, reg);
     tcg_gen_neg_i32(reg, src1);
-    gen_update_cc_add(reg, src1);
+    gen_update_cc_add(reg, src1, OS_LONG);
     tcg_gen_setcondi_i32(TCG_COND_NE, QREG_CC_X, src1, 0);
-    set_cc_op(s, CC_OP_SUB);
+    set_cc_op(s, CC_OP_SUBL);
 }
 
 static void gen_set_sr_im(DisasContext *s, uint16_t val, int ccr_only)
@@ -1895,13 +1910,13 @@ DISAS_INSN(addsubq)
         if (insn & 0x0100) {
             tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, dest, src2);
             tcg_gen_sub_i32(dest, dest, src2);
-            set_cc_op(s, CC_OP_SUB);
+            set_cc_op(s, CC_OP_SUBL);
         } else {
             tcg_gen_add_i32(dest, dest, src2);
             tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, dest, src2);
-            set_cc_op(s, CC_OP_ADD);
+            set_cc_op(s, CC_OP_ADDL);
         }
-        gen_update_cc_add(dest, src2);
+        gen_update_cc_add(dest, src2, OS_LONG);
     }
     DEST_EA(env, insn, OS_LONG, dest, &addr);
 }
@@ -2105,8 +2120,8 @@ DISAS_INSN(cmp)
     opsize = insn_opsize(insn);
     SRC_EA(env, src, opsize, -1, NULL);
     reg = DREG(insn, 9);
-    gen_update_cc_add(reg, src);
-    set_cc_op(s, CC_OP_CMP);
+    gen_update_cc_add(reg, src, OS_LONG);
+    set_cc_op(s, CC_OP_CMPL);
 }
 
 DISAS_INSN(cmpa)
@@ -2122,8 +2137,8 @@ DISAS_INSN(cmpa)
     }
     SRC_EA(env, src, opsize, 1, NULL);
     reg = AREG(insn, 9);
-    gen_update_cc_add(reg, src);
-    set_cc_op(s, CC_OP_CMP);
+    gen_update_cc_add(reg, src, OS_LONG);
+    set_cc_op(s, CC_OP_CMPL);
 }
 
 DISAS_INSN(eor)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PATCH 13/16] target-m68k: add addressing modes to neg
  2016-10-26 16:35 [Qemu-devel] [PATCH 00/16] 680x0 instruction set, part 1 Laurent Vivier
                   ` (11 preceding siblings ...)
  2016-10-26 16:36 ` [Qemu-devel] [PATCH 12/16] target-m68k: introduce byte and word cc_ops Laurent Vivier
@ 2016-10-26 16:36 ` Laurent Vivier
  2016-10-26 16:36 ` [Qemu-devel] [PATCH 14/16] target-m68k: add/sub manage word and byte operands Laurent Vivier
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 21+ messages in thread
From: Laurent Vivier @ 2016-10-26 16:36 UTC (permalink / raw)
  To: qemu-devel; +Cc: schwab, agraf, Richard Henderson, gerg, Laurent Vivier

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Richard Henderson <rth@twiddle.net>
---
 target-m68k/translate.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 27bde2e..383709d 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -1631,16 +1631,20 @@ DISAS_INSN(move_from_ccr)
 
 DISAS_INSN(neg)
 {
-    TCGv reg;
     TCGv src1;
+    TCGv dest;
+    TCGv addr;
+    int opsize;
 
-    reg = DREG(insn, 0);
-    src1 = tcg_temp_new();
-    tcg_gen_mov_i32(src1, reg);
-    tcg_gen_neg_i32(reg, src1);
-    gen_update_cc_add(reg, src1, OS_LONG);
-    tcg_gen_setcondi_i32(TCG_COND_NE, QREG_CC_X, src1, 0);
-    set_cc_op(s, CC_OP_SUBL);
+    opsize = insn_opsize(insn);
+    SRC_EA(env, src1, opsize, 1, &addr);
+    dest = tcg_temp_new();
+    tcg_gen_neg_i32(dest, src1);
+    set_cc_op(s, CC_OP_SUBB + opsize);
+    gen_update_cc_add(dest, src1, opsize);
+    tcg_gen_setcondi_i32(TCG_COND_NE, QREG_CC_X, dest, 0);
+    DEST_EA(env, insn, opsize, dest, &addr);
+    tcg_temp_free(dest);
 }
 
 static void gen_set_sr_im(DisasContext *s, uint16_t val, int ccr_only)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PATCH 14/16] target-m68k: add/sub manage word and byte operands
  2016-10-26 16:35 [Qemu-devel] [PATCH 00/16] 680x0 instruction set, part 1 Laurent Vivier
                   ` (12 preceding siblings ...)
  2016-10-26 16:36 ` [Qemu-devel] [PATCH 13/16] target-m68k: add addressing modes to neg Laurent Vivier
@ 2016-10-26 16:36 ` Laurent Vivier
  2016-10-26 16:36 ` [Qemu-devel] [PATCH 15/16] target-m68k: cmp manages word and bytes operands Laurent Vivier
  2016-10-26 16:36 ` [Qemu-devel] [PATCH 16/16] target-m68k: immediate ops manage word and byte operands Laurent Vivier
  15 siblings, 0 replies; 21+ messages in thread
From: Laurent Vivier @ 2016-10-26 16:36 UTC (permalink / raw)
  To: qemu-devel; +Cc: schwab, agraf, Richard Henderson, gerg, Laurent Vivier

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Richard Henderson <rth@twiddle.net>
---
 target-m68k/translate.c | 73 +++++++++++++++++++++++++++----------------------
 1 file changed, 40 insertions(+), 33 deletions(-)

diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 383709d..3659b9f 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -1253,35 +1253,37 @@ DISAS_INSN(addsub)
     TCGv tmp;
     TCGv addr;
     int add;
+    int opsize;
 
     add = (insn & 0x4000) != 0;
-    reg = DREG(insn, 9);
+    opsize = insn_opsize(insn);
+    reg = gen_extend(DREG(insn, 9), opsize, 1);
     dest = tcg_temp_new();
     if (insn & 0x100) {
-        SRC_EA(env, tmp, OS_LONG, 0, &addr);
+        SRC_EA(env, tmp, opsize, 1, &addr);
         src = reg;
     } else {
         tmp = reg;
-        SRC_EA(env, src, OS_LONG, 0, NULL);
+        SRC_EA(env, src, opsize, 1, NULL);
     }
     if (add) {
         tcg_gen_add_i32(dest, tmp, src);
         tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, dest, src);
-        set_cc_op(s, CC_OP_ADDL);
+        set_cc_op(s, CC_OP_ADDB + opsize);
     } else {
         tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, tmp, src);
         tcg_gen_sub_i32(dest, tmp, src);
-        set_cc_op(s, CC_OP_SUBL);
+        set_cc_op(s, CC_OP_SUBB + opsize);
     }
-    gen_update_cc_add(dest, src, OS_LONG);
+    gen_update_cc_add(dest, src, opsize);
     if (insn & 0x100) {
-        DEST_EA(env, insn, OS_LONG, dest, &addr);
+        DEST_EA(env, insn, opsize, dest, &addr);
     } else {
-        tcg_gen_mov_i32(reg, dest);
+        gen_partset_reg(opsize, DREG(insn, 9), dest);
     }
+    tcg_temp_free(dest);
 }
 
-
 /* Reverse the order of the bits in REG.  */
 DISAS_INSN(bitrev)
 {
@@ -1889,40 +1891,48 @@ DISAS_INSN(jump)
 
 DISAS_INSN(addsubq)
 {
-    TCGv src1;
-    TCGv src2;
+    TCGv src;
     TCGv dest;
-    int val;
+    TCGv val;
+    int imm;
     TCGv addr;
+    int opsize;
 
-    SRC_EA(env, src1, OS_LONG, 0, &addr);
-    val = (insn >> 9) & 7;
-    if (val == 0)
-        val = 8;
+    if ((insn & 070) == 010) {
+        /* Operation on address register is always long.  */
+        opsize = OS_LONG;
+    } else {
+        opsize = insn_opsize(insn);
+    }
+    SRC_EA(env, src, opsize, 1, &addr);
+    imm = (insn >> 9) & 7;
+    if (imm == 0) {
+        imm = 8;
+    }
+    val = tcg_const_i32(imm);
     dest = tcg_temp_new();
-    tcg_gen_mov_i32(dest, src1);
+    tcg_gen_mov_i32(dest, src);
     if ((insn & 0x38) == 0x08) {
         /* Don't update condition codes if the destination is an
            address register.  */
         if (insn & 0x0100) {
-            tcg_gen_subi_i32(dest, dest, val);
+            tcg_gen_sub_i32(dest, dest, val);
         } else {
-            tcg_gen_addi_i32(dest, dest, val);
+            tcg_gen_add_i32(dest, dest, val);
         }
     } else {
-        src2 = tcg_const_i32(val);
         if (insn & 0x0100) {
-            tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, dest, src2);
-            tcg_gen_sub_i32(dest, dest, src2);
-            set_cc_op(s, CC_OP_SUBL);
+            tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, dest, val);
+            tcg_gen_sub_i32(dest, dest, val);
+            set_cc_op(s, CC_OP_SUBB + opsize);
         } else {
-            tcg_gen_add_i32(dest, dest, src2);
-            tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, dest, src2);
-            set_cc_op(s, CC_OP_ADDL);
+            tcg_gen_add_i32(dest, dest, val);
+            tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, dest, val);
+            set_cc_op(s, CC_OP_ADDB + opsize);
         }
-        gen_update_cc_add(dest, src2, OS_LONG);
+        gen_update_cc_add(dest, val, opsize);
     }
-    DEST_EA(env, insn, OS_LONG, dest, &addr);
+    DEST_EA(env, insn, opsize, dest, &addr);
 }
 
 DISAS_INSN(tpf)
@@ -3344,15 +3354,12 @@ void register_m68k_insns (CPUM68KState *env)
     BASE(rts,       4e75, ffff);
     INSN(movec,     4e7b, ffff, CF_ISA_A);
     BASE(jump,      4e80, ffc0);
-    INSN(jump,      4ec0, ffc0, CF_ISA_A);
-    INSN(addsubq,   5180, f1c0, CF_ISA_A);
-    INSN(jump,      4ec0, ffc0, M68000);
+    BASE(jump,      4ec0, ffc0);
     INSN(addsubq,   5000, f080, M68000);
-    INSN(addsubq,   5080, f0c0, M68000);
+    BASE(addsubq,   5080, f0c0);
     INSN(scc,       50c0, f0f8, CF_ISA_A); /* Scc.B Dx   */
     INSN(scc,       50c0, f0c0, M68000);   /* Scc.B <EA> */
     INSN(dbcc,      50c8, f0f8, M68000);
-    INSN(addsubq,   5080, f1c0, CF_ISA_A);
     INSN(tpf,       51f8, fff8, CF_ISA_A);
 
     /* Branch instructions.  */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PATCH 15/16] target-m68k: cmp manages word and bytes operands
  2016-10-26 16:35 [Qemu-devel] [PATCH 00/16] 680x0 instruction set, part 1 Laurent Vivier
                   ` (13 preceding siblings ...)
  2016-10-26 16:36 ` [Qemu-devel] [PATCH 14/16] target-m68k: add/sub manage word and byte operands Laurent Vivier
@ 2016-10-26 16:36 ` Laurent Vivier
  2016-10-26 16:36 ` [Qemu-devel] [PATCH 16/16] target-m68k: immediate ops manage word and byte operands Laurent Vivier
  15 siblings, 0 replies; 21+ messages in thread
From: Laurent Vivier @ 2016-10-26 16:36 UTC (permalink / raw)
  To: qemu-devel; +Cc: schwab, agraf, Richard Henderson, gerg, Laurent Vivier

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Richard Henderson <rth@twiddle.net>
---
 target-m68k/translate.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 3659b9f..1685abb 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -582,6 +582,13 @@ static void gen_logic_cc(DisasContext *s, TCGv val, int opsize)
     set_cc_op(s, CC_OP_LOGIC);
 }
 
+static void gen_update_cc_cmp(DisasContext *s, TCGv dest, TCGv src, int opsize)
+{
+    tcg_gen_mov_i32(QREG_CC_N, dest);
+    tcg_gen_mov_i32(QREG_CC_V, src);
+    set_cc_op(s, CC_OP_CMPB + opsize);
+}
+
 static void gen_update_cc_add(TCGv dest, TCGv src, int opsize)
 {
     gen_ext(QREG_CC_N, dest, opsize, 1);
@@ -2132,10 +2139,9 @@ DISAS_INSN(cmp)
     int opsize;
 
     opsize = insn_opsize(insn);
-    SRC_EA(env, src, opsize, -1, NULL);
-    reg = DREG(insn, 9);
-    gen_update_cc_add(reg, src, OS_LONG);
-    set_cc_op(s, CC_OP_CMPL);
+    SRC_EA(env, src, opsize, 1, NULL);
+    reg = gen_extend(DREG(insn, 9), opsize, 1);
+    gen_update_cc_cmp(s, reg, src, opsize);
 }
 
 DISAS_INSN(cmpa)
@@ -2151,8 +2157,7 @@ DISAS_INSN(cmpa)
     }
     SRC_EA(env, src, opsize, 1, NULL);
     reg = AREG(insn, 9);
-    gen_update_cc_add(reg, src, OS_LONG);
-    set_cc_op(s, CC_OP_CMPL);
+    gen_update_cc_cmp(s, reg, src, opsize);
 }
 
 DISAS_INSN(eor)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PATCH 16/16] target-m68k: immediate ops manage word and byte operands
  2016-10-26 16:35 [Qemu-devel] [PATCH 00/16] 680x0 instruction set, part 1 Laurent Vivier
                   ` (14 preceding siblings ...)
  2016-10-26 16:36 ` [Qemu-devel] [PATCH 15/16] target-m68k: cmp manages word and bytes operands Laurent Vivier
@ 2016-10-26 16:36 ` Laurent Vivier
  15 siblings, 0 replies; 21+ messages in thread
From: Laurent Vivier @ 2016-10-26 16:36 UTC (permalink / raw)
  To: qemu-devel; +Cc: schwab, agraf, Richard Henderson, gerg, Laurent Vivier

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Richard Henderson <rth@twiddle.net>
---
 target-m68k/translate.c | 57 ++++++++++++++++++++++++++++++-------------------
 1 file changed, 35 insertions(+), 22 deletions(-)

diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 1685abb..125b502 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -1461,52 +1461,65 @@ DISAS_INSN(bitop_im)
 DISAS_INSN(arith_im)
 {
     int op;
-    uint32_t im;
+    TCGv im;
     TCGv src1;
     TCGv dest;
     TCGv addr;
+    int opsize;
 
     op = (insn >> 9) & 7;
-    SRC_EA(env, src1, OS_LONG, 0, (op == 6) ? NULL : &addr);
-    im = read_im32(env, s);
+    opsize = insn_opsize(insn);
+    switch (opsize) {
+    case OS_BYTE:
+        im = tcg_const_i32((int8_t)read_im8(env, s));
+        break;
+    case OS_WORD:
+        im = tcg_const_i32((int16_t)read_im16(env, s));
+        break;
+    case OS_LONG:
+        im = tcg_const_i32(read_im32(env, s));
+        break;
+    default:
+       abort();
+    }
+    SRC_EA(env, src1, opsize, 1, (op == 6) ? NULL : &addr);
     dest = tcg_temp_new();
     switch (op) {
     case 0: /* ori */
-        tcg_gen_ori_i32(dest, src1, im);
-        gen_logic_cc(s, dest, OS_LONG);
+        tcg_gen_or_i32(dest, src1, im);
+        gen_logic_cc(s, dest, opsize);
         break;
     case 1: /* andi */
-        tcg_gen_andi_i32(dest, src1, im);
-        gen_logic_cc(s, dest, OS_LONG);
+        tcg_gen_and_i32(dest, src1, im);
+        gen_logic_cc(s, dest, opsize);
         break;
     case 2: /* subi */
-        tcg_gen_mov_i32(dest, src1);
-        tcg_gen_setcondi_i32(TCG_COND_LTU, QREG_CC_X, dest, im);
-        tcg_gen_subi_i32(dest, dest, im);
-        gen_update_cc_add(dest, tcg_const_i32(im), OS_LONG);
-        set_cc_op(s, CC_OP_SUBL);
+        tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, src1, im);
+        tcg_gen_sub_i32(dest, src1, im);
+        gen_update_cc_add(dest, im, opsize);
+        set_cc_op(s, CC_OP_SUBB + opsize);
         break;
     case 3: /* addi */
-        tcg_gen_mov_i32(dest, src1);
-        tcg_gen_addi_i32(dest, dest, im);
-        gen_update_cc_add(dest, tcg_const_i32(im), OS_LONG);
-        tcg_gen_setcondi_i32(TCG_COND_LTU, QREG_CC_X, dest, im);
-        set_cc_op(s, CC_OP_ADDL);
+        tcg_gen_add_i32(dest, src1, im);
+        gen_update_cc_add(dest, im, opsize);
+        tcg_gen_setcond_i32(TCG_COND_LTU, QREG_CC_X, dest, im);
+        set_cc_op(s, CC_OP_ADDB + opsize);
         break;
     case 5: /* eori */
-        tcg_gen_xori_i32(dest, src1, im);
-        gen_logic_cc(s, dest, OS_LONG);
+        tcg_gen_xor_i32(dest, src1, im);
+        gen_logic_cc(s, dest, opsize);
         break;
     case 6: /* cmpi */
-        gen_update_cc_add(src1, tcg_const_i32(im), OS_LONG);
-        set_cc_op(s, CC_OP_CMPL);
+        gen_update_cc_cmp(s, src1, im, opsize);
         break;
     default:
         abort();
     }
+    tcg_temp_free(im);
     if (op != 6) {
-        DEST_EA(env, insn, OS_LONG, dest, &addr);
+        DEST_EA(env, insn, opsize, dest, &addr);
     }
+    tcg_temp_free(dest);
 }
 
 DISAS_INSN(byterev)
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] [PATCH 01/16] target-m68k: add bkpt instruction
  2016-10-26 16:35 ` [Qemu-devel] [PATCH 01/16] target-m68k: add bkpt instruction Laurent Vivier
@ 2016-10-26 21:38   ` Richard Henderson
  0 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2016-10-26 21:38 UTC (permalink / raw)
  To: Laurent Vivier, qemu-devel; +Cc: gerg, schwab, agraf

On 10/26/2016 09:35 AM, Laurent Vivier wrote:
> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
> ---
>  target-m68k/translate.c | 6 ++++++
>  1 file changed, 6 insertions(+)

Reviewed-by: Richard Henderson <rth@twiddle.net>

r~

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] [PATCH 03/16] target-m68k: add exg ops
  2016-10-26 16:35 ` [Qemu-devel] [PATCH 03/16] target-m68k: add exg ops Laurent Vivier
@ 2016-10-26 22:07   ` Richard Henderson
  0 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2016-10-26 22:07 UTC (permalink / raw)
  To: Laurent Vivier, qemu-devel; +Cc: gerg, schwab, agraf

On 10/26/2016 09:35 AM, Laurent Vivier wrote:
> +    INSN(undef,     c140, f1f8, CF_ISA_A);
> +    INSN(exg,       c140, f1f8, M68000);
> +    INSN(undef,     c148, f1f8, CF_ISA_A);
> +    INSN(exg,       c148, f1f8, M68000);
> +    INSN(undef,     c188, f1f8, CF_ISA_A);
> +    INSN(exg,       c188, f1f8, M68000);

Given that we started with

+    BASE(undef,     0000, 0000);

why do we need to re-add these undef's?

Otherwise, why not use these, and a helper, to avoid having to re-decode.

static void do_exg(TCGv reg1, TCGv reg2)
{
     TCGv temp = tcg_temp_new();
     tcg_gen_mov_i32(temp, reg1);
     tcg_gen_mov_i32(reg1, reg2);
     tcg_gen_mov_i32(reg2, temp);
     tcg_temp_free(temp);
}

DISAS_INSN(exg_dd)
{
     do_exg(DREG(insn, 9), DREG(insn, 0));
}

DISAS_INSN(exg_aa)
{
     do_exg(AREG(insn, 9), AREG(insn, 0));
}

DISAS_INSN(exg_da)
{
     do_exg(DREG(insn, 9), AREG(insn, 0));
}


r~

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] [PATCH 04/16] target-m68k: add scc/dbcc
  2016-10-26 16:35 ` [Qemu-devel] [PATCH 04/16] target-m68k: add scc/dbcc Laurent Vivier
@ 2016-10-26 22:12   ` Richard Henderson
  0 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2016-10-26 22:12 UTC (permalink / raw)
  To: Laurent Vivier, qemu-devel; +Cc: gerg, schwab, agraf

On 10/26/2016 09:35 AM, Laurent Vivier wrote:
> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
> ---
>  target-m68k/translate.c | 65 ++++++++++++++++++++++++++++++++++---------------
>  1 file changed, 45 insertions(+), 20 deletions(-)
>
> diff --git a/target-m68k/translate.c b/target-m68k/translate.c
> index a07b6f5..05efd29 100644
> --- a/target-m68k/translate.c
> +++ b/target-m68k/translate.c
> @@ -1008,25 +1008,6 @@ static void gen_jmpcc(DisasContext *s, int cond, TCGLabel *l1)
>    free_cond(&c);
>  }
>
> -DISAS_INSN(scc)
> -{
> -    DisasCompare c;
> -    int cond;
> -    TCGv reg, tmp;
> -
> -    cond = (insn >> 8) & 0xf;
> -    gen_cc_cond(&c, s, cond);
> -
> -    tmp = tcg_temp_new();
> -    tcg_gen_setcond_i32(c.tcond, tmp, c.v1, c.v2);
> -    free_cond(&c);
> -
> -    reg = DREG(insn, 0);
> -    tcg_gen_neg_i32(tmp, tmp);
> -    tcg_gen_deposit_i32(reg, reg, tmp, 0, 8);
> -    tcg_temp_free(tmp);
> -}
> -
>  /* Force a TB lookup after an instruction that changes the CPU state.  */
>  static void gen_lookup_tb(DisasContext *s)
>  {
> @@ -1106,6 +1087,48 @@ static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest)
>      s->is_jmp = DISAS_TB_JUMP;
>  }
>
> +DISAS_INSN(scc)
> +{
> +    DisasCompare c;
> +    int cond;
> +    TCGv tmp;
> +
> +    cond = (insn >> 8) & 0xf;
> +    gen_cc_cond(&c, s, cond);
> +
> +    tmp = tcg_temp_new();
> +    tcg_gen_setcond_i32(c.tcond, tmp, c.v1, c.v2);
> +    free_cond(&c);
> +
> +    tcg_gen_neg_i32(tmp, tmp);
> +    DEST_EA(env, insn, OS_BYTE, tmp, NULL);
> +    tcg_temp_free(tmp);
> +}

This change to scc, to add support for EA, should be in a separate patch from 
adding dbcc.  Otherwise it looks good.


r~


> +
> +DISAS_INSN(dbcc)
> +{
> +    TCGLabel *l1;
> +    TCGv reg;
> +    TCGv tmp;
> +    int16_t offset;
> +    uint32_t base;
> +
> +    reg = DREG(insn, 0);
> +    base = s->pc;
> +    offset = (int16_t)read_im16(env, s);
> +    l1 = gen_new_label();
> +    gen_jmpcc(s, (insn >> 8) & 0xf, l1);
> +
> +    tmp = tcg_temp_new();
> +    tcg_gen_ext16s_i32(tmp, reg);
> +    tcg_gen_addi_i32(tmp, tmp, -1);
> +    gen_partset_reg(OS_WORD, reg, tmp);
> +    tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, -1, l1);
> +    gen_jmp_tb(s, 1, base + offset);
> +    gen_set_label(l1);
> +    gen_jmp_tb(s, 0, s->pc);
> +}
> +
>  DISAS_INSN(undef_mac)
>  {
>      gen_exception(s, s->pc - 2, EXCP_LINEA);
> @@ -3144,7 +3167,9 @@ void register_m68k_insns (CPUM68KState *env)
>      INSN(jump,      4ec0, ffc0, M68000);
>      INSN(addsubq,   5000, f080, M68000);
>      INSN(addsubq,   5080, f0c0, M68000);
> -    INSN(scc,       50c0, f0f8, CF_ISA_A);
> +    INSN(scc,       50c0, f0f8, CF_ISA_A); /* Scc.B Dx   */
> +    INSN(scc,       50c0, f0c0, M68000);   /* Scc.B <EA> */
> +    INSN(dbcc,      50c8, f0f8, M68000);
>      INSN(addsubq,   5080, f1c0, CF_ISA_A);
>      INSN(tpf,       51f8, fff8, CF_ISA_A);
>
>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] [PATCH 12/16] target-m68k: introduce byte and word cc_ops
  2016-10-26 16:36 ` [Qemu-devel] [PATCH 12/16] target-m68k: introduce byte and word cc_ops Laurent Vivier
@ 2016-10-26 22:26   ` Richard Henderson
  0 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2016-10-26 22:26 UTC (permalink / raw)
  To: Laurent Vivier, qemu-devel; +Cc: gerg, schwab, agraf

On 10/26/2016 09:36 AM, Laurent Vivier wrote:
> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
> ---
>  target-m68k/cpu.h       |   6 +--
>  target-m68k/helper.c    |  25 ++++++---
>  target-m68k/translate.c | 131 +++++++++++++++++++++++++++---------------------
>  3 files changed, 93 insertions(+), 69 deletions(-)

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2016-10-26 22:26 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-26 16:35 [Qemu-devel] [PATCH 00/16] 680x0 instruction set, part 1 Laurent Vivier
2016-10-26 16:35 ` [Qemu-devel] [PATCH 01/16] target-m68k: add bkpt instruction Laurent Vivier
2016-10-26 21:38   ` Richard Henderson
2016-10-26 16:35 ` [Qemu-devel] [PATCH 02/16] target-m68k: add linkl Laurent Vivier
2016-10-26 16:35 ` [Qemu-devel] [PATCH 03/16] target-m68k: add exg ops Laurent Vivier
2016-10-26 22:07   ` Richard Henderson
2016-10-26 16:35 ` [Qemu-devel] [PATCH 04/16] target-m68k: add scc/dbcc Laurent Vivier
2016-10-26 22:12   ` Richard Henderson
2016-10-26 16:35 ` [Qemu-devel] [PATCH 05/16] target-m68k: Inline addx, subx, negx Laurent Vivier
2016-10-26 16:35 ` [Qemu-devel] [PATCH 06/16] target-m68k: add addressing modes to not Laurent Vivier
2016-10-26 16:35 ` [Qemu-devel] [PATCH 07/16] target-m68k: eor can manage word and byte operands Laurent Vivier
2016-10-26 16:35 ` [Qemu-devel] [PATCH 08/16] target-m68k: or " Laurent Vivier
2016-10-26 16:35 ` [Qemu-devel] [PATCH 09/16] target-m68k: and " Laurent Vivier
2016-10-26 16:36 ` [Qemu-devel] [PATCH 10/16] target-m68k: suba/adda can manage word operand Laurent Vivier
2016-10-26 16:36 ` [Qemu-devel] [PATCH 11/16] target-m68k: some bit ops cleanup Laurent Vivier
2016-10-26 16:36 ` [Qemu-devel] [PATCH 12/16] target-m68k: introduce byte and word cc_ops Laurent Vivier
2016-10-26 22:26   ` Richard Henderson
2016-10-26 16:36 ` [Qemu-devel] [PATCH 13/16] target-m68k: add addressing modes to neg Laurent Vivier
2016-10-26 16:36 ` [Qemu-devel] [PATCH 14/16] target-m68k: add/sub manage word and byte operands Laurent Vivier
2016-10-26 16:36 ` [Qemu-devel] [PATCH 15/16] target-m68k: cmp manages word and bytes operands Laurent Vivier
2016-10-26 16:36 ` [Qemu-devel] [PATCH 16/16] target-m68k: immediate ops manage word and byte operands Laurent Vivier

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.