Message ID | 36D1AB4E1AAC4541A1C88167C7231D0B748288@G08CNEXMBPEKD02.g08.fujitsu.local |
---|---|
State | New |
Headers | show |
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 --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