diff mbox

Add new instruction for M68K family

Message ID 36D1AB4E1AAC4541A1C88167C7231D0B748288@G08CNEXMBPEKD02.g08.fujitsu.local
State New
Headers show

Commit Message

Guo, Lei Oct. 31, 2014, 4:28 a.m. UTC
This patch aims to add new instructions (ABCD) for M68K family.
The original TCG for M68k doesn’t include all instructions,so I intend to add the unrealized instruction or fix wrong instructions step by step.
This instruction is realized according to M68000RPM pdf.
It’s my great hornor if someone can review my new code.
Best Regards

Instruction Description:
Adds the source operand to the destination operand along with the extend bit,
and stores the result in the destination location. The addition is performed using binary-coded decimal arithmetic. The operands, which are packed binary-coded decimal
numbers, can be addressed in two different ways:
1. Data Register to Data Register: The operands are contained in the data regis-ters specified in the instruction.
2. Memory to Memory: The operands are addressed with the predecrement ad-dressing mode using the address registers specified in the instruction.

igned-off-by: Guolei <guol-fnst@cn.fujitsu.com >
---
target-m68k/helper.c    |   31 +++++++++++++++++++++++++++++++
target-m68k/helper.h    |    2 ++
target-m68k/translate.c |   27 +++++++++++++++++++++++++++
3 files changed, 60 insertions(+)

Comments

Thomas Huth Nov. 3, 2014, 2:39 p.m. UTC | #1
On Fri, 31 Oct 2014 04:28:16 +0000
"Guo, Lei" <guol-fnst@cn.fujitsu.com> wrote:

> This patch aims to add new instructions (ABCD) for M68K family.
> The original TCG for M68k doesn’t include all instructions,so I intend to add the unrealized instruction or fix wrong instructions step by step.
> This instruction is realized according to M68000RPM pdf.
> It’s my great hornor if someone can review my new code.
> Best Regards
> 
> Instruction Description:
> Adds the source operand to the destination operand along with the extend bit,
> and stores the result in the destination location. The addition is performed using binary-coded decimal arithmetic. The operands, which are packed binary-coded decimal
> numbers, can be addressed in two different ways:
> 1. Data Register to Data Register: The operands are contained in the data regis-ters specified in the instruction.
> 2. Memory to Memory: The operands are addressed with the predecrement ad-dressing mode using the address registers specified in the instruction.
> 
> igned-off-by: Guolei <guol-fnst@cn.fujitsu.com >
> ---
> target-m68k/helper.c    |   31 +++++++++++++++++++++++++++++++
> target-m68k/helper.h    |    2 ++
> target-m68k/translate.c |   27 +++++++++++++++++++++++++++
> 3 files changed, 60 insertions(+)
> 
> diff --git a/target-m68k/helper.c b/target-m68k/helper.c
> index 77225a2..e480ba4 100644
> --- a/target-m68k/helper.c
> +++ b/target-m68k/helper.c
> @@ -865,6 +865,37 @@ void HELPER(set_mac_extu)(CPUM68KState *env, uint32_t val, uint32_t acc)
>      env->macc[acc + 1] = res;
> }
> +uint32_t HELPER(abcd_cc)(CPUM68KState *env, uint32_t src, uint32_t dest)
> +{
> +    uint16_t hi, lo;
> +    uint16_t res;
> +    uint32_t flags;
> +
> +    flags = env->cc_dest;
> +    flags &= ~(CCF_C|CCF_X);
> +    lo = (src & 0x0f) + (dest & 0x0f);
> +    if (env->cc_x)
> +        lo ++;
> +    hi = (src & 0xf0) + (dest & 0xf0);
> +    res = hi + lo;
> +    if (lo > 9)
> +        res += 0x06;
> +
> +    /* C and X flags: set if decimal carry, cleared otherwise */
> +    if ((res & 0x3F0) > 0x90) {
> +        res += 0x60;
> +        flags |= CCF_C|CCF_X;
> +    }
> +
> +    /* Z flag: cleared if nonzero */
> +    if (res & 0xff)
> +        flags &= ~CCF_Z;
> +    dest = (dest & 0xffffff00) | (res & 0xff);
> +    env->cc_x = (flags & CCF_X) != 0;
> +    env->cc_dest = flags;
> +    return dest;
> +}
> +
> void m68k_cpu_exec_enter(CPUState *cs)
> {
>      M68kCPU *cpu = M68K_CPU(cs);
> diff --git a/target-m68k/helper.h b/target-m68k/helper.h
> index f4e5fdf..21d31f2 100644
> --- a/target-m68k/helper.h
> +++ b/target-m68k/helper.h
> @@ -48,3 +48,5 @@ DEF_HELPER_3(set_mac_extu, void, env, i32, i32)
>  DEF_HELPER_2(flush_flags, void, env, i32)
> DEF_HELPER_2(raise_exception, void, env, i32)
> +
> +DEF_HELPER_3(abcd_cc, i32, env, i32, i32)
> diff --git a/target-m68k/translate.c b/target-m68k/translate.c
> index efd4cfc..df18a66 100644
> --- a/target-m68k/translate.c
> +++ b/target-m68k/translate.c
> @@ -872,6 +872,33 @@ static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest)
>      s->is_jmp = DISAS_TB_JUMP;
> }
> +DISAS_INSN(abcd_reg)
> +{
> +    TCGv src;
> +    TCGv dest;
> +
> +    src = DREG(insn, 0);
> +    dest = DREG(insn, 9);
> +    gen_helper_abcd_cc(dest, cpu_env, src, dest);
> +}
> +
> +DISAS_INSN(abcd_mem)
> +{
> +    TCGv src;
> +    TCGv addr_src;
> +    TCGv dest;
> +    TCGv addr_dest;
> +
> +    addr_src = AREG(insn, 0);
> +    tcg_gen_subi_i32(addr_src, addr_src, opsize_bytes(OS_BYTE));
> +    src = gen_load(s, OS_BYTE, addr_src, 0);
> +    addr_dest = AREG(insn, 9);
> +    tcg_gen_subi_i32(addr_dest, addr_dest, opsize_bytes(OS_BYTE));
> +    dest = gen_load(s, OS_BYTE, addr_dest, 0);
> +    gen_helper_abcd_cc(dest, cpu_env, src, dest);
> +    gen_store(s, OS_BYTE, addr_dest, dest);
> +}
> +
> DISAS_INSN(undef_mac)
> {
>      gen_exception(s, s->pc - 2, EXCP_LINEA);
> --
> 1.7.9.5

Déjà-vu :

https://gitorious.org/qemu-m68k/qemu-m68k/commit/17b1b9e1d82055c70fd1d38a9a6fb60cbdc989fe

Have you been in touch with the author of that original patch already?

 Thomas
diff mbox

Patch

diff --git a/target-m68k/helper.c b/target-m68k/helper.c
index 77225a2..e480ba4 100644
--- a/target-m68k/helper.c
+++ b/target-m68k/helper.c
@@ -865,6 +865,37 @@  void HELPER(set_mac_extu)(CPUM68KState *env, uint32_t val, uint32_t acc)
     env->macc[acc + 1] = res;
}
+uint32_t HELPER(abcd_cc)(CPUM68KState *env, uint32_t src, uint32_t dest)
+{
+    uint16_t hi, lo;
+    uint16_t res;
+    uint32_t flags;
+
+    flags = env->cc_dest;
+    flags &= ~(CCF_C|CCF_X);
+    lo = (src & 0x0f) + (dest & 0x0f);
+    if (env->cc_x)
+        lo ++;
+    hi = (src & 0xf0) + (dest & 0xf0);
+    res = hi + lo;
+    if (lo > 9)
+        res += 0x06;
+
+    /* C and X flags: set if decimal carry, cleared otherwise */
+    if ((res & 0x3F0) > 0x90) {
+        res += 0x60;
+        flags |= CCF_C|CCF_X;
+    }
+
+    /* Z flag: cleared if nonzero */
+    if (res & 0xff)
+        flags &= ~CCF_Z;
+    dest = (dest & 0xffffff00) | (res & 0xff);
+    env->cc_x = (flags & CCF_X) != 0;
+    env->cc_dest = flags;
+    return dest;
+}
+
void m68k_cpu_exec_enter(CPUState *cs)
{
     M68kCPU *cpu = M68K_CPU(cs);
diff --git a/target-m68k/helper.h b/target-m68k/helper.h
index f4e5fdf..21d31f2 100644
--- a/target-m68k/helper.h
+++ b/target-m68k/helper.h
@@ -48,3 +48,5 @@  DEF_HELPER_3(set_mac_extu, void, env, i32, i32)
 DEF_HELPER_2(flush_flags, void, env, i32)
DEF_HELPER_2(raise_exception, void, env, i32)
+
+DEF_HELPER_3(abcd_cc, i32, env, i32, i32)
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index efd4cfc..df18a66 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -872,6 +872,33 @@  static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest)
     s->is_jmp = DISAS_TB_JUMP;
}
+DISAS_INSN(abcd_reg)
+{
+    TCGv src;
+    TCGv dest;
+
+    src = DREG(insn, 0);
+    dest = DREG(insn, 9);
+    gen_helper_abcd_cc(dest, cpu_env, src, dest);
+}
+
+DISAS_INSN(abcd_mem)
+{
+    TCGv src;
+    TCGv addr_src;
+    TCGv dest;
+    TCGv addr_dest;
+
+    addr_src = AREG(insn, 0);
+    tcg_gen_subi_i32(addr_src, addr_src, opsize_bytes(OS_BYTE));
+    src = gen_load(s, OS_BYTE, addr_src, 0);
+    addr_dest = AREG(insn, 9);
+    tcg_gen_subi_i32(addr_dest, addr_dest, opsize_bytes(OS_BYTE));
+    dest = gen_load(s, OS_BYTE, addr_dest, 0);
+    gen_helper_abcd_cc(dest, cpu_env, src, dest);
+    gen_store(s, OS_BYTE, addr_dest, dest);
+}
+
DISAS_INSN(undef_mac)
{
     gen_exception(s, s->pc - 2, EXCP_LINEA);
--
1.7.9.5