[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 2/3] m68k: add FScc instruction
From: |
Laurent Vivier |
Subject: |
[Qemu-devel] [PATCH 2/3] m68k: add FScc instruction |
Date: |
Sun, 31 May 2009 02:50:20 +0200 |
This patch allows to manage instructions like "fsge %d0".
Signed-off-by: Laurent Vivier <address@hidden>
---
target-m68k/translate.c | 82 +++++++++++++++++++++++++++++++++++++++--------
1 files changed, 68 insertions(+), 14 deletions(-)
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 223b296..8e73984 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -3259,27 +3259,15 @@ undef:
disas_undef_fpu(s, insn);
}
-DISAS_INSN(fbcc)
+static void gen_fjmpcc(DisasContext *s, int cond, int l1)
{
- uint32_t offset;
- uint32_t addr;
TCGv flag;
- int l1;
- addr = s->pc;
- offset = ldsw_code(s->pc);
- s->pc += 2;
- if (insn & (1 << 6)) {
- offset = (offset << 16) | lduw_code(s->pc);
- s->pc += 2;
- }
-
- l1 = gen_new_label();
/* TODO: Raise BSUN exception. */
flag = tcg_temp_new();
gen_helper_compare_f64(flag, cpu_env, QREG_FP_RESULT);
/* Jump to l1 if condition is true. */
- switch (insn & 0xf) {
+ switch (cond) {
case 0: /* f */
break;
case 1: /* eq (=0) */
@@ -3330,11 +3318,75 @@ DISAS_INSN(fbcc)
tcg_gen_br(l1);
break;
}
+}
+
+DISAS_INSN(fbcc)
+{
+ uint32_t offset;
+ uint32_t addr;
+ int l1;
+
+ addr = s->pc;
+ offset = ldsw_code(s->pc);
+ s->pc += 2;
+ if (insn & (1 << 6)) {
+ offset = (offset << 16) | lduw_code(s->pc);
+ s->pc += 2;
+ }
+
+ l1 = gen_new_label();
+ gen_fjmpcc(s, insn & 0xf, l1);
gen_jmp_tb(s, 0, s->pc);
gen_set_label(l1);
gen_jmp_tb(s, 1, addr + offset);
}
+DISAS_INSN(fscc_mem)
+{
+ int l1, l2;
+ TCGv taddr;
+ TCGv addr;
+ uint16_t ext;
+
+ ext = lduw_code(s->pc);
+ s->pc += 2;
+
+ taddr = gen_lea(s, insn, OS_BYTE);
+ if (IS_NULL_QREG(taddr)) {
+ gen_addr_fault(s);
+ return;
+ }
+ addr = tcg_temp_local_new ();
+ tcg_gen_mov_i32(addr, taddr);
+ l1 = gen_new_label();
+ l2 = gen_new_label();
+ gen_fjmpcc(s, ext & 0xf, l1);
+ gen_store(s, OS_BYTE, addr, tcg_const_i32(0x00));
+ tcg_gen_br(l2);
+ gen_set_label(l1);
+ gen_store(s, OS_BYTE, addr, tcg_const_i32(0xff));
+ gen_set_label(l2);
+ tcg_temp_free(addr);
+}
+
+DISAS_INSN(fscc_reg)
+{
+ int l1;
+ TCGv reg;
+ uint16_t ext;
+
+ ext = lduw_code(s->pc);
+ s->pc += 2;
+
+ reg = DREG(insn, 0);
+
+ l1 = gen_new_label();
+ tcg_gen_ori_i32(reg, reg, 0x000000ff);
+ gen_fjmpcc(s, ext & 0xf, l1);
+ tcg_gen_andi_i32(reg, reg, 0xffffff00);
+ gen_set_label(l1);
+}
+
DISAS_INSN(frestore)
{
/* TODO: Implement frestore. */
@@ -3912,6 +3964,8 @@ void register_m68k_insns (CPUM68KState *env)
INSN(frestore, f340, ffc0, CF_FPU);
INSN(fsave, f340, ffc0, CF_FPU);
INSN(fpu, f200, ffc0, FPU);
+ INSN(fscc_mem, f240, ffc0, FPU);
+ INSN(fscc_reg, f240, fff8, FPU);
INSN(fbcc, f280, ffc0, FPU);
INSN(frestore, f340, ffc0, FPU);
INSN(fsave, f340, ffc0, FPU);
--
1.5.6.5