qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Laurent Vivier <laurent@vivier.eu>
To: qemu-devel@nongnu.org
Cc: Andreas Schwab <schwab@linux-m68k.org>,
	Laurent Vivier <laurent@vivier.eu>
Subject: [Qemu-devel] [PATCH 13/17] m68k: add "byte", "word" and memory shift
Date: Sat, 30 May 2009 00:41:57 +0200	[thread overview]
Message-ID: <1243636921-23054-14-git-send-email-laurent@vivier.eu> (raw)
In-Reply-To: <1243636921-23054-13-git-send-email-laurent@vivier.eu>

This patch defines shift8_im, shift16_im, shift8_reg, shift16_reg,
shift_mem and attach them to M68000 feature.

Signed-off-by: Andreas Schwab <schwab@linux-m68k.org>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
 target-m68k/cpu.h       |    2 +
 target-m68k/helper.c    |  160 +++++++++++++++++++++++++++--------------------
 target-m68k/helpers.h   |   12 +++-
 target-m68k/translate.c |  155 +++++++++++++++++++++++++++++++++++++++++++---
 4 files changed, 249 insertions(+), 80 deletions(-)

diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h
index fa0b055..727a0b1 100644
--- a/target-m68k/cpu.h
+++ b/target-m68k/cpu.h
@@ -146,6 +146,8 @@ enum {
     CC_OP_SUBXB,  /* CC_DEST = result, CC_SRC = source */
     CC_OP_SUBXW,  /* CC_DEST = result, CC_SRC = source */
     CC_OP_SUBX,  /* CC_DEST = result, CC_SRC = source */
+    CC_OP_SHIFTB, /* CC_DEST = result, CC_SRC = carry */
+    CC_OP_SHIFTW, /* CC_DEST = result, CC_SRC = carry */
     CC_OP_SHIFT, /* CC_DEST = result, CC_SRC = carry */
 };
 
diff --git a/target-m68k/helper.c b/target-m68k/helper.c
index bcd73d5..f15902a 100644
--- a/target-m68k/helper.c
+++ b/target-m68k/helper.c
@@ -283,6 +283,12 @@ void cpu_m68k_flush_flags(CPUM68KState *env, int cc_op)
         flags |= CCF_V; \
     } while (0)
 
+#define SET_FLAGS_SHIFT(type) do { \
+    SET_NZ((type)dest); \
+    if (src) \
+        flags |= CCF_C; \
+    } while(0)
+
     flags = 0;
     src = env->cc_src;
     dest = env->cc_dest;
@@ -329,10 +335,14 @@ void cpu_m68k_flush_flags(CPUM68KState *env, int cc_op)
     case CC_OP_SUBX:
         SET_FLAGS_SUBX(int32_t, uint32_t);
         break;
+    case CC_OP_SHIFTB:
+        SET_FLAGS_SHIFT(int8_t);
+	break;
+    case CC_OP_SHIFTW:
+        SET_FLAGS_SHIFT(int16_t);
+	break;
     case CC_OP_SHIFT:
-        SET_NZ(dest);
-        if (src)
-            flags |= CCF_C;
+        SET_FLAGS_SHIFT(int32_t);
         break;
     default:
         cpu_abort(env, "Bad CC_OP %d", cc_op);
@@ -533,77 +543,89 @@ void HELPER(set_sr)(CPUState *env, uint32_t val)
     m68k_switch_sp(env);
 }
 
-uint32_t HELPER(shl_cc)(CPUState *env, uint32_t val, uint32_t shift)
-{
-    uint32_t result;
-    uint32_t cf;
-
-    shift &= 63;
-    if (shift == 0) {
-        result = val;
-        cf = env->cc_src & CCF_C;
-    } else if (shift < 32) {
-        result = val << shift;
-        cf = (val >> (32 - shift)) & 1;
-    } else if (shift == 32) {
-        result = 0;
-        cf = val & 1;
-    } else /* shift > 32 */ {
-        result = 0;
-        cf = 0;
-    }
-    env->cc_src = cf;
-    env->cc_x = (cf != 0);
-    env->cc_dest = result;
-    return result;
-}
-
-uint32_t HELPER(shr_cc)(CPUState *env, uint32_t val, uint32_t shift)
-{
-    uint32_t result;
-    uint32_t cf;
-
-    shift &= 63;
-    if (shift == 0) {
-        result = val;
-        cf = env->cc_src & CCF_C;
-    } else if (shift < 32) {
-        result = val >> shift;
-        cf = (val >> (shift - 1)) & 1;
-    } else if (shift == 32) {
-        result = 0;
-        cf = val >> 31;
-    } else /* shift > 32 */ {
-        result = 0;
-        cf = 0;
-    }
-    env->cc_src = cf;
-    env->cc_x = (cf != 0);
-    env->cc_dest = result;
-    return result;
-}
-
-uint32_t HELPER(sar_cc)(CPUState *env, uint32_t val, uint32_t shift)
-{
-    uint32_t result;
-    uint32_t cf;
-
-    shift &= 63;
-    if (shift == 0) {
-        result = val;
-        cf = (env->cc_src & CCF_C) != 0;
-    } else if (shift < 32) {
-        result = (int32_t)val >> shift;
-        cf = (val >> (shift - 1)) & 1;
-    } else /* shift >= 32 */ {
-        result = (int32_t)val >> 31;
-        cf = val >> 31;
-    }
-    env->cc_src = cf;
-    env->cc_x = cf;
-    env->cc_dest = result;
-    return result;
-}
+#define HELPER_SHL(type, bits) \
+uint32_t HELPER(glue(glue(shl, bits),_cc))(CPUState *env, uint32_t val, uint32_t shift) \
+{ \
+    type result; \
+    uint32_t cf; \
+    shift &= 63; \
+    if (shift == 0) { \
+        result = (type)val; \
+        cf = env->cc_src & CCF_C; \
+    } else if (shift < bits) { \
+        result = (type)val << shift; \
+        cf = ((type)val >> (bits - shift)) & 1; \
+    } else if (shift == bits) { \
+        result = 0; \
+        cf = val & 1; \
+    } else /* shift > bits */ { \
+        result = 0; \
+        cf = 0; \
+    } \
+    env->cc_src = cf; \
+    env->cc_x = (cf != 0); \
+    env->cc_dest = result; \
+    return result; \
+}
+
+HELPER_SHL(uint8_t, 8)
+HELPER_SHL(uint16_t, 16)
+HELPER_SHL(uint32_t, 32)
+
+#define HELPER_SHR(type, bits) \
+uint32_t HELPER(glue(glue(shr, bits), _cc))(CPUState *env, uint32_t val, uint32_t shift) \
+{ \
+    type result; \
+    uint32_t cf; \
+    shift &= 63; \
+    if (shift == 0) { \
+        result = (type)val; \
+        cf = env->cc_src & CCF_C; \
+    } else if (shift < bits) { \
+        result = (type)val >> shift; \
+        cf = ((type)val >> (shift - 1)) & 1; \
+    } else if (shift == bits) { \
+        result = 0; \
+        cf = (type)val >> (bits - 1); \
+    } else /* shift > bits */ { \
+        result = 0; \
+        cf = 0; \
+    } \
+    env->cc_src = cf; \
+    env->cc_x = (cf != 0); \
+    env->cc_dest = result; \
+    return result; \
+}
+
+HELPER_SHR(uint8_t, 8)
+HELPER_SHR(uint16_t, 16)
+HELPER_SHR(uint32_t, 32)
+
+#define HELPER_SAR(type, bits) \
+uint32_t HELPER(glue(glue(sar, bits), _cc))(CPUState *env, uint32_t val, uint32_t shift)					\
+{ \
+    type result; \
+    uint32_t cf; \
+    shift &= 63; \
+    if (shift == 0) { \
+        result = (type)val; \
+        cf = (env->cc_src & CCF_C) != 0; \
+    } else if (shift < bits) { \
+        result = (type)val >> shift; \
+        cf = (val >> (shift - 1)) & 1; \
+    } else /* shift >= bits */ { \
+        result = (type)val >> (bits - 1); \
+        cf = val >> (bits - 1); \
+    } \
+    env->cc_src = cf; \
+    env->cc_x = cf; \
+    env->cc_dest = result; \
+    return result; \
+}
+
+HELPER_SAR(int8_t, 8)
+HELPER_SAR(int16_t, 16)
+HELPER_SAR(int32_t, 32)
 
 /* FPU helpers.  */
 uint32_t HELPER(f64_to_i32)(CPUState *env, float64 val)
diff --git a/target-m68k/helpers.h b/target-m68k/helpers.h
index ca2bf82..d1993ab 100644
--- a/target-m68k/helpers.h
+++ b/target-m68k/helpers.h
@@ -13,9 +13,15 @@ DEF_HELPER_3(mulu64, i32, env, i32, i32)
 DEF_HELPER_3(muls64, i32, env, i32, 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)
+DEF_HELPER_3(shl8_cc, i32, env, i32, i32)
+DEF_HELPER_3(shl16_cc, i32, env, i32, i32)
+DEF_HELPER_3(shl32_cc, i32, env, i32, i32)
+DEF_HELPER_3(shr8_cc, i32, env, i32, i32)
+DEF_HELPER_3(shr16_cc, i32, env, i32, i32)
+DEF_HELPER_3(shr32_cc, i32, env, i32, i32)
+DEF_HELPER_3(sar8_cc, i32, env, i32, i32)
+DEF_HELPER_3(sar16_cc, i32, env, i32, i32)
+DEF_HELPER_3(sar32_cc, i32, env, i32, i32)
 DEF_HELPER_2(xflag_lt, i32, i32, i32)
 DEF_HELPER_2(set_sr, void, env, i32)
 DEF_HELPER_3(movec, void, env, i32, i32)
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index d00bde3..10b67e5 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -2013,6 +2013,63 @@ DISAS_INSN(addx)
 }
 
 /* TODO: This could be implemented without helper functions.  */
+DISAS_INSN(shift8_im)
+{
+    TCGv reg;
+    int tmp;
+    TCGv shift;
+    TCGv dest;
+
+    reg = DREG(insn, 0);
+    tmp = (insn >> 9) & 7;
+    if (tmp == 0)
+        tmp = 8;
+    shift = tcg_const_i32(tmp);
+    dest = tcg_temp_new_i32();
+    /* No need to flush flags becuse we know we will set C flag.  */
+    if (insn & 0x100) {
+        gen_helper_shl8_cc(dest, cpu_env, reg, shift);
+    } else {
+        if (insn & 8) {
+            gen_helper_shr8_cc(dest, cpu_env, reg, shift);
+        } else {
+            gen_helper_sar8_cc(dest, cpu_env, reg, shift);
+        }
+    }
+    s->cc_op = CC_OP_SHIFTB;
+    gen_partset_reg(OS_BYTE, reg, dest);
+}
+
+/* TODO: This could be implemented without helper functions.  */
+DISAS_INSN(shift16_im)
+{
+    TCGv reg;
+    int tmp;
+    TCGv shift;
+    TCGv dest;
+
+    reg = DREG(insn, 0);
+    tmp = (insn >> 9) & 7;
+    if (tmp == 0)
+        tmp = 8;
+    shift = tcg_const_i32(tmp);
+    dest = tcg_temp_new_i32();
+    /* No need to flush flags becuse we know we will set C flag.  */
+    if (insn & 0x100) {
+        gen_helper_shl16_cc(dest, cpu_env, reg, shift);
+    } else {
+        if (insn & 8) {
+            gen_helper_shr16_cc(dest, cpu_env, reg, shift);
+        } else {
+            gen_helper_sar16_cc(dest, cpu_env, reg, shift);
+        }
+    }
+    s->cc_op = CC_OP_SHIFTW;
+    gen_partset_reg(OS_WORD, reg, dest);
+}
+
+
+/* TODO: This could be implemented without helper functions.  */
 DISAS_INSN(shift_im)
 {
     TCGv reg;
@@ -2026,17 +2083,71 @@ DISAS_INSN(shift_im)
     shift = tcg_const_i32(tmp);
     /* No need to flush flags becuse we know we will set C flag.  */
     if (insn & 0x100) {
-        gen_helper_shl_cc(reg, cpu_env, reg, shift);
+        gen_helper_shl32_cc(reg, cpu_env, reg, shift);
     } else {
         if (insn & 8) {
-            gen_helper_shr_cc(reg, cpu_env, reg, shift);
+            gen_helper_shr32_cc(reg, cpu_env, reg, shift);
         } else {
-            gen_helper_sar_cc(reg, cpu_env, reg, shift);
+            gen_helper_sar32_cc(reg, cpu_env, reg, shift);
         }
     }
     s->cc_op = CC_OP_SHIFT;
 }
 
+DISAS_INSN(shift8_reg)
+{
+    TCGv reg;
+    TCGv shift;
+    TCGv dest;
+    TCGv tmp;
+
+    reg = DREG(insn, 0);
+    shift = DREG(insn, 9);
+    tmp = tcg_temp_new_i32();
+    tcg_gen_andi_i32(tmp, shift, 63);
+    dest = tcg_temp_new_i32();
+    /* Shift by zero leaves C flag unmodified.   */
+    gen_flush_flags(s);
+    if (insn & 0x100) {
+        gen_helper_shl8_cc(dest, cpu_env, reg, tmp);
+    } else {
+        if (insn & 8) {
+            gen_helper_shr8_cc(dest, cpu_env, reg, tmp);
+        } else {
+            gen_helper_sar8_cc(dest, cpu_env, reg, tmp);
+        }
+    }
+    s->cc_op = CC_OP_SHIFTB;
+    gen_partset_reg(OS_BYTE, reg, dest);
+}
+
+DISAS_INSN(shift16_reg)
+{
+    TCGv reg;
+    TCGv shift;
+    TCGv dest;
+    TCGv tmp;
+
+    reg = DREG(insn, 0);
+    shift = DREG(insn, 9);
+    tmp = tcg_temp_new_i32();
+    tcg_gen_andi_i32(tmp, shift, 63);
+    dest = tcg_temp_new_i32();
+    /* Shift by zero leaves C flag unmodified.   */
+    gen_flush_flags(s);
+    if (insn & 0x100) {
+        gen_helper_shl16_cc(dest, cpu_env, reg, tmp);
+    } else {
+        if (insn & 8) {
+            gen_helper_shr16_cc(dest, cpu_env, reg, tmp);
+        } else {
+            gen_helper_sar16_cc(dest, cpu_env, reg, tmp);
+        }
+    }
+    s->cc_op = CC_OP_SHIFTB;
+    gen_partset_reg(OS_WORD, reg, dest);
+}
+
 DISAS_INSN(shift_reg)
 {
     TCGv reg;
@@ -2047,17 +2158,40 @@ DISAS_INSN(shift_reg)
     /* Shift by zero leaves C flag unmodified.   */
     gen_flush_flags(s);
     if (insn & 0x100) {
-        gen_helper_shl_cc(reg, cpu_env, reg, shift);
+        gen_helper_shl32_cc(reg, cpu_env, reg, shift);
     } else {
         if (insn & 8) {
-            gen_helper_shr_cc(reg, cpu_env, reg, shift);
+            gen_helper_shr32_cc(reg, cpu_env, reg, shift);
         } else {
-            gen_helper_sar_cc(reg, cpu_env, reg, shift);
+            gen_helper_sar32_cc(reg, cpu_env, reg, shift);
         }
     }
     s->cc_op = CC_OP_SHIFT;
 }
 
+DISAS_INSN(shift_mem)
+{
+    TCGv src;
+    TCGv dest;
+    TCGv addr;
+    TCGv shift;
+
+    SRC_EA(src, OS_WORD, 0, &addr);
+    dest = tcg_temp_new_i32();
+    shift = tcg_const_i32(1);
+    if (insn & 0x100) {
+        gen_helper_shl16_cc(dest, cpu_env, src, shift);
+    } else {
+        if (insn & 8) {
+            gen_helper_shr16_cc(dest, cpu_env, src, shift);
+        } else {
+            gen_helper_sar16_cc(dest, cpu_env, src, shift);
+        }
+    }
+    s->cc_op = CC_OP_SHIFTW;
+    DEST_EA(insn, OS_WORD, dest, &addr);
+}
+
 DISAS_INSN(ff1)
 {
     TCGv reg;
@@ -3186,8 +3320,13 @@ void register_m68k_insns (CPUM68KState *env)
     INSN(adda,      d0c0, f0c0, M68000);
     INSN(shift_im,  e080, f0f0, CF_ISA_A);
     INSN(shift_reg, e0a0, f0f0, CF_ISA_A);
-    INSN(shift_im,    e080, f0f0, M68000);
-    INSN(shift_reg,   e0a0, f0f0, M68000);
+    INSN(shift8_im, e000, f0f0, M68000);
+    INSN(shift16_im, e040, f0f0, M68000);
+    INSN(shift_im,  e080, f0f0, M68000);
+    INSN(shift8_reg, e020, f0f0, M68000);
+    INSN(shift16_reg, e060, f0f0, M68000);
+    INSN(shift_reg, e0a0, f0f0, M68000);
+    INSN(shift_mem, e0c0, fcc0, M68000);
     INSN(undef_fpu, f000, f000, CF_ISA_A);
     INSN(undef_fpu, f000, f000, M68000);
     INSN(fpu,       f200, ffc0, CF_FPU);
-- 
1.5.6.5

  reply	other threads:[~2009-05-29 22:42 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-05-29 22:41 [Qemu-devel] [PATCH 00/17] m68k: add partial Motorola 680x0 support Laurent Vivier
2009-05-29 22:41 ` [Qemu-devel] [PATCH 01/17] m68k: Replace gen_im32() by tcg_const_i32() Laurent Vivier
2009-05-29 22:41   ` [Qemu-devel] [PATCH 02/17] m68k: add tcg_gen_debug_insn_start() Laurent Vivier
2009-05-29 22:41     ` [Qemu-devel] [PATCH 03/17] m68k: define m680x0 CPUs and features Laurent Vivier
2009-05-29 22:41       ` [Qemu-devel] [PATCH 04/17] m68k: add missing accessing modes for some instructions Laurent Vivier
2009-05-29 22:41         ` [Qemu-devel] [PATCH 05/17] m68k: add Motorola 680x0 family common instructions Laurent Vivier
2009-05-29 22:41           ` [Qemu-devel] [PATCH 06/17] m68k: add Scc instruction with memory operand Laurent Vivier
2009-05-29 22:41             ` [Qemu-devel] [PATCH 07/17] m68k: add DBcc instruction Laurent Vivier
2009-05-29 22:41               ` [Qemu-devel] [PATCH 08/17] m68k: modify movem instruction to manage word Laurent Vivier
2009-05-29 22:41                 ` [Qemu-devel] [PATCH 09/17] m68k: add 64bit divide Laurent Vivier
2009-05-29 22:41                   ` [Qemu-devel] [PATCH 10/17] m68k: add 32bit and 64bit multiply Laurent Vivier
2009-05-29 22:41                     ` [Qemu-devel] [PATCH 11/17] m68k: add word data size for suba/adda Laurent Vivier
2009-05-29 22:41                       ` [Qemu-devel] [PATCH 12/17] m68k: add fpu Laurent Vivier
2009-05-29 22:41                         ` Laurent Vivier [this message]
2009-05-29 22:41                           ` [Qemu-devel] [PATCH 14/17] m68k: add "byte", "word" and memory rotate Laurent Vivier
2009-05-29 22:41                             ` [Qemu-devel] [PATCH 15/17] m68k: add bitfield_mem, bitfield_reg Laurent Vivier
2009-05-29 22:42                               ` [Qemu-devel] [PATCH 16/17] m68k: add variable offset/width to bitfield_reg/bitfield_mem Laurent Vivier
2009-05-29 22:42                                 ` [Qemu-devel] [PATCH 17/17] m68k: add cas Laurent Vivier
2009-05-30 13:53                                   ` [Qemu-devel] " Andreas Schwab
2009-05-30 16:53                                     ` Laurent Vivier
2009-05-30 22:00               ` [Qemu-devel] Re: [PATCH 07/17] m68k: add DBcc instruction Andreas Schwab
2009-05-30 22:05                 ` Laurent Vivier
2009-05-31  2:06         ` [Qemu-devel] [PATCH 04/17] m68k: add missing accessing modes for some instructions Stuart Brady
2009-05-31  9:03           ` Laurent Vivier
2009-05-30 17:31 ` [Qemu-devel] [PATCH 00/17] m68k: add partial Motorola 680x0 support François Revol
2009-09-21  2:56 ` Rob Landley

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1243636921-23054-14-git-send-email-laurent@vivier.eu \
    --to=laurent@vivier.eu \
    --cc=qemu-devel@nongnu.org \
    --cc=schwab@linux-m68k.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).