* [Qemu-devel] [PATCH, RFC, WIP] TCG for Qemu target Sparc32/64
@ 2008-02-21 20:27 Blue Swirl
2008-02-22 0:06 ` Thiemo Seufer
2008-02-23 18:23 ` [Qemu-devel] " Fabrice Bellard
0 siblings, 2 replies; 8+ messages in thread
From: Blue Swirl @ 2008-02-21 20:27 UTC (permalink / raw)
To: Fabrice Bellard; +Cc: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 354 bytes --]
The attached patch enables most TCG ops for Qemu Sparc32/64 target.
Sparc32 softmmu and linux-user are OK, but Sparc64 and Sparc32plus
targets do not work.
Comments?
It would be nice to get rid of T2 usage in std (also stda and
casa/casxa) but I don't know how to pass a 64-bit value from legacy op
to TCG stores and loads on a 32-bit target and host.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: tcg_sparc_target.diff --]
[-- Type: text/x-diff; name=tcg_sparc_target.diff, Size: 36404 bytes --]
Index: qemu/target-sparc/translate.c
===================================================================
--- qemu.orig/target-sparc/translate.c 2008-02-21 20:00:28.000000000 +0000
+++ qemu/target-sparc/translate.c 2008-02-21 20:02:07.000000000 +0000
@@ -44,6 +44,81 @@
#define JUMP_PC 2 /* dynamic pc value which takes only two values
according to jump_pc[T2] */
+#ifdef TARGET_SPARC64
+#define TCG_TYPE_TL TCG_TYPE_I64
+#define tcg_gen_movi_tl tcg_gen_movi_i64
+#define tcg_gen_mov_tl tcg_gen_mov_i64
+#define tcg_gen_ld8u_tl tcg_gen_ld8u_i64
+#define tcg_gen_ld8s_tl tcg_gen_ld8s_i64
+#define tcg_gen_ld16u_tl tcg_gen_ld16u_i64
+#define tcg_gen_ld16s_tl tcg_gen_ld16s_i64
+#define tcg_gen_ld32u_tl tcg_gen_ld32u_i64
+#define tcg_gen_ld32s_tl tcg_gen_ld32s_i64
+#define tcg_gen_ld_tl tcg_gen_ld_i64
+#define tcg_gen_st8_tl tcg_gen_st8_i64
+#define tcg_gen_st16_tl tcg_gen_st16_i64
+#define tcg_gen_st32_tl tcg_gen_st32_i64
+#define tcg_gen_st_tl tcg_gen_st_i64
+#define tcg_gen_add_tl tcg_gen_add_i64
+#define tcg_gen_addi_tl tcg_gen_addi_i64
+#define tcg_gen_sub_tl tcg_gen_sub_i64
+#define tcg_gen_subi_tl tcg_gen_subi_i64
+#define tcg_gen_and_tl tcg_gen_and_i64
+#define tcg_gen_andi_tl tcg_gen_andi_i64
+#define tcg_gen_or_tl tcg_gen_or_i64
+#define tcg_gen_ori_tl tcg_gen_ori_i64
+#define tcg_gen_xor_tl tcg_gen_xor_i64
+#define tcg_gen_xori_tl tcg_gen_xori_i64
+#define tcg_gen_shl_tl tcg_gen_shl_i64
+#define tcg_gen_shli_tl tcg_gen_shli_i64
+#define tcg_gen_shr_tl tcg_gen_shr_i64
+#define tcg_gen_shri_tl tcg_gen_shri_i64
+#define tcg_gen_sar_tl tcg_gen_sar_i64
+#define tcg_gen_sari_tl tcg_gen_sari_i64
+#else
+#define TCG_TYPE_TL TCG_TYPE_I32
+#define tcg_gen_movi_tl tcg_gen_movi_i32
+#define tcg_gen_mov_tl tcg_gen_mov_i32
+#define tcg_gen_ld8u_tl tcg_gen_ld8u_i32
+#define tcg_gen_ld8s_tl tcg_gen_ld8s_i32
+#define tcg_gen_ld16u_tl tcg_gen_ld16u_i32
+#define tcg_gen_ld16s_tl tcg_gen_ld16s_i32
+#define tcg_gen_ld32u_tl tcg_gen_ld_i32
+#define tcg_gen_ld32s_tl tcg_gen_ld_i32
+#define tcg_gen_ld_tl tcg_gen_ld_i32
+#define tcg_gen_st8_tl tcg_gen_st8_i32
+#define tcg_gen_st16_tl tcg_gen_st16_i32
+#define tcg_gen_st32_tl tcg_gen_st_i32
+#define tcg_gen_st_tl tcg_gen_st_i32
+#define tcg_gen_add_tl tcg_gen_add_i32
+#define tcg_gen_addi_tl tcg_gen_addi_i32
+#define tcg_gen_sub_tl tcg_gen_sub_i32
+#define tcg_gen_subi_tl tcg_gen_subi_i32
+#define tcg_gen_and_tl tcg_gen_and_i32
+#define tcg_gen_andi_tl tcg_gen_andi_i32
+#define tcg_gen_or_tl tcg_gen_or_i32
+#define tcg_gen_ori_tl tcg_gen_ori_i32
+#define tcg_gen_xor_tl tcg_gen_xor_i32
+#define tcg_gen_xori_tl tcg_gen_xori_i32
+#define tcg_gen_shl_tl tcg_gen_shl_i32
+#define tcg_gen_shli_tl tcg_gen_shli_i32
+#define tcg_gen_shr_tl tcg_gen_shr_i32
+#define tcg_gen_shri_tl tcg_gen_shri_i32
+#define tcg_gen_sar_tl tcg_gen_sar_i32
+#define tcg_gen_sari_tl tcg_gen_sari_i32
+#endif
+
+#if TCG_TARGET_REG_BITS == 32
+#define tcg_gen_ld_ptr tcg_gen_ld_i32
+#else
+#define tcg_gen_ld_ptr tcg_gen_ld_i64
+#endif
+
+/* global register indexes */
+static TCGv cpu_env, cpu_T[3], cpu_regwptr;
+/* local register indexes (only used inside old micro ops) */
+static TCGv cpu_tmp0;
+
typedef struct DisasContext {
target_ulong pc; /* current Program Counter: integer or DYNAMIC_PC */
target_ulong npc; /* next PC: integer or DYNAMIC_PC or JUMP_PC */
@@ -102,195 +177,6 @@
static void disas_sparc_insn(DisasContext * dc);
-static GenOpFunc * const gen_op_movl_TN_reg[2][32] = {
- {
- gen_op_movl_g0_T0,
- gen_op_movl_g1_T0,
- gen_op_movl_g2_T0,
- gen_op_movl_g3_T0,
- gen_op_movl_g4_T0,
- gen_op_movl_g5_T0,
- gen_op_movl_g6_T0,
- gen_op_movl_g7_T0,
- gen_op_movl_o0_T0,
- gen_op_movl_o1_T0,
- gen_op_movl_o2_T0,
- gen_op_movl_o3_T0,
- gen_op_movl_o4_T0,
- gen_op_movl_o5_T0,
- gen_op_movl_o6_T0,
- gen_op_movl_o7_T0,
- gen_op_movl_l0_T0,
- gen_op_movl_l1_T0,
- gen_op_movl_l2_T0,
- gen_op_movl_l3_T0,
- gen_op_movl_l4_T0,
- gen_op_movl_l5_T0,
- gen_op_movl_l6_T0,
- gen_op_movl_l7_T0,
- gen_op_movl_i0_T0,
- gen_op_movl_i1_T0,
- gen_op_movl_i2_T0,
- gen_op_movl_i3_T0,
- gen_op_movl_i4_T0,
- gen_op_movl_i5_T0,
- gen_op_movl_i6_T0,
- gen_op_movl_i7_T0,
- },
- {
- gen_op_movl_g0_T1,
- gen_op_movl_g1_T1,
- gen_op_movl_g2_T1,
- gen_op_movl_g3_T1,
- gen_op_movl_g4_T1,
- gen_op_movl_g5_T1,
- gen_op_movl_g6_T1,
- gen_op_movl_g7_T1,
- gen_op_movl_o0_T1,
- gen_op_movl_o1_T1,
- gen_op_movl_o2_T1,
- gen_op_movl_o3_T1,
- gen_op_movl_o4_T1,
- gen_op_movl_o5_T1,
- gen_op_movl_o6_T1,
- gen_op_movl_o7_T1,
- gen_op_movl_l0_T1,
- gen_op_movl_l1_T1,
- gen_op_movl_l2_T1,
- gen_op_movl_l3_T1,
- gen_op_movl_l4_T1,
- gen_op_movl_l5_T1,
- gen_op_movl_l6_T1,
- gen_op_movl_l7_T1,
- gen_op_movl_i0_T1,
- gen_op_movl_i1_T1,
- gen_op_movl_i2_T1,
- gen_op_movl_i3_T1,
- gen_op_movl_i4_T1,
- gen_op_movl_i5_T1,
- gen_op_movl_i6_T1,
- gen_op_movl_i7_T1,
- }
-};
-
-static GenOpFunc * const gen_op_movl_reg_TN[3][32] = {
- {
- gen_op_movl_T0_g0,
- gen_op_movl_T0_g1,
- gen_op_movl_T0_g2,
- gen_op_movl_T0_g3,
- gen_op_movl_T0_g4,
- gen_op_movl_T0_g5,
- gen_op_movl_T0_g6,
- gen_op_movl_T0_g7,
- gen_op_movl_T0_o0,
- gen_op_movl_T0_o1,
- gen_op_movl_T0_o2,
- gen_op_movl_T0_o3,
- gen_op_movl_T0_o4,
- gen_op_movl_T0_o5,
- gen_op_movl_T0_o6,
- gen_op_movl_T0_o7,
- gen_op_movl_T0_l0,
- gen_op_movl_T0_l1,
- gen_op_movl_T0_l2,
- gen_op_movl_T0_l3,
- gen_op_movl_T0_l4,
- gen_op_movl_T0_l5,
- gen_op_movl_T0_l6,
- gen_op_movl_T0_l7,
- gen_op_movl_T0_i0,
- gen_op_movl_T0_i1,
- gen_op_movl_T0_i2,
- gen_op_movl_T0_i3,
- gen_op_movl_T0_i4,
- gen_op_movl_T0_i5,
- gen_op_movl_T0_i6,
- gen_op_movl_T0_i7,
- },
- {
- gen_op_movl_T1_g0,
- gen_op_movl_T1_g1,
- gen_op_movl_T1_g2,
- gen_op_movl_T1_g3,
- gen_op_movl_T1_g4,
- gen_op_movl_T1_g5,
- gen_op_movl_T1_g6,
- gen_op_movl_T1_g7,
- gen_op_movl_T1_o0,
- gen_op_movl_T1_o1,
- gen_op_movl_T1_o2,
- gen_op_movl_T1_o3,
- gen_op_movl_T1_o4,
- gen_op_movl_T1_o5,
- gen_op_movl_T1_o6,
- gen_op_movl_T1_o7,
- gen_op_movl_T1_l0,
- gen_op_movl_T1_l1,
- gen_op_movl_T1_l2,
- gen_op_movl_T1_l3,
- gen_op_movl_T1_l4,
- gen_op_movl_T1_l5,
- gen_op_movl_T1_l6,
- gen_op_movl_T1_l7,
- gen_op_movl_T1_i0,
- gen_op_movl_T1_i1,
- gen_op_movl_T1_i2,
- gen_op_movl_T1_i3,
- gen_op_movl_T1_i4,
- gen_op_movl_T1_i5,
- gen_op_movl_T1_i6,
- gen_op_movl_T1_i7,
- },
- {
- gen_op_movl_T2_g0,
- gen_op_movl_T2_g1,
- gen_op_movl_T2_g2,
- gen_op_movl_T2_g3,
- gen_op_movl_T2_g4,
- gen_op_movl_T2_g5,
- gen_op_movl_T2_g6,
- gen_op_movl_T2_g7,
- gen_op_movl_T2_o0,
- gen_op_movl_T2_o1,
- gen_op_movl_T2_o2,
- gen_op_movl_T2_o3,
- gen_op_movl_T2_o4,
- gen_op_movl_T2_o5,
- gen_op_movl_T2_o6,
- gen_op_movl_T2_o7,
- gen_op_movl_T2_l0,
- gen_op_movl_T2_l1,
- gen_op_movl_T2_l2,
- gen_op_movl_T2_l3,
- gen_op_movl_T2_l4,
- gen_op_movl_T2_l5,
- gen_op_movl_T2_l6,
- gen_op_movl_T2_l7,
- gen_op_movl_T2_i0,
- gen_op_movl_T2_i1,
- gen_op_movl_T2_i2,
- gen_op_movl_T2_i3,
- gen_op_movl_T2_i4,
- gen_op_movl_T2_i5,
- gen_op_movl_T2_i6,
- gen_op_movl_T2_i7,
- }
-};
-
-static GenOpFunc1 * const gen_op_movl_TN_im[3] = {
- gen_op_movl_T0_im,
- gen_op_movl_T1_im,
- gen_op_movl_T2_im
-};
-
-// Sign extending version
-static GenOpFunc1 * const gen_op_movl_TN_sim[3] = {
- gen_op_movl_T0_sim,
- gen_op_movl_T1_sim,
- gen_op_movl_T2_sim
-};
-
#ifdef TARGET_SPARC64
#define GEN32(func, NAME) \
static GenOpFunc * const NAME ## _table [64] = { \
@@ -375,29 +261,18 @@
#endif
#ifndef CONFIG_USER_ONLY
-OP_LD_TABLE(ld);
-OP_LD_TABLE(st);
-OP_LD_TABLE(ldub);
-OP_LD_TABLE(lduh);
-OP_LD_TABLE(ldsb);
-OP_LD_TABLE(ldsh);
-OP_LD_TABLE(stb);
-OP_LD_TABLE(sth);
OP_LD_TABLE(std);
-OP_LD_TABLE(ldstub);
-OP_LD_TABLE(swap);
OP_LD_TABLE(ldd);
OP_LD_TABLE(stf);
OP_LD_TABLE(stdf);
OP_LD_TABLE(ldf);
OP_LD_TABLE(lddf);
-
-#ifdef TARGET_SPARC64
-OP_LD_TABLE(lduw);
-OP_LD_TABLE(ldsw);
-OP_LD_TABLE(ldx);
-OP_LD_TABLE(stx);
#endif
+
+#ifdef TARGET_ABI32
+#define ABI32_MASK() tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffff);
+#else
+#define ABI32_MASK()
#endif
/* asi moves */
@@ -583,99 +458,105 @@
}
#endif
-static inline void gen_movl_imm_TN(int reg, uint32_t imm)
+static inline void gen_movl_simm_T1(int32_t val)
{
- gen_op_movl_TN_im[reg](imm);
+ tcg_gen_movi_tl(cpu_T[1], val);
}
-static inline void gen_movl_imm_T1(uint32_t val)
+static inline void gen_movl_reg_TN(int reg, int t)
{
- gen_movl_imm_TN(1, val);
+ if (reg == 0)
+ tcg_gen_movi_tl(cpu_T[t], 0);
+ else if (reg < 8)
+ tcg_gen_ld_tl(cpu_T[t], cpu_env, offsetof(CPUState, gregs[reg]));
+ else {
+ tcg_gen_ld_ptr(cpu_regwptr, cpu_env, offsetof(CPUState, regwptr)); // XXX
+ tcg_gen_ld_tl(cpu_T[t], cpu_regwptr, (reg - 8) * sizeof(target_ulong));
+ }
}
-static inline void gen_movl_imm_T0(uint32_t val)
+static inline void gen_movl_reg_T0(int reg)
{
- gen_movl_imm_TN(0, val);
+ gen_movl_reg_TN(reg, 0);
}
-static inline void gen_movl_simm_TN(int reg, int32_t imm)
+static inline void gen_movl_reg_T1(int reg)
{
- gen_op_movl_TN_sim[reg](imm);
+ gen_movl_reg_TN(reg, 1);
}
-static inline void gen_movl_simm_T1(int32_t val)
+static inline void gen_movl_reg_T2(int reg)
{
- gen_movl_simm_TN(1, val);
+ gen_movl_reg_TN(reg, 2);
}
-static inline void gen_movl_simm_T0(int32_t val)
+static inline void gen_movl_TN_reg(int reg, int t)
{
- gen_movl_simm_TN(0, val);
+ if (reg == 0)
+ return;
+ else if (reg < 8)
+ tcg_gen_st_tl(cpu_T[t], cpu_env, offsetof(CPUState, gregs[reg]));
+ else {
+ tcg_gen_ld_ptr(cpu_regwptr, cpu_env, offsetof(CPUState, regwptr)); // XXX
+ tcg_gen_st_tl(cpu_T[t], cpu_regwptr, (reg - 8) * sizeof(target_ulong));
+ }
}
-static inline void gen_movl_reg_TN(int reg, int t)
+static inline void gen_movl_T0_reg(int reg)
{
- if (reg)
- gen_op_movl_reg_TN[t][reg] ();
- else
- gen_movl_imm_TN(t, 0);
+ gen_movl_TN_reg(reg, 0);
}
-static inline void gen_movl_reg_T0(int reg)
+static inline void gen_movl_T1_reg(int reg)
{
- gen_movl_reg_TN(reg, 0);
+ gen_movl_TN_reg(reg, 1);
}
-static inline void gen_movl_reg_T1(int reg)
+static inline void gen_op_movl_T0_env(size_t offset)
{
- gen_movl_reg_TN(reg, 1);
+ tcg_gen_ld_i32(cpu_T[0], cpu_env, offset);
}
-static inline void gen_movl_reg_T2(int reg)
+static inline void gen_op_movl_env_T0(size_t offset)
{
- gen_movl_reg_TN(reg, 2);
+ tcg_gen_st_i32(cpu_T[0], cpu_env, offset);
}
-static inline void gen_movl_TN_reg(int reg, int t)
+static inline void gen_op_movtl_T0_env(size_t offset)
{
- if (reg)
- gen_op_movl_TN_reg[t][reg] ();
+ tcg_gen_ld_tl(cpu_T[0], cpu_env, offset);
}
-static inline void gen_movl_T0_reg(int reg)
+static inline void gen_op_movtl_env_T0(size_t offset)
{
- gen_movl_TN_reg(reg, 0);
+ tcg_gen_st_tl(cpu_T[0], cpu_env, offset);
}
-static inline void gen_movl_T1_reg(int reg)
+static inline void gen_op_add_T1_T0(void)
{
- gen_movl_TN_reg(reg, 1);
+ tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
+}
+
+static inline void gen_op_or_T1_T0(void)
+{
+ tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
+}
+
+static inline void gen_op_xor_T1_T0(void)
+{
+ tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
}
static inline void gen_jmp_im(target_ulong pc)
{
-#ifdef TARGET_SPARC64
- if (pc == (uint32_t)pc) {
- gen_op_jmp_im(pc);
- } else {
- gen_op_jmp_im64(pc >> 32, pc);
- }
-#else
- gen_op_jmp_im(pc);
-#endif
+ tcg_gen_movi_tl(cpu_tmp0, pc);
+ tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, pc));
}
static inline void gen_movl_npc_im(target_ulong npc)
{
-#ifdef TARGET_SPARC64
- if (npc == (uint32_t)npc) {
- gen_op_movl_npc_im(npc);
- } else {
- gen_op_movq_npc_im64(npc >> 32, npc);
- }
-#else
- gen_op_movl_npc_im(npc);
-#endif
+ tcg_gen_movi_tl(cpu_tmp0, npc);
+ tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, npc));
}
static inline void gen_goto_tb(DisasContext *s, int tb_num,
@@ -1179,7 +1060,7 @@
if (rd) { // nop
#endif
uint32_t value = GET_FIELD(insn, 10, 31);
- gen_movl_imm_T0(value << 10);
+ tcg_gen_movi_tl(cpu_T[0], value << 10);
gen_movl_T0_reg(rd);
#if defined(OPTIM)
}
@@ -1196,15 +1077,7 @@
/*CALL*/ {
target_long target = GET_FIELDs(insn, 2, 31) << 2;
-#ifdef TARGET_SPARC64
- if (dc->pc == (uint32_t)dc->pc) {
- gen_op_movl_T0_im(dc->pc);
- } else {
- gen_op_movq_T0_im64(dc->pc >> 32, dc->pc);
- }
-#else
- gen_op_movl_T0_im(dc->pc);
-#endif
+ tcg_gen_movi_tl(cpu_T[0], dc->pc);
gen_movl_T0_reg(15);
target += dc->pc;
gen_mov_pc_npc(dc);
@@ -1221,14 +1094,7 @@
gen_movl_reg_T0(rs1);
if (IS_IMM) {
rs2 = GET_FIELD(insn, 25, 31);
-#if defined(OPTIM)
- if (rs2 != 0) {
-#endif
- gen_movl_simm_T1(rs2);
- gen_op_add_T1_T0();
-#if defined(OPTIM)
- }
-#endif
+ tcg_gen_addi_tl(cpu_T[0], cpu_T[0], rs2);
} else {
rs2 = GET_FIELD(insn, 27, 31);
#if defined(OPTIM)
@@ -1298,11 +1164,7 @@
gen_movl_T0_reg(rd);
break;
case 0x5: /* V9 rdpc */
- if (dc->pc == (uint32_t)dc->pc) {
- gen_op_movl_T0_im(dc->pc);
- } else {
- gen_op_movq_T0_im64(dc->pc >> 32, dc->pc);
- }
+ tcg_gen_movi_tl(cpu_T[0], dc->pc);
gen_movl_T0_reg(rd);
break;
case 0x6: /* V9 rdfprs */
@@ -2078,24 +1940,19 @@
rs1 = GET_FIELD(insn, 13, 17);
if (rs1 == 0) {
- // or %g0, x, y -> mov T1, x; mov y, T1
+ // or %g0, x, y -> mov T0, x; mov y, T0
if (IS_IMM) { /* immediate */
rs2 = GET_FIELDs(insn, 19, 31);
- gen_movl_simm_T1(rs2);
+ tcg_gen_movi_tl(cpu_T[0], rs2);
} else { /* register */
rs2 = GET_FIELD(insn, 27, 31);
- gen_movl_reg_T1(rs2);
+ gen_movl_reg_T0(rs2);
}
- gen_movl_T1_reg(rd);
} else {
gen_movl_reg_T0(rs1);
if (IS_IMM) { /* immediate */
- // or x, #0, y -> mov T1, x; mov y, T1
rs2 = GET_FIELDs(insn, 19, 31);
- if (rs2 != 0) {
- gen_movl_simm_T1(rs2);
- gen_op_or_T1_T0();
- }
+ tcg_gen_ori_tl(cpu_T[0], cpu_T[0], rs2);
} else { /* register */
// or x, %g0, y -> mov T1, x; mov y, T1
rs2 = GET_FIELD(insn, 27, 31);
@@ -2104,8 +1961,8 @@
gen_op_or_T1_T0();
}
}
- gen_movl_T0_reg(rd);
}
+ gen_movl_T0_reg(rd);
#endif
#ifdef TARGET_SPARC64
} else if (xop == 0x25) { /* sll, V9 sllx */
@@ -2173,17 +2030,17 @@
gen_op_add_T1_T0();
break;
case 0x1:
- gen_op_and_T1_T0();
+ tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
if (xop & 0x10)
gen_op_logic_T0_cc();
break;
case 0x2:
- gen_op_or_T1_T0();
+ tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
if (xop & 0x10)
gen_op_logic_T0_cc();
break;
case 0x3:
- gen_op_xor_T1_T0();
+ tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
if (xop & 0x10)
gen_op_logic_T0_cc();
break;
@@ -2191,7 +2048,7 @@
if (xop & 0x10)
gen_op_sub_T1_T0_cc();
else
- gen_op_sub_T1_T0();
+ tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
break;
case 0x5:
gen_op_andn_T1_T0();
@@ -2216,7 +2073,7 @@
break;
#ifdef TARGET_SPARC64
case 0x9: /* V9 mulx */
- gen_op_mulx_T1_T0();
+ tcg_gen_mul_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
break;
#endif
case 0xa:
@@ -3003,14 +2860,7 @@
gen_movl_reg_T0(rs1);
if (IS_IMM) { /* immediate */
rs2 = GET_FIELDs(insn, 19, 31);
-#if defined(OPTIM)
- if (rs2) {
-#endif
- gen_movl_simm_T1(rs2);
- gen_op_add_T1_T0();
-#if defined(OPTIM)
- }
-#endif
+ tcg_gen_addi_tl(cpu_T[0], cpu_T[0], rs2);
} else { /* register */
rs2 = GET_FIELD(insn, 27, 31);
#if defined(OPTIM)
@@ -3034,14 +2884,7 @@
gen_movl_reg_T0(rs1);
if (IS_IMM) { /* immediate */
rs2 = GET_FIELDs(insn, 19, 31);
-#if defined(OPTIM)
- if (rs2) {
-#endif
- gen_movl_simm_T1(rs2);
- gen_op_add_T1_T0();
-#if defined(OPTIM)
- }
-#endif
+ tcg_gen_addi_tl(cpu_T[0], cpu_T[0], rs2);
} else { /* register */
rs2 = GET_FIELD(insn, 27, 31);
#if defined(OPTIM)
@@ -3057,15 +2900,7 @@
case 0x38: /* jmpl */
{
if (rd != 0) {
-#ifdef TARGET_SPARC64
- if (dc->pc == (uint32_t)dc->pc) {
- gen_op_movl_T1_im(dc->pc);
- } else {
- gen_op_movq_T1_im64(dc->pc >> 32, dc->pc);
- }
-#else
- gen_op_movl_T1_im(dc->pc);
-#endif
+ tcg_gen_movi_tl(cpu_T[1], dc->pc);
gen_movl_T1_reg(rd);
}
gen_mov_pc_npc(dc);
@@ -3144,14 +2979,7 @@
}
else if (IS_IMM) { /* immediate */
rs2 = GET_FIELDs(insn, 19, 31);
-#if defined(OPTIM)
- if (rs2 != 0) {
-#endif
- gen_movl_simm_T1(rs2);
- gen_op_add_T1_T0();
-#if defined(OPTIM)
- }
-#endif
+ tcg_gen_addi_tl(cpu_T[0], cpu_T[0], rs2);
} else { /* register */
rs2 = GET_FIELD(insn, 27, 31);
#if defined(OPTIM)
@@ -3167,20 +2995,19 @@
(xop > 0x17 && xop <= 0x1d ) ||
(xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) {
switch (xop) {
- case 0x0: /* load word */
+ case 0x0: /* load unsigned word */
gen_op_check_align_T0_3();
-#ifndef TARGET_SPARC64
- gen_op_ldst(ld);
-#else
- gen_op_ldst(lduw);
-#endif
+ ABI32_MASK();
+ tcg_gen_qemu_ld32u(cpu_T[1], cpu_T[0], dc->mem_idx);
break;
case 0x1: /* load unsigned byte */
- gen_op_ldst(ldub);
+ ABI32_MASK();
+ tcg_gen_qemu_ld8u(cpu_T[1], cpu_T[0], dc->mem_idx);
break;
case 0x2: /* load unsigned halfword */
gen_op_check_align_T0_1();
- gen_op_ldst(lduh);
+ ABI32_MASK();
+ tcg_gen_qemu_ld16u(cpu_T[1], cpu_T[0], dc->mem_idx);
break;
case 0x3: /* load double word */
if (rd & 1)
@@ -3190,19 +3017,27 @@
gen_movl_T0_reg(rd + 1);
break;
case 0x9: /* load signed byte */
- gen_op_ldst(ldsb);
+ ABI32_MASK();
+ tcg_gen_qemu_ld8s(cpu_T[1], cpu_T[0], dc->mem_idx);
break;
case 0xa: /* load signed halfword */
gen_op_check_align_T0_1();
- gen_op_ldst(ldsh);
+ ABI32_MASK();
+ tcg_gen_qemu_ld16s(cpu_T[1], cpu_T[0], dc->mem_idx);
break;
case 0xd: /* ldstub -- XXX: should be atomically */
- gen_op_ldst(ldstub);
+ tcg_gen_movi_i32(cpu_tmp0, 0xff);
+ ABI32_MASK();
+ tcg_gen_qemu_ld8s(cpu_T[1], cpu_T[0], dc->mem_idx);
+ tcg_gen_qemu_st8(cpu_tmp0, cpu_T[0], dc->mem_idx);
break;
case 0x0f: /* swap register with memory. Also atomically */
gen_op_check_align_T0_3();
gen_movl_reg_T1(rd);
- gen_op_ldst(swap);
+ ABI32_MASK();
+ tcg_gen_qemu_ld32u(cpu_tmp0, cpu_T[0], dc->mem_idx);
+ tcg_gen_qemu_st32(cpu_T[1], cpu_T[0], dc->mem_idx);
+ tcg_gen_mov_i32(cpu_T[1], cpu_tmp0);
break;
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
case 0x10: /* load word alternate */
@@ -3297,11 +3132,13 @@
#ifdef TARGET_SPARC64
case 0x08: /* V9 ldsw */
gen_op_check_align_T0_3();
- gen_op_ldst(ldsw);
+ ABI32_MASK();
+ tcg_gen_qemu_ld32s(cpu_T[1], cpu_T[0], dc->mem_idx);
break;
case 0x0b: /* V9 ldx */
gen_op_check_align_T0_7();
- gen_op_ldst(ldx);
+ ABI32_MASK();
+ tcg_gen_qemu_ld64(cpu_T[1], cpu_T[0], dc->mem_idx);
break;
case 0x18: /* V9 ldswa */
gen_op_check_align_T0_3();
@@ -3374,16 +3211,19 @@
xop == 0xe || xop == 0x1e) {
gen_movl_reg_T1(rd);
switch (xop) {
- case 0x4:
+ case 0x4: /* store word */
gen_op_check_align_T0_3();
- gen_op_ldst(st);
+ ABI32_MASK();
+ tcg_gen_qemu_st32(cpu_T[1], cpu_T[0], dc->mem_idx);
break;
- case 0x5:
- gen_op_ldst(stb);
+ case 0x5: /* store byte */
+ ABI32_MASK();
+ tcg_gen_qemu_st8(cpu_T[1], cpu_T[0], dc->mem_idx);
break;
- case 0x6:
+ case 0x6: /* store halfword */
gen_op_check_align_T0_1();
- gen_op_ldst(sth);
+ ABI32_MASK();
+ tcg_gen_qemu_st16(cpu_T[1], cpu_T[0], dc->mem_idx);
break;
case 0x7:
if (rd & 1)
@@ -3441,7 +3281,8 @@
#ifdef TARGET_SPARC64
case 0x0e: /* V9 stx */
gen_op_check_align_T0_7();
- gen_op_ldst(stx);
+ ABI32_MASK();
+ tcg_gen_qemu_st64(cpu_T[1], cpu_T[0], dc->mem_idx);
break;
case 0x1e: /* V9 stxa */
gen_op_check_align_T0_7();
@@ -3597,6 +3438,10 @@
#endif
}
+static void tcg_macro_func(TCGContext *s, int macro_id, const int *dead_args)
+{
+}
+
static inline int gen_intermediate_code_internal(TranslationBlock * tb,
int spc, CPUSPARCState *env)
{
@@ -3615,6 +3460,9 @@
dc->fpu_enabled = cpu_fpu_enabled(env);
gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
+ cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
+ cpu_regwptr = tcg_temp_new(TCG_TYPE_PTR); // XXX
+
do {
if (env->nb_breakpoints > 0) {
for(j = 0; j < env->nb_breakpoints; j++) {
@@ -3748,6 +3596,7 @@
{
CPUSPARCState *env;
const sparc_def_t *def;
+ static int inited;
def = cpu_sparc_find_by_name(cpu_model);
if (!def)
@@ -3769,6 +3618,27 @@
env->mmuregs[0] |= def->mmu_version;
cpu_sparc_set_id(env, 0);
#endif
+
+ /* init various static tables */
+ if (!inited) {
+ inited = 1;
+
+ tcg_set_macro_func(&tcg_ctx, tcg_macro_func);
+ cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
+#if TARGET_LONG_BITS > HOST_LONG_BITS
+ cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
+ TCG_AREG0, offsetof(CPUState, t0), "T0");
+ cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
+ TCG_AREG0, offsetof(CPUState, t1), "T1");
+ cpu_T[2] = tcg_global_mem_new(TCG_TYPE_TL,
+ TCG_AREG0, offsetof(CPUState, t2), "T2");
+#else
+ cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
+ cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
+ cpu_T[2] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "T2");
+#endif
+ }
+
cpu_reset(env);
return env;
Index: qemu/target-sparc/op.c
===================================================================
--- qemu.orig/target-sparc/op.c 2008-02-21 20:00:28.000000000 +0000
+++ qemu/target-sparc/op.c 2008-02-21 20:02:07.000000000 +0000
@@ -20,104 +20,6 @@
#include "exec.h"
- /*XXX*/
-#define REGNAME g0
-#define REG (env->gregs[0])
-#include "op_template.h"
-#define REGNAME g1
-#define REG (env->gregs[1])
-#include "op_template.h"
-#define REGNAME g2
-#define REG (env->gregs[2])
-#include "op_template.h"
-#define REGNAME g3
-#define REG (env->gregs[3])
-#include "op_template.h"
-#define REGNAME g4
-#define REG (env->gregs[4])
-#include "op_template.h"
-#define REGNAME g5
-#define REG (env->gregs[5])
-#include "op_template.h"
-#define REGNAME g6
-#define REG (env->gregs[6])
-#include "op_template.h"
-#define REGNAME g7
-#define REG (env->gregs[7])
-#include "op_template.h"
-#define REGNAME i0
-#define REG (REGWPTR[16])
-#include "op_template.h"
-#define REGNAME i1
-#define REG (REGWPTR[17])
-#include "op_template.h"
-#define REGNAME i2
-#define REG (REGWPTR[18])
-#include "op_template.h"
-#define REGNAME i3
-#define REG (REGWPTR[19])
-#include "op_template.h"
-#define REGNAME i4
-#define REG (REGWPTR[20])
-#include "op_template.h"
-#define REGNAME i5
-#define REG (REGWPTR[21])
-#include "op_template.h"
-#define REGNAME i6
-#define REG (REGWPTR[22])
-#include "op_template.h"
-#define REGNAME i7
-#define REG (REGWPTR[23])
-#include "op_template.h"
-#define REGNAME l0
-#define REG (REGWPTR[8])
-#include "op_template.h"
-#define REGNAME l1
-#define REG (REGWPTR[9])
-#include "op_template.h"
-#define REGNAME l2
-#define REG (REGWPTR[10])
-#include "op_template.h"
-#define REGNAME l3
-#define REG (REGWPTR[11])
-#include "op_template.h"
-#define REGNAME l4
-#define REG (REGWPTR[12])
-#include "op_template.h"
-#define REGNAME l5
-#define REG (REGWPTR[13])
-#include "op_template.h"
-#define REGNAME l6
-#define REG (REGWPTR[14])
-#include "op_template.h"
-#define REGNAME l7
-#define REG (REGWPTR[15])
-#include "op_template.h"
-#define REGNAME o0
-#define REG (REGWPTR[0])
-#include "op_template.h"
-#define REGNAME o1
-#define REG (REGWPTR[1])
-#include "op_template.h"
-#define REGNAME o2
-#define REG (REGWPTR[2])
-#include "op_template.h"
-#define REGNAME o3
-#define REG (REGWPTR[3])
-#include "op_template.h"
-#define REGNAME o4
-#define REG (REGWPTR[4])
-#include "op_template.h"
-#define REGNAME o5
-#define REG (REGWPTR[5])
-#include "op_template.h"
-#define REGNAME o6
-#define REG (REGWPTR[6])
-#include "op_template.h"
-#define REGNAME o7
-#define REG (REGWPTR[7])
-#include "op_template.h"
-
#define REGNAME f0
#define REG (env->fpr[0])
#include "fop_template.h"
@@ -267,106 +169,11 @@
#endif
#ifdef TARGET_SPARC64
-#ifdef WORDS_BIGENDIAN
-typedef union UREG64 {
- struct { uint16_t v3, v2, v1, v0; } w;
- struct { uint32_t v1, v0; } l;
- uint64_t q;
-} UREG64;
-#else
-typedef union UREG64 {
- struct { uint16_t v0, v1, v2, v3; } w;
- struct { uint32_t v0, v1; } l;
- uint64_t q;
-} UREG64;
-#endif
-
-#define PARAMQ1 \
-({\
- UREG64 __p;\
- __p.l.v1 = PARAM1;\
- __p.l.v0 = PARAM2;\
- __p.q;\
-})
-
-void OPPROTO op_movq_T0_im64(void)
-{
- T0 = PARAMQ1;
-}
-
-void OPPROTO op_movq_T1_im64(void)
-{
- T1 = PARAMQ1;
-}
-
#define XFLAG_SET(x) ((env->xcc&x)?1:0)
-
-#else
-#define EIP (env->pc)
#endif
#define FLAG_SET(x) ((env->psr&x)?1:0)
-void OPPROTO op_movl_T0_0(void)
-{
- T0 = 0;
-}
-
-void OPPROTO op_movl_T0_im(void)
-{
- T0 = (uint32_t)PARAM1;
-}
-
-void OPPROTO op_movl_T1_im(void)
-{
- T1 = (uint32_t)PARAM1;
-}
-
-void OPPROTO op_movl_T2_im(void)
-{
- T2 = (uint32_t)PARAM1;
-}
-
-void OPPROTO op_movl_T0_sim(void)
-{
- T0 = (int32_t)PARAM1;
-}
-
-void OPPROTO op_movl_T1_sim(void)
-{
- T1 = (int32_t)PARAM1;
-}
-
-void OPPROTO op_movl_T2_sim(void)
-{
- T2 = (int32_t)PARAM1;
-}
-
-void OPPROTO op_movl_T0_env(void)
-{
- T0 = *(uint32_t *)((char *)env + PARAM1);
-}
-
-void OPPROTO op_movl_env_T0(void)
-{
- *(uint32_t *)((char *)env + PARAM1) = T0;
-}
-
-void OPPROTO op_movtl_T0_env(void)
-{
- T0 = *(target_ulong *)((char *)env + PARAM1);
-}
-
-void OPPROTO op_movtl_env_T0(void)
-{
- *(target_ulong *)((char *)env + PARAM1) = T0;
-}
-
-void OPPROTO op_add_T1_T0(void)
-{
- T0 += T1;
-}
-
void OPPROTO op_add_T1_T0_cc(void)
{
target_ulong src1;
@@ -565,11 +372,6 @@
FORCE_RET();
}
-void OPPROTO op_sub_T1_T0(void)
-{
- T0 -= T1;
-}
-
void OPPROTO op_sub_T1_T0_cc(void)
{
target_ulong src1;
@@ -765,21 +567,6 @@
FORCE_RET();
}
-void OPPROTO op_and_T1_T0(void)
-{
- T0 &= T1;
-}
-
-void OPPROTO op_or_T1_T0(void)
-{
- T0 |= T1;
-}
-
-void OPPROTO op_xor_T1_T0(void)
-{
- T0 ^= T1;
-}
-
void OPPROTO op_andn_T1_T0(void)
{
T0 &= ~T1;
@@ -921,12 +708,6 @@
}
#ifdef TARGET_SPARC64
-void OPPROTO op_mulx_T1_T0(void)
-{
- T0 *= T1;
- FORCE_RET();
-}
-
void OPPROTO op_udivx_T1_T0(void)
{
if (T1 == 0) {
@@ -1499,28 +1280,8 @@
{
T2 = ((int64_t)T0 >= 0);
}
-
-void OPPROTO op_jmp_im64(void)
-{
- env->pc = PARAMQ1;
-}
-
-void OPPROTO op_movq_npc_im64(void)
-{
- env->npc = PARAMQ1;
-}
#endif
-void OPPROTO op_jmp_im(void)
-{
- env->pc = (uint32_t)PARAM1;
-}
-
-void OPPROTO op_movl_npc_im(void)
-{
- env->npc = (uint32_t)PARAM1;
-}
-
void OPPROTO op_movl_npc_T0(void)
{
env->npc = T0;
Index: qemu/target-sparc/op_template.h
===================================================================
--- qemu.orig/target-sparc/op_template.h 2008-02-21 20:00:28.000000000 +0000
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,48 +0,0 @@
-/*
- * SPARC micro operations (templates for various register related
- * operations)
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-void OPPROTO glue(op_movl_T0_, REGNAME)(void)
-{
- T0 = REG;
-}
-
-void OPPROTO glue(op_movl_T1_, REGNAME)(void)
-{
- T1 = REG;
-}
-
-void OPPROTO glue(op_movl_T2_, REGNAME)(void)
-{
- T2 = REG;
-}
-
-void OPPROTO glue(glue(op_movl_, REGNAME), _T0)(void)
-{
- REG = T0;
-}
-
-void OPPROTO glue(glue(op_movl_, REGNAME), _T1)(void)
-{
- REG = T1;
-}
-
-#undef REG
-#undef REGNAME
Index: qemu/target-sparc/op_mem.h
===================================================================
--- qemu.orig/target-sparc/op_mem.h 2008-02-21 20:00:28.000000000 +0000
+++ qemu/target-sparc/op_mem.h 2008-02-21 20:02:07.000000000 +0000
@@ -4,36 +4,6 @@
#define ADDR(x) (x)
#endif
-/*** Integer load ***/
-#define SPARC_LD_OP(name, qp) \
-void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \
-{ \
- T1 = (target_ulong)glue(qp, MEMSUFFIX)(ADDR(T0)); \
-}
-
-#define SPARC_LD_OP_S(name, qp) \
- void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \
- { \
- T1 = (target_long)glue(qp, MEMSUFFIX)(ADDR(T0)); \
- }
-
-#define SPARC_ST_OP(name, op) \
-void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \
-{ \
- glue(op, MEMSUFFIX)(ADDR(T0), T1); \
-}
-
-SPARC_LD_OP(ld, ldl);
-SPARC_LD_OP(ldub, ldub);
-SPARC_LD_OP(lduh, lduw);
-SPARC_LD_OP_S(ldsb, ldsb);
-SPARC_LD_OP_S(ldsh, ldsw);
-
-/*** Integer store ***/
-SPARC_ST_OP(st, stl);
-SPARC_ST_OP(stb, stb);
-SPARC_ST_OP(sth, stw);
-
void OPPROTO glue(op_std, MEMSUFFIX)(void)
{
uint64_t tmp = ((uint64_t)T1 << 32) | (uint64_t)(T2 & 0xffffffff);
@@ -41,19 +11,6 @@
glue(stq, MEMSUFFIX)(ADDR(T0), tmp);
}
-void OPPROTO glue(op_ldstub, MEMSUFFIX)(void)
-{
- T1 = glue(ldub, MEMSUFFIX)(ADDR(T0));
- glue(stb, MEMSUFFIX)(ADDR(T0), 0xff); /* XXX: Should be Atomically */
-}
-
-void OPPROTO glue(op_swap, MEMSUFFIX)(void)
-{
- target_ulong tmp = glue(ldl, MEMSUFFIX)(ADDR(T0));
- glue(stl, MEMSUFFIX)(ADDR(T0), T1); /* XXX: Should be Atomically */
- T1 = tmp;
-}
-
void OPPROTO glue(op_ldd, MEMSUFFIX)(void)
{
uint64_t tmp;
@@ -107,18 +64,4 @@
}
#endif
-#ifdef TARGET_SPARC64
-void OPPROTO glue(op_lduw, MEMSUFFIX)(void)
-{
- T1 = (uint64_t)(glue(ldl, MEMSUFFIX)(ADDR(T0)) & 0xffffffff);
-}
-
-void OPPROTO glue(op_ldsw, MEMSUFFIX)(void)
-{
- T1 = (int64_t)(glue(ldl, MEMSUFFIX)(ADDR(T0)) & 0xffffffff);
-}
-
-SPARC_LD_OP(ldx, ldq);
-SPARC_ST_OP(stx, stq);
-#endif
#undef MEMSUFFIX
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [PATCH, RFC, WIP] TCG for Qemu target Sparc32/64
2008-02-21 20:27 [Qemu-devel] [PATCH, RFC, WIP] TCG for Qemu target Sparc32/64 Blue Swirl
@ 2008-02-22 0:06 ` Thiemo Seufer
2008-02-22 16:13 ` Blue Swirl
2008-02-23 18:23 ` [Qemu-devel] " Fabrice Bellard
1 sibling, 1 reply; 8+ messages in thread
From: Thiemo Seufer @ 2008-02-22 0:06 UTC (permalink / raw)
To: Blue Swirl; +Cc: qemu-devel
Blue Swirl wrote:
> The attached patch enables most TCG ops for Qemu Sparc32/64 target.
> Sparc32 softmmu and linux-user are OK, but Sparc64 and Sparc32plus
> targets do not work.
>
> Comments?
>
> It would be nice to get rid of T2 usage in std (also stda and
> casa/casxa) but I don't know how to pass a 64-bit value from legacy op
> to TCG stores and loads on a 32-bit target and host.
> Index: qemu/target-sparc/translate.c
> ===================================================================
> --- qemu.orig/target-sparc/translate.c 2008-02-21 20:00:28.000000000 +0000
> +++ qemu/target-sparc/translate.c 2008-02-21 20:02:07.000000000 +0000
> @@ -44,6 +44,81 @@
> #define JUMP_PC 2 /* dynamic pc value which takes only two values
> according to jump_pc[T2] */
>
> +#ifdef TARGET_SPARC64
> +#define TCG_TYPE_TL TCG_TYPE_I64
> +#define tcg_gen_movi_tl tcg_gen_movi_i64
> +#define tcg_gen_mov_tl tcg_gen_mov_i64
> +#define tcg_gen_ld8u_tl tcg_gen_ld8u_i64
> +#define tcg_gen_ld8s_tl tcg_gen_ld8s_i64
> +#define tcg_gen_ld16u_tl tcg_gen_ld16u_i64
> +#define tcg_gen_ld16s_tl tcg_gen_ld16s_i64
> +#define tcg_gen_ld32u_tl tcg_gen_ld32u_i64
> +#define tcg_gen_ld32s_tl tcg_gen_ld32s_i64
> +#define tcg_gen_ld_tl tcg_gen_ld_i64
> +#define tcg_gen_st8_tl tcg_gen_st8_i64
> +#define tcg_gen_st16_tl tcg_gen_st16_i64
> +#define tcg_gen_st32_tl tcg_gen_st32_i64
> +#define tcg_gen_st_tl tcg_gen_st_i64
> +#define tcg_gen_add_tl tcg_gen_add_i64
> +#define tcg_gen_addi_tl tcg_gen_addi_i64
> +#define tcg_gen_sub_tl tcg_gen_sub_i64
> +#define tcg_gen_subi_tl tcg_gen_subi_i64
> +#define tcg_gen_and_tl tcg_gen_and_i64
> +#define tcg_gen_andi_tl tcg_gen_andi_i64
> +#define tcg_gen_or_tl tcg_gen_or_i64
> +#define tcg_gen_ori_tl tcg_gen_ori_i64
> +#define tcg_gen_xor_tl tcg_gen_xor_i64
> +#define tcg_gen_xori_tl tcg_gen_xori_i64
> +#define tcg_gen_shl_tl tcg_gen_shl_i64
> +#define tcg_gen_shli_tl tcg_gen_shli_i64
> +#define tcg_gen_shr_tl tcg_gen_shr_i64
> +#define tcg_gen_shri_tl tcg_gen_shri_i64
> +#define tcg_gen_sar_tl tcg_gen_sar_i64
> +#define tcg_gen_sari_tl tcg_gen_sari_i64
> +#else
> +#define TCG_TYPE_TL TCG_TYPE_I32
> +#define tcg_gen_movi_tl tcg_gen_movi_i32
> +#define tcg_gen_mov_tl tcg_gen_mov_i32
> +#define tcg_gen_ld8u_tl tcg_gen_ld8u_i32
> +#define tcg_gen_ld8s_tl tcg_gen_ld8s_i32
> +#define tcg_gen_ld16u_tl tcg_gen_ld16u_i32
> +#define tcg_gen_ld16s_tl tcg_gen_ld16s_i32
> +#define tcg_gen_ld32u_tl tcg_gen_ld_i32
> +#define tcg_gen_ld32s_tl tcg_gen_ld_i32
> +#define tcg_gen_ld_tl tcg_gen_ld_i32
> +#define tcg_gen_st8_tl tcg_gen_st8_i32
> +#define tcg_gen_st16_tl tcg_gen_st16_i32
> +#define tcg_gen_st32_tl tcg_gen_st_i32
> +#define tcg_gen_st_tl tcg_gen_st_i32
> +#define tcg_gen_add_tl tcg_gen_add_i32
> +#define tcg_gen_addi_tl tcg_gen_addi_i32
> +#define tcg_gen_sub_tl tcg_gen_sub_i32
> +#define tcg_gen_subi_tl tcg_gen_subi_i32
> +#define tcg_gen_and_tl tcg_gen_and_i32
> +#define tcg_gen_andi_tl tcg_gen_andi_i32
> +#define tcg_gen_or_tl tcg_gen_or_i32
> +#define tcg_gen_ori_tl tcg_gen_ori_i32
> +#define tcg_gen_xor_tl tcg_gen_xor_i32
> +#define tcg_gen_xori_tl tcg_gen_xori_i32
> +#define tcg_gen_shl_tl tcg_gen_shl_i32
> +#define tcg_gen_shli_tl tcg_gen_shli_i32
> +#define tcg_gen_shr_tl tcg_gen_shr_i32
> +#define tcg_gen_shri_tl tcg_gen_shri_i32
> +#define tcg_gen_sar_tl tcg_gen_sar_i32
> +#define tcg_gen_sari_tl tcg_gen_sari_i32
> +#endif
This whole lot should probably move to generic code (conditionalized on
TARGET_LONG_BITS), I have the same code in my MIPS prototype.
Thiemo
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [PATCH, RFC, WIP] TCG for Qemu target Sparc32/64
2008-02-22 0:06 ` Thiemo Seufer
@ 2008-02-22 16:13 ` Blue Swirl
0 siblings, 0 replies; 8+ messages in thread
From: Blue Swirl @ 2008-02-22 16:13 UTC (permalink / raw)
To: Thiemo Seufer; +Cc: qemu-devel
On 2/22/08, Thiemo Seufer <ths@networkno.de> wrote:
> Blue Swirl wrote:
> > The attached patch enables most TCG ops for Qemu Sparc32/64 target.
> > Sparc32 softmmu and linux-user are OK, but Sparc64 and Sparc32plus
> > targets do not work.
> >
> > Comments?
> >
> > It would be nice to get rid of T2 usage in std (also stda and
> > casa/casxa) but I don't know how to pass a 64-bit value from legacy op
> > to TCG stores and loads on a 32-bit target and host.
[cut]
> This whole lot should probably move to generic code (conditionalized on
> TARGET_LONG_BITS), I have the same code in my MIPS prototype.
I agree. Also these lines, if they are really needed:
+#if TCG_TARGET_REG_BITS == 32
+#define tcg_gen_ld_ptr tcg_gen_ld_i32
+#else
+#define tcg_gen_ld_ptr tcg_gen_ld_i64
+#endif
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Qemu-devel] Re: [PATCH, RFC, WIP] TCG for Qemu target Sparc32/64
2008-02-21 20:27 [Qemu-devel] [PATCH, RFC, WIP] TCG for Qemu target Sparc32/64 Blue Swirl
2008-02-22 0:06 ` Thiemo Seufer
@ 2008-02-23 18:23 ` Fabrice Bellard
2008-02-23 18:29 ` Blue Swirl
` (2 more replies)
1 sibling, 3 replies; 8+ messages in thread
From: Fabrice Bellard @ 2008-02-23 18:23 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl
Blue Swirl wrote:
> The attached patch enables most TCG ops for Qemu Sparc32/64 target.
> Sparc32 softmmu and linux-user are OK, but Sparc64 and Sparc32plus
> targets do not work.
>
> Comments?
>
> It would be nice to get rid of T2 usage in std (also stda and
> casa/casxa) but I don't know how to pass a 64-bit value from legacy op
> to TCG stores and loads on a 32-bit target and host.
[...]
Also don't forget that T2 is used in CPU restore state to handle delay
slots. This part of the SPARC target is tricky and should be simplified.
Another point is that you should define TCG globals for each SPARC GPR.
It was not done for i386 because I feared performance regressions when
accessing to 16 bit or 8 bit sub-registers. On SPARC you do not have
this issue.
Regarding the generic "xxx_tl" defines, I did not move it into TCG
because I wanted TCG to be target independent. Since it is no longer the
case because of the target memory access instructions, I think it is a
good idea now. But do not mix the target specific defines with target
independent defines (in tcg-op.h there is a specific section for target
specific defines).
Regards,
Fabrice.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Qemu-devel] Re: [PATCH, RFC, WIP] TCG for Qemu target Sparc32/64
2008-02-23 18:23 ` [Qemu-devel] " Fabrice Bellard
@ 2008-02-23 18:29 ` Blue Swirl
2008-02-23 18:48 ` Fabrice Bellard
2008-02-23 20:32 ` Paul Brook
2008-02-23 23:59 ` Stuart Brady
2 siblings, 1 reply; 8+ messages in thread
From: Blue Swirl @ 2008-02-23 18:29 UTC (permalink / raw)
To: Fabrice Bellard; +Cc: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 1471 bytes --]
On 2/23/08, Fabrice Bellard <fabrice@bellard.org> wrote:
> Blue Swirl wrote:
> > The attached patch enables most TCG ops for Qemu Sparc32/64 target.
> > Sparc32 softmmu and linux-user are OK, but Sparc64 and Sparc32plus
> > targets do not work.
> >
> > Comments?
> >
> > It would be nice to get rid of T2 usage in std (also stda and
> > casa/casxa) but I don't know how to pass a 64-bit value from legacy op
> > to TCG stores and loads on a 32-bit target and host.
>
> [...]
>
> Also don't forget that T2 is used in CPU restore state to handle delay
> slots. This part of the SPARC target is tricky and should be simplified.
I just got rid of other T2 accesses.
> Another point is that you should define TCG globals for each SPARC GPR.
> It was not done for i386 because I feared performance regressions when
> accessing to 16 bit or 8 bit sub-registers. On SPARC you do not have
> this issue.
Nice idea. Would this also work for windowed registers?
> Regarding the generic "xxx_tl" defines, I did not move it into TCG
> because I wanted TCG to be target independent. Since it is no longer the
> case because of the target memory access instructions, I think it is a
> good idea now. But do not mix the target specific defines with target
> independent defines (in tcg-op.h there is a specific section for target
> specific defines).
Ok, I'll move them there.
Here's my current version. Sparc32 is still OK and Sparc32plus
helloworld executes.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: tcg_more_calls.diff --]
[-- Type: text/x-diff; name=tcg_more_calls.diff, Size: 1833 bytes --]
Index: qemu/tcg/tcg-op.h
===================================================================
--- qemu.orig/tcg/tcg-op.h 2008-02-23 06:48:38.000000000 +0000
+++ qemu/tcg/tcg-op.h 2008-02-23 08:13:15.000000000 +0000
@@ -192,6 +192,33 @@
0, NULL, 2, args);
}
+static inline void tcg_gen_helper_0_4(void *func, TCGv arg1, TCGv arg2,
+ TCGv arg3, TCGv arg4)
+{
+ TCGv args[4];
+ args[0] = arg1;
+ args[1] = arg2;
+ args[2] = arg3;
+ args[3] = arg4;
+ tcg_gen_call(&tcg_ctx,
+ tcg_const_ptr((tcg_target_long)func), TCG_HELPER_CALL_FLAGS,
+ 0, NULL, 4, args);
+}
+
+static inline void tcg_gen_helper_1_0(void *func, TCGv ret)
+{
+ tcg_gen_call(&tcg_ctx,
+ tcg_const_ptr((tcg_target_long)func), TCG_HELPER_CALL_FLAGS,
+ 1, &ret, 0, NULL);
+}
+
+static inline void tcg_gen_helper_1_1(void *func, TCGv ret, TCGv arg1)
+{
+ tcg_gen_call(&tcg_ctx,
+ tcg_const_ptr((tcg_target_long)func), TCG_HELPER_CALL_FLAGS,
+ 1, &ret, 1, &arg1);
+}
+
static inline void tcg_gen_helper_1_2(void *func, TCGv ret,
TCGv arg1, TCGv arg2)
{
@@ -203,6 +230,20 @@
1, &ret, 2, args);
}
+static inline void tcg_gen_helper_1_4(void *func, TCGv ret,
+ TCGv arg1, TCGv arg2, TCGv arg3,
+ TCGv arg4)
+{
+ TCGv args[4];
+ args[0] = arg1;
+ args[1] = arg2;
+ args[2] = arg3;
+ args[3] = arg4;
+ tcg_gen_call(&tcg_ctx,
+ tcg_const_ptr((tcg_target_long)func), TCG_HELPER_CALL_FLAGS,
+ 1, &ret, 4, args);
+}
+
/* 32 bit ops */
static inline void tcg_gen_ld8u_i32(TCGv ret, TCGv arg2, tcg_target_long offset)
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: tcg_sparc_target.diff --]
[-- Type: text/x-diff; name=tcg_sparc_target.diff, Size: 122097 bytes --]
Index: qemu/target-sparc/translate.c
===================================================================
--- qemu.orig/target-sparc/translate.c 2008-02-22 16:16:21.000000000 +0000
+++ qemu/target-sparc/translate.c 2008-02-23 16:47:43.000000000 +0000
@@ -36,6 +36,7 @@
#include "cpu.h"
#include "exec-all.h"
#include "disas.h"
+#include "helper.h"
#include "tcg-op.h"
#define DEBUG_DISAS
@@ -44,6 +45,81 @@
#define JUMP_PC 2 /* dynamic pc value which takes only two values
according to jump_pc[T2] */
+#ifdef TARGET_SPARC64
+#define TCG_TYPE_TL TCG_TYPE_I64
+#define tcg_gen_movi_tl tcg_gen_movi_i64
+#define tcg_gen_mov_tl tcg_gen_mov_i64
+#define tcg_gen_ld8u_tl tcg_gen_ld8u_i64
+#define tcg_gen_ld8s_tl tcg_gen_ld8s_i64
+#define tcg_gen_ld16u_tl tcg_gen_ld16u_i64
+#define tcg_gen_ld16s_tl tcg_gen_ld16s_i64
+#define tcg_gen_ld32u_tl tcg_gen_ld32u_i64
+#define tcg_gen_ld32s_tl tcg_gen_ld32s_i64
+#define tcg_gen_ld_tl tcg_gen_ld_i64
+#define tcg_gen_st8_tl tcg_gen_st8_i64
+#define tcg_gen_st16_tl tcg_gen_st16_i64
+#define tcg_gen_st32_tl tcg_gen_st32_i64
+#define tcg_gen_st_tl tcg_gen_st_i64
+#define tcg_gen_add_tl tcg_gen_add_i64
+#define tcg_gen_addi_tl tcg_gen_addi_i64
+#define tcg_gen_sub_tl tcg_gen_sub_i64
+#define tcg_gen_subi_tl tcg_gen_subi_i64
+#define tcg_gen_and_tl tcg_gen_and_i64
+#define tcg_gen_andi_tl tcg_gen_andi_i64
+#define tcg_gen_or_tl tcg_gen_or_i64
+#define tcg_gen_ori_tl tcg_gen_ori_i64
+#define tcg_gen_xor_tl tcg_gen_xor_i64
+#define tcg_gen_xori_tl tcg_gen_xori_i64
+#define tcg_gen_shl_tl tcg_gen_shl_i64
+#define tcg_gen_shli_tl tcg_gen_shli_i64
+#define tcg_gen_shr_tl tcg_gen_shr_i64
+#define tcg_gen_shri_tl tcg_gen_shri_i64
+#define tcg_gen_sar_tl tcg_gen_sar_i64
+#define tcg_gen_sari_tl tcg_gen_sari_i64
+#else
+#define TCG_TYPE_TL TCG_TYPE_I32
+#define tcg_gen_movi_tl tcg_gen_movi_i32
+#define tcg_gen_mov_tl tcg_gen_mov_i32
+#define tcg_gen_ld8u_tl tcg_gen_ld8u_i32
+#define tcg_gen_ld8s_tl tcg_gen_ld8s_i32
+#define tcg_gen_ld16u_tl tcg_gen_ld16u_i32
+#define tcg_gen_ld16s_tl tcg_gen_ld16s_i32
+#define tcg_gen_ld32u_tl tcg_gen_ld_i32
+#define tcg_gen_ld32s_tl tcg_gen_ld_i32
+#define tcg_gen_ld_tl tcg_gen_ld_i32
+#define tcg_gen_st8_tl tcg_gen_st8_i32
+#define tcg_gen_st16_tl tcg_gen_st16_i32
+#define tcg_gen_st32_tl tcg_gen_st_i32
+#define tcg_gen_st_tl tcg_gen_st_i32
+#define tcg_gen_add_tl tcg_gen_add_i32
+#define tcg_gen_addi_tl tcg_gen_addi_i32
+#define tcg_gen_sub_tl tcg_gen_sub_i32
+#define tcg_gen_subi_tl tcg_gen_subi_i32
+#define tcg_gen_and_tl tcg_gen_and_i32
+#define tcg_gen_andi_tl tcg_gen_andi_i32
+#define tcg_gen_or_tl tcg_gen_or_i32
+#define tcg_gen_ori_tl tcg_gen_ori_i32
+#define tcg_gen_xor_tl tcg_gen_xor_i32
+#define tcg_gen_xori_tl tcg_gen_xori_i32
+#define tcg_gen_shl_tl tcg_gen_shl_i32
+#define tcg_gen_shli_tl tcg_gen_shli_i32
+#define tcg_gen_shr_tl tcg_gen_shr_i32
+#define tcg_gen_shri_tl tcg_gen_shri_i32
+#define tcg_gen_sar_tl tcg_gen_sar_i32
+#define tcg_gen_sari_tl tcg_gen_sari_i32
+#endif
+
+#if TCG_TARGET_REG_BITS == 32
+#define tcg_gen_ld_ptr tcg_gen_ld_i32
+#else
+#define tcg_gen_ld_ptr tcg_gen_ld_i64
+#endif
+
+/* global register indexes */
+static TCGv cpu_env, cpu_T[3], cpu_regwptr;
+/* local register indexes (only used inside old micro ops) */
+static TCGv cpu_tmp0;
+
typedef struct DisasContext {
target_ulong pc; /* current Program Counter: integer or DYNAMIC_PC */
target_ulong npc; /* next PC: integer or DYNAMIC_PC or JUMP_PC */
@@ -102,195 +178,6 @@
static void disas_sparc_insn(DisasContext * dc);
-static GenOpFunc * const gen_op_movl_TN_reg[2][32] = {
- {
- gen_op_movl_g0_T0,
- gen_op_movl_g1_T0,
- gen_op_movl_g2_T0,
- gen_op_movl_g3_T0,
- gen_op_movl_g4_T0,
- gen_op_movl_g5_T0,
- gen_op_movl_g6_T0,
- gen_op_movl_g7_T0,
- gen_op_movl_o0_T0,
- gen_op_movl_o1_T0,
- gen_op_movl_o2_T0,
- gen_op_movl_o3_T0,
- gen_op_movl_o4_T0,
- gen_op_movl_o5_T0,
- gen_op_movl_o6_T0,
- gen_op_movl_o7_T0,
- gen_op_movl_l0_T0,
- gen_op_movl_l1_T0,
- gen_op_movl_l2_T0,
- gen_op_movl_l3_T0,
- gen_op_movl_l4_T0,
- gen_op_movl_l5_T0,
- gen_op_movl_l6_T0,
- gen_op_movl_l7_T0,
- gen_op_movl_i0_T0,
- gen_op_movl_i1_T0,
- gen_op_movl_i2_T0,
- gen_op_movl_i3_T0,
- gen_op_movl_i4_T0,
- gen_op_movl_i5_T0,
- gen_op_movl_i6_T0,
- gen_op_movl_i7_T0,
- },
- {
- gen_op_movl_g0_T1,
- gen_op_movl_g1_T1,
- gen_op_movl_g2_T1,
- gen_op_movl_g3_T1,
- gen_op_movl_g4_T1,
- gen_op_movl_g5_T1,
- gen_op_movl_g6_T1,
- gen_op_movl_g7_T1,
- gen_op_movl_o0_T1,
- gen_op_movl_o1_T1,
- gen_op_movl_o2_T1,
- gen_op_movl_o3_T1,
- gen_op_movl_o4_T1,
- gen_op_movl_o5_T1,
- gen_op_movl_o6_T1,
- gen_op_movl_o7_T1,
- gen_op_movl_l0_T1,
- gen_op_movl_l1_T1,
- gen_op_movl_l2_T1,
- gen_op_movl_l3_T1,
- gen_op_movl_l4_T1,
- gen_op_movl_l5_T1,
- gen_op_movl_l6_T1,
- gen_op_movl_l7_T1,
- gen_op_movl_i0_T1,
- gen_op_movl_i1_T1,
- gen_op_movl_i2_T1,
- gen_op_movl_i3_T1,
- gen_op_movl_i4_T1,
- gen_op_movl_i5_T1,
- gen_op_movl_i6_T1,
- gen_op_movl_i7_T1,
- }
-};
-
-static GenOpFunc * const gen_op_movl_reg_TN[3][32] = {
- {
- gen_op_movl_T0_g0,
- gen_op_movl_T0_g1,
- gen_op_movl_T0_g2,
- gen_op_movl_T0_g3,
- gen_op_movl_T0_g4,
- gen_op_movl_T0_g5,
- gen_op_movl_T0_g6,
- gen_op_movl_T0_g7,
- gen_op_movl_T0_o0,
- gen_op_movl_T0_o1,
- gen_op_movl_T0_o2,
- gen_op_movl_T0_o3,
- gen_op_movl_T0_o4,
- gen_op_movl_T0_o5,
- gen_op_movl_T0_o6,
- gen_op_movl_T0_o7,
- gen_op_movl_T0_l0,
- gen_op_movl_T0_l1,
- gen_op_movl_T0_l2,
- gen_op_movl_T0_l3,
- gen_op_movl_T0_l4,
- gen_op_movl_T0_l5,
- gen_op_movl_T0_l6,
- gen_op_movl_T0_l7,
- gen_op_movl_T0_i0,
- gen_op_movl_T0_i1,
- gen_op_movl_T0_i2,
- gen_op_movl_T0_i3,
- gen_op_movl_T0_i4,
- gen_op_movl_T0_i5,
- gen_op_movl_T0_i6,
- gen_op_movl_T0_i7,
- },
- {
- gen_op_movl_T1_g0,
- gen_op_movl_T1_g1,
- gen_op_movl_T1_g2,
- gen_op_movl_T1_g3,
- gen_op_movl_T1_g4,
- gen_op_movl_T1_g5,
- gen_op_movl_T1_g6,
- gen_op_movl_T1_g7,
- gen_op_movl_T1_o0,
- gen_op_movl_T1_o1,
- gen_op_movl_T1_o2,
- gen_op_movl_T1_o3,
- gen_op_movl_T1_o4,
- gen_op_movl_T1_o5,
- gen_op_movl_T1_o6,
- gen_op_movl_T1_o7,
- gen_op_movl_T1_l0,
- gen_op_movl_T1_l1,
- gen_op_movl_T1_l2,
- gen_op_movl_T1_l3,
- gen_op_movl_T1_l4,
- gen_op_movl_T1_l5,
- gen_op_movl_T1_l6,
- gen_op_movl_T1_l7,
- gen_op_movl_T1_i0,
- gen_op_movl_T1_i1,
- gen_op_movl_T1_i2,
- gen_op_movl_T1_i3,
- gen_op_movl_T1_i4,
- gen_op_movl_T1_i5,
- gen_op_movl_T1_i6,
- gen_op_movl_T1_i7,
- },
- {
- gen_op_movl_T2_g0,
- gen_op_movl_T2_g1,
- gen_op_movl_T2_g2,
- gen_op_movl_T2_g3,
- gen_op_movl_T2_g4,
- gen_op_movl_T2_g5,
- gen_op_movl_T2_g6,
- gen_op_movl_T2_g7,
- gen_op_movl_T2_o0,
- gen_op_movl_T2_o1,
- gen_op_movl_T2_o2,
- gen_op_movl_T2_o3,
- gen_op_movl_T2_o4,
- gen_op_movl_T2_o5,
- gen_op_movl_T2_o6,
- gen_op_movl_T2_o7,
- gen_op_movl_T2_l0,
- gen_op_movl_T2_l1,
- gen_op_movl_T2_l2,
- gen_op_movl_T2_l3,
- gen_op_movl_T2_l4,
- gen_op_movl_T2_l5,
- gen_op_movl_T2_l6,
- gen_op_movl_T2_l7,
- gen_op_movl_T2_i0,
- gen_op_movl_T2_i1,
- gen_op_movl_T2_i2,
- gen_op_movl_T2_i3,
- gen_op_movl_T2_i4,
- gen_op_movl_T2_i5,
- gen_op_movl_T2_i6,
- gen_op_movl_T2_i7,
- }
-};
-
-static GenOpFunc1 * const gen_op_movl_TN_im[3] = {
- gen_op_movl_T0_im,
- gen_op_movl_T1_im,
- gen_op_movl_T2_im
-};
-
-// Sign extending version
-static GenOpFunc1 * const gen_op_movl_TN_sim[3] = {
- gen_op_movl_T0_sim,
- gen_op_movl_T1_sim,
- gen_op_movl_T2_sim
-};
-
#ifdef TARGET_SPARC64
#define GEN32(func, NAME) \
static GenOpFunc * const NAME ## _table [64] = { \
@@ -375,307 +262,112 @@
#endif
#ifndef CONFIG_USER_ONLY
-OP_LD_TABLE(ld);
-OP_LD_TABLE(st);
-OP_LD_TABLE(ldub);
-OP_LD_TABLE(lduh);
-OP_LD_TABLE(ldsb);
-OP_LD_TABLE(ldsh);
-OP_LD_TABLE(stb);
-OP_LD_TABLE(sth);
-OP_LD_TABLE(std);
-OP_LD_TABLE(ldstub);
-OP_LD_TABLE(swap);
-OP_LD_TABLE(ldd);
OP_LD_TABLE(stf);
OP_LD_TABLE(stdf);
OP_LD_TABLE(ldf);
OP_LD_TABLE(lddf);
-
-#ifdef TARGET_SPARC64
-OP_LD_TABLE(lduw);
-OP_LD_TABLE(ldsw);
-OP_LD_TABLE(ldx);
-OP_LD_TABLE(stx);
#endif
-#endif
-
-/* asi moves */
-#ifdef TARGET_SPARC64
-static inline void gen_ld_asi(int insn, int size, int sign)
-{
- int asi, offset;
-
- if (IS_IMM) {
- offset = GET_FIELD(insn, 25, 31);
- gen_op_ld_asi_reg(offset, size, sign);
- } else {
- asi = GET_FIELD(insn, 19, 26);
- gen_op_ld_asi(asi, size, sign);
- }
-}
-
-static inline void gen_st_asi(int insn, int size)
-{
- int asi, offset;
-
- if (IS_IMM) {
- offset = GET_FIELD(insn, 25, 31);
- gen_op_st_asi_reg(offset, size);
- } else {
- asi = GET_FIELD(insn, 19, 26);
- gen_op_st_asi(asi, size);
- }
-}
-
-static inline void gen_ldf_asi(int insn, int size, int rd)
-{
- int asi, offset;
-
- if (IS_IMM) {
- offset = GET_FIELD(insn, 25, 31);
- gen_op_ldf_asi_reg(offset, size, rd);
- } else {
- asi = GET_FIELD(insn, 19, 26);
- gen_op_ldf_asi(asi, size, rd);
- }
-}
-
-static inline void gen_stf_asi(int insn, int size, int rd)
-{
- int asi, offset;
-
- if (IS_IMM) {
- offset = GET_FIELD(insn, 25, 31);
- gen_op_stf_asi_reg(offset, size, rd);
- } else {
- asi = GET_FIELD(insn, 19, 26);
- gen_op_stf_asi(asi, size, rd);
- }
-}
-static inline void gen_swap_asi(int insn)
-{
- int asi, offset;
-
- if (IS_IMM) {
- offset = GET_FIELD(insn, 25, 31);
- gen_op_swap_asi_reg(offset);
- } else {
- asi = GET_FIELD(insn, 19, 26);
- gen_op_swap_asi(asi);
- }
-}
+#ifdef TARGET_ABI32
+#define ABI32_MASK(addr) tcg_gen_andi_i64(addr, addr, 0xffffffff);
+#else
+#define ABI32_MASK(addr)
+#endif
-static inline void gen_ldstub_asi(int insn)
+static inline void gen_movl_simm_T1(int32_t val)
{
- int asi, offset;
-
- if (IS_IMM) {
- offset = GET_FIELD(insn, 25, 31);
- gen_op_ldstub_asi_reg(offset);
- } else {
- asi = GET_FIELD(insn, 19, 26);
- gen_op_ldstub_asi(asi);
- }
+ tcg_gen_movi_tl(cpu_T[1], val);
}
-static inline void gen_ldda_asi(int insn)
+static inline void gen_movl_reg_TN(int reg, TCGv tn)
{
- int asi, offset;
-
- if (IS_IMM) {
- offset = GET_FIELD(insn, 25, 31);
- gen_op_ldda_asi_reg(offset);
- } else {
- asi = GET_FIELD(insn, 19, 26);
- gen_op_ldda_asi(asi);
+ if (reg == 0)
+ tcg_gen_movi_tl(tn, 0);
+ else if (reg < 8)
+ tcg_gen_ld_tl(tn, cpu_env, offsetof(CPUState, gregs[reg]));
+ else {
+ tcg_gen_ld_ptr(cpu_regwptr, cpu_env, offsetof(CPUState, regwptr)); // XXX
+ tcg_gen_ld_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
}
}
-static inline void gen_stda_asi(int insn)
+static inline void gen_movl_reg_T0(int reg)
{
- int asi, offset;
-
- if (IS_IMM) {
- offset = GET_FIELD(insn, 25, 31);
- gen_op_stda_asi_reg(offset);
- } else {
- asi = GET_FIELD(insn, 19, 26);
- gen_op_stda_asi(asi);
- }
+ gen_movl_reg_TN(reg, cpu_T[0]);
}
-static inline void gen_cas_asi(int insn)
+static inline void gen_movl_reg_T1(int reg)
{
- int asi, offset;
-
- if (IS_IMM) {
- offset = GET_FIELD(insn, 25, 31);
- gen_op_cas_asi_reg(offset);
- } else {
- asi = GET_FIELD(insn, 19, 26);
- gen_op_cas_asi(asi);
- }
+ gen_movl_reg_TN(reg, cpu_T[1]);
}
-static inline void gen_casx_asi(int insn)
+static inline void gen_movl_TN_reg(int reg, TCGv tn)
{
- int asi, offset;
-
- if (IS_IMM) {
- offset = GET_FIELD(insn, 25, 31);
- gen_op_casx_asi_reg(offset);
- } else {
- asi = GET_FIELD(insn, 19, 26);
- gen_op_casx_asi(asi);
+ if (reg == 0)
+ return;
+ else if (reg < 8)
+ tcg_gen_st_tl(tn, cpu_env, offsetof(CPUState, gregs[reg]));
+ else {
+ tcg_gen_ld_ptr(cpu_regwptr, cpu_env, offsetof(CPUState, regwptr)); // XXX
+ tcg_gen_st_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
}
}
-#elif !defined(CONFIG_USER_ONLY)
-
-static inline void gen_ld_asi(int insn, int size, int sign)
-{
- int asi;
-
- asi = GET_FIELD(insn, 19, 26);
- gen_op_ld_asi(asi, size, sign);
-}
-
-static inline void gen_st_asi(int insn, int size)
-{
- int asi;
-
- asi = GET_FIELD(insn, 19, 26);
- gen_op_st_asi(asi, size);
-}
-
-static inline void gen_ldstub_asi(int insn)
-{
- int asi;
-
- asi = GET_FIELD(insn, 19, 26);
- gen_op_ldstub_asi(asi);
-}
-
-static inline void gen_swap_asi(int insn)
-{
- int asi;
-
- asi = GET_FIELD(insn, 19, 26);
- gen_op_swap_asi(asi);
-}
-
-static inline void gen_ldda_asi(int insn)
-{
- int asi;
-
- asi = GET_FIELD(insn, 19, 26);
- gen_op_ld_asi(asi, 8, 0);
-}
-
-static inline void gen_stda_asi(int insn)
-{
- int asi;
-
- asi = GET_FIELD(insn, 19, 26);
- gen_op_st_asi(asi, 8);
-}
-#endif
-
-static inline void gen_movl_imm_TN(int reg, uint32_t imm)
-{
- gen_op_movl_TN_im[reg](imm);
-}
-
-static inline void gen_movl_imm_T1(uint32_t val)
-{
- gen_movl_imm_TN(1, val);
-}
-
-static inline void gen_movl_imm_T0(uint32_t val)
-{
- gen_movl_imm_TN(0, val);
-}
-
-static inline void gen_movl_simm_TN(int reg, int32_t imm)
+static inline void gen_movl_T0_reg(int reg)
{
- gen_op_movl_TN_sim[reg](imm);
+ gen_movl_TN_reg(reg, cpu_T[0]);
}
-static inline void gen_movl_simm_T1(int32_t val)
+static inline void gen_movl_T1_reg(int reg)
{
- gen_movl_simm_TN(1, val);
+ gen_movl_TN_reg(reg, cpu_T[1]);
}
-static inline void gen_movl_simm_T0(int32_t val)
+static inline void gen_op_movl_T0_env(size_t offset)
{
- gen_movl_simm_TN(0, val);
+ tcg_gen_ld_i32(cpu_T[0], cpu_env, offset);
}
-static inline void gen_movl_reg_TN(int reg, int t)
+static inline void gen_op_movl_env_T0(size_t offset)
{
- if (reg)
- gen_op_movl_reg_TN[t][reg] ();
- else
- gen_movl_imm_TN(t, 0);
+ tcg_gen_st_i32(cpu_T[0], cpu_env, offset);
}
-static inline void gen_movl_reg_T0(int reg)
+static inline void gen_op_movtl_T0_env(size_t offset)
{
- gen_movl_reg_TN(reg, 0);
+ tcg_gen_ld_tl(cpu_T[0], cpu_env, offset);
}
-static inline void gen_movl_reg_T1(int reg)
+static inline void gen_op_movtl_env_T0(size_t offset)
{
- gen_movl_reg_TN(reg, 1);
+ tcg_gen_st_tl(cpu_T[0], cpu_env, offset);
}
-static inline void gen_movl_reg_T2(int reg)
+static inline void gen_op_add_T1_T0(void)
{
- gen_movl_reg_TN(reg, 2);
+ tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
}
-static inline void gen_movl_TN_reg(int reg, int t)
+static inline void gen_op_or_T1_T0(void)
{
- if (reg)
- gen_op_movl_TN_reg[t][reg] ();
+ tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
}
-static inline void gen_movl_T0_reg(int reg)
+static inline void gen_op_xor_T1_T0(void)
{
- gen_movl_TN_reg(reg, 0);
-}
-
-static inline void gen_movl_T1_reg(int reg)
-{
- gen_movl_TN_reg(reg, 1);
+ tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
}
static inline void gen_jmp_im(target_ulong pc)
{
-#ifdef TARGET_SPARC64
- if (pc == (uint32_t)pc) {
- gen_op_jmp_im(pc);
- } else {
- gen_op_jmp_im64(pc >> 32, pc);
- }
-#else
- gen_op_jmp_im(pc);
-#endif
+ tcg_gen_movi_tl(cpu_tmp0, pc);
+ tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, pc));
}
static inline void gen_movl_npc_im(target_ulong npc)
{
-#ifdef TARGET_SPARC64
- if (npc == (uint32_t)npc) {
- gen_op_movl_npc_im(npc);
- } else {
- gen_op_movq_npc_im64(npc >> 32, npc);
- }
-#else
- gen_op_movl_npc_im(npc);
-#endif
+ tcg_gen_movi_tl(cpu_tmp0, npc);
+ tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, npc));
}
static inline void gen_goto_tb(DisasContext *s, int tb_num,
@@ -1095,6 +787,270 @@
return 0;
}
+/* asi moves */
+#ifdef TARGET_SPARC64
+static inline void gen_ld_asi(int insn, int size, int sign)
+{
+ int asi, offset;
+ TCGv r_size, r_sign;
+
+ r_size = tcg_temp_new(TCG_TYPE_I32);
+ r_sign = tcg_temp_new(TCG_TYPE_I32);
+ tcg_gen_movi_i32(r_size, size);
+ tcg_gen_movi_i32(r_sign, sign);
+ if (IS_IMM) {
+ offset = GET_FIELD(insn, 25, 31);
+ tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
+ tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUSPARCState, asi));
+ } else {
+ asi = GET_FIELD(insn, 19, 26);
+ tcg_gen_movi_i32(cpu_T[1], asi);
+ }
+ tcg_gen_helper_1_4(helper_ld_asi, cpu_T[1], cpu_T[0], cpu_T[1], r_size,
+ r_sign);
+}
+
+static inline void gen_st_asi(int insn, int size)
+{
+ int asi, offset;
+ TCGv r_asi, r_size;
+
+ r_asi = tcg_temp_new(TCG_TYPE_I32);
+ r_size = tcg_temp_new(TCG_TYPE_I32);
+ tcg_gen_movi_i32(r_size, size);
+ if (IS_IMM) {
+ offset = GET_FIELD(insn, 25, 31);
+ tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
+ tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
+ } else {
+ asi = GET_FIELD(insn, 19, 26);
+ tcg_gen_movi_i32(r_asi, asi);
+ }
+ tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], cpu_T[1], r_asi, r_size);
+}
+
+static inline void gen_ldf_asi(int insn, int size, int rd)
+{
+ int asi, offset;
+ TCGv r_asi, r_size, r_rd;
+
+ r_asi = tcg_temp_new(TCG_TYPE_I32);
+ r_size = tcg_temp_new(TCG_TYPE_I32);
+ r_rd = tcg_temp_new(TCG_TYPE_I32);
+ tcg_gen_movi_i32(r_size, size);
+ tcg_gen_movi_i32(r_rd, rd);
+ if (IS_IMM) {
+ offset = GET_FIELD(insn, 25, 31);
+ tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
+ tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
+ } else {
+ asi = GET_FIELD(insn, 19, 26);
+ tcg_gen_movi_i32(r_asi, asi);
+ }
+ tcg_gen_helper_0_4(helper_ldf_asi, cpu_T[0], r_asi, r_size, r_rd);
+}
+
+static inline void gen_stf_asi(int insn, int size, int rd)
+{
+ int asi, offset;
+ TCGv r_asi, r_size, r_rd;
+
+ r_asi = tcg_temp_new(TCG_TYPE_I32);
+ r_size = tcg_temp_new(TCG_TYPE_I32);
+ r_rd = tcg_temp_new(TCG_TYPE_I32);
+ tcg_gen_movi_i32(r_size, size);
+ tcg_gen_movi_i32(r_rd, rd);
+ if (IS_IMM) {
+ offset = GET_FIELD(insn, 25, 31);
+ tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
+ tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
+ } else {
+ asi = GET_FIELD(insn, 19, 26);
+ tcg_gen_movi_i32(r_asi, asi);
+ }
+ tcg_gen_helper_0_4(helper_stf_asi, cpu_T[0], r_asi, r_size, r_rd);
+}
+
+static inline void gen_swap_asi(int insn)
+{
+ int asi, offset;
+ TCGv r_size, r_sign, r_temp;
+
+ r_size = tcg_temp_new(TCG_TYPE_I32);
+ r_sign = tcg_temp_new(TCG_TYPE_I32);
+ r_temp = tcg_temp_new(TCG_TYPE_I32);
+ tcg_gen_movi_i32(r_size, 4);
+ tcg_gen_movi_i32(r_sign, 0);
+ if (IS_IMM) {
+ offset = GET_FIELD(insn, 25, 31);
+ tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
+ tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUSPARCState, asi));
+ } else {
+ asi = GET_FIELD(insn, 19, 26);
+ tcg_gen_movi_i32(cpu_T[1], asi);
+ }
+ tcg_gen_helper_1_4(helper_ld_asi, r_temp, cpu_T[0], cpu_T[1], r_size,
+ r_sign);
+ tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], cpu_T[1], r_size, r_sign);
+ tcg_gen_mov_i32(cpu_T[1], r_temp);
+}
+
+static inline void gen_ldda_asi(int insn)
+{
+ int asi, offset;
+ TCGv r_size, r_sign, r_dword;
+
+ r_size = tcg_temp_new(TCG_TYPE_I32);
+ r_sign = tcg_temp_new(TCG_TYPE_I32);
+ r_dword = tcg_temp_new(TCG_TYPE_I64);
+ tcg_gen_movi_i32(r_size, 8);
+ tcg_gen_movi_i32(r_sign, 0);
+ if (IS_IMM) {
+ offset = GET_FIELD(insn, 25, 31);
+ tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
+ tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUSPARCState, asi));
+ } else {
+ asi = GET_FIELD(insn, 19, 26);
+ tcg_gen_movi_i32(cpu_T[1], asi);
+ }
+ tcg_gen_helper_1_4(helper_ld_asi, r_dword, cpu_T[0], cpu_T[1], r_size,
+ r_sign);
+ tcg_gen_trunc_i64_i32(cpu_T[0], r_dword);
+ tcg_gen_shri_i64(r_dword, r_dword, 32);
+ tcg_gen_trunc_i64_i32(cpu_T[1], r_dword);
+}
+
+static inline void gen_cas_asi(int insn, int rd)
+{
+ int asi, offset;
+ TCGv r_val1, r_asi;
+
+ r_val1 = tcg_temp_new(TCG_TYPE_I32);
+ r_asi = tcg_temp_new(TCG_TYPE_I32);
+ gen_movl_reg_TN(rd, r_val1);
+ if (IS_IMM) {
+ offset = GET_FIELD(insn, 25, 31);
+ tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
+ tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
+ } else {
+ asi = GET_FIELD(insn, 19, 26);
+ tcg_gen_movi_i32(r_asi, asi);
+ }
+ tcg_gen_helper_1_4(helper_cas_asi, cpu_T[1], cpu_T[0], r_val1, cpu_T[1],
+ r_asi);
+}
+
+static inline void gen_casx_asi(int insn, int rd)
+{
+ int asi, offset;
+ TCGv r_val1, r_asi;
+
+ r_val1 = tcg_temp_new(TCG_TYPE_I64);
+ r_asi = tcg_temp_new(TCG_TYPE_I32);
+ gen_movl_reg_TN(rd, r_val1);
+ if (IS_IMM) {
+ offset = GET_FIELD(insn, 25, 31);
+ tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
+ tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
+ } else {
+ asi = GET_FIELD(insn, 19, 26);
+ tcg_gen_movi_i32(r_asi, asi);
+ }
+ tcg_gen_helper_1_4(helper_casx_asi, cpu_T[1], cpu_T[0], r_val1, cpu_T[1],
+ r_asi);
+}
+
+#elif !defined(CONFIG_USER_ONLY)
+
+static inline void gen_ld_asi(int insn, int size, int sign)
+{
+ int asi;
+ TCGv r_size, r_sign, r_dword;
+
+ r_size = tcg_temp_new(TCG_TYPE_I32);
+ r_sign = tcg_temp_new(TCG_TYPE_I32);
+ r_dword = tcg_temp_new(TCG_TYPE_I64);
+ tcg_gen_movi_i32(r_size, size);
+ tcg_gen_movi_i32(r_sign, sign);
+ asi = GET_FIELD(insn, 19, 26);
+ tcg_gen_movi_i32(cpu_T[1], asi);
+ tcg_gen_helper_1_4(helper_ld_asi, r_dword, cpu_T[0], cpu_T[1], r_size,
+ r_sign);
+ tcg_gen_trunc_i64_i32(cpu_T[1], r_dword);
+}
+
+static inline void gen_st_asi(int insn, int size)
+{
+ int asi;
+ TCGv r_dword, r_asi, r_size;
+
+ r_dword = tcg_temp_new(TCG_TYPE_I64);
+ tcg_gen_extu_i32_i64(r_dword, cpu_T[1]);
+ r_asi = tcg_temp_new(TCG_TYPE_I32);
+ r_size = tcg_temp_new(TCG_TYPE_I32);
+ asi = GET_FIELD(insn, 19, 26);
+ tcg_gen_movi_i32(r_asi, asi);
+ tcg_gen_movi_i32(r_size, size);
+ tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], r_dword, r_asi, r_size);
+}
+
+static inline void gen_swap_asi(int insn)
+{
+ int asi;
+ TCGv r_size, r_sign, r_temp;
+
+ r_size = tcg_temp_new(TCG_TYPE_I32);
+ r_sign = tcg_temp_new(TCG_TYPE_I32);
+ r_temp = tcg_temp_new(TCG_TYPE_I32);
+ tcg_gen_movi_i32(r_size, 4);
+ tcg_gen_movi_i32(r_sign, 0);
+ asi = GET_FIELD(insn, 19, 26);
+ tcg_gen_movi_i32(cpu_T[1], asi);
+ tcg_gen_helper_1_4(helper_ld_asi, r_temp, cpu_T[0], cpu_T[1], r_size,
+ r_sign);
+ tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], cpu_T[1], r_size, r_sign);
+ tcg_gen_mov_i32(cpu_T[1], r_temp);
+}
+
+static inline void gen_ldda_asi(int insn)
+{
+ int asi;
+ TCGv r_size, r_sign, r_dword;
+
+ r_size = tcg_temp_new(TCG_TYPE_I32);
+ r_sign = tcg_temp_new(TCG_TYPE_I32);
+ r_dword = tcg_temp_new(TCG_TYPE_I64);
+ tcg_gen_movi_i32(r_size, 8);
+ tcg_gen_movi_i32(r_sign, 0);
+ asi = GET_FIELD(insn, 19, 26);
+ tcg_gen_movi_i32(cpu_T[1], asi);
+ tcg_gen_helper_1_4(helper_ld_asi, r_dword, cpu_T[0], cpu_T[1], r_size,
+ r_sign);
+ tcg_gen_trunc_i64_i32(cpu_T[0], r_dword);
+ tcg_gen_shri_i64(r_dword, r_dword, 32);
+ tcg_gen_trunc_i64_i32(cpu_T[1], r_dword);
+}
+#endif
+
+#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
+static inline void gen_ldstub_asi(int insn)
+{
+ int asi;
+ TCGv r_dword, r_asi, r_size;
+
+ gen_ld_asi(insn, 1, 0);
+
+ r_dword = tcg_temp_new(TCG_TYPE_I64);
+ r_asi = tcg_temp_new(TCG_TYPE_I32);
+ r_size = tcg_temp_new(TCG_TYPE_I32);
+ asi = GET_FIELD(insn, 19, 26);
+ tcg_gen_movi_i32(r_dword, 0xff);
+ tcg_gen_movi_i32(r_asi, asi);
+ tcg_gen_movi_i32(r_size, 1);
+ tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], r_dword, r_asi, r_size);
+}
+#endif
+
/* before an instruction, dc->pc must be static */
static void disas_sparc_insn(DisasContext * dc)
{
@@ -1179,7 +1135,7 @@
if (rd) { // nop
#endif
uint32_t value = GET_FIELD(insn, 10, 31);
- gen_movl_imm_T0(value << 10);
+ tcg_gen_movi_tl(cpu_T[0], value << 10);
gen_movl_T0_reg(rd);
#if defined(OPTIM)
}
@@ -1196,15 +1152,7 @@
/*CALL*/ {
target_long target = GET_FIELDs(insn, 2, 31) << 2;
-#ifdef TARGET_SPARC64
- if (dc->pc == (uint32_t)dc->pc) {
- gen_op_movl_T0_im(dc->pc);
- } else {
- gen_op_movq_T0_im64(dc->pc >> 32, dc->pc);
- }
-#else
- gen_op_movl_T0_im(dc->pc);
-#endif
+ tcg_gen_movi_tl(cpu_T[0], dc->pc);
gen_movl_T0_reg(15);
target += dc->pc;
gen_mov_pc_npc(dc);
@@ -1221,14 +1169,7 @@
gen_movl_reg_T0(rs1);
if (IS_IMM) {
rs2 = GET_FIELD(insn, 25, 31);
-#if defined(OPTIM)
- if (rs2 != 0) {
-#endif
- gen_movl_simm_T1(rs2);
- gen_op_add_T1_T0();
-#if defined(OPTIM)
- }
-#endif
+ tcg_gen_addi_tl(cpu_T[0], cpu_T[0], rs2);
} else {
rs2 = GET_FIELD(insn, 27, 31);
#if defined(OPTIM)
@@ -1243,7 +1184,7 @@
cond = GET_FIELD(insn, 3, 6);
if (cond == 0x8) {
save_state(dc);
- gen_op_trap_T0();
+ tcg_gen_helper_0_1(helper_trap, cpu_T[0]);
} else if (cond != 0) {
#ifdef TARGET_SPARC64
/* V9 icc/xcc */
@@ -1261,7 +1202,7 @@
save_state(dc);
gen_cond[0][cond]();
#endif
- gen_op_trapcc_T0();
+ tcg_gen_helper_0_2(helper_trapcc, cpu_T[0], cpu_T[2]);
}
gen_op_next_insn();
tcg_gen_exit_tb(0);
@@ -1298,11 +1239,7 @@
gen_movl_T0_reg(rd);
break;
case 0x5: /* V9 rdpc */
- if (dc->pc == (uint32_t)dc->pc) {
- gen_op_movl_T0_im(dc->pc);
- } else {
- gen_op_movq_T0_im64(dc->pc >> 32, dc->pc);
- }
+ tcg_gen_movi_tl(cpu_T[0], dc->pc);
gen_movl_T0_reg(rd);
break;
case 0x6: /* V9 rdfprs */
@@ -1344,7 +1281,7 @@
#ifndef TARGET_SPARC64
if (!supervisor(dc))
goto priv_insn;
- gen_op_rdpsr();
+ tcg_gen_helper_1_0(helper_rdpsr, cpu_T[0]);
#else
if (!hypervisor(dc))
goto priv_insn;
@@ -1399,7 +1336,7 @@
gen_op_movtl_T0_env(offsetof(CPUSPARCState, tbr));
break;
case 6: // pstate
- gen_op_rdpstate();
+ gen_op_movl_T0_env(offsetof(CPUSPARCState, pstate));
break;
case 7: // tl
gen_op_movl_T0_env(offsetof(CPUSPARCState, tl));
@@ -2078,24 +2015,19 @@
rs1 = GET_FIELD(insn, 13, 17);
if (rs1 == 0) {
- // or %g0, x, y -> mov T1, x; mov y, T1
+ // or %g0, x, y -> mov T0, x; mov y, T0
if (IS_IMM) { /* immediate */
rs2 = GET_FIELDs(insn, 19, 31);
- gen_movl_simm_T1(rs2);
+ tcg_gen_movi_tl(cpu_T[0], rs2);
} else { /* register */
rs2 = GET_FIELD(insn, 27, 31);
- gen_movl_reg_T1(rs2);
+ gen_movl_reg_T0(rs2);
}
- gen_movl_T1_reg(rd);
} else {
gen_movl_reg_T0(rs1);
if (IS_IMM) { /* immediate */
- // or x, #0, y -> mov T1, x; mov y, T1
rs2 = GET_FIELDs(insn, 19, 31);
- if (rs2 != 0) {
- gen_movl_simm_T1(rs2);
- gen_op_or_T1_T0();
- }
+ tcg_gen_ori_tl(cpu_T[0], cpu_T[0], rs2);
} else { /* register */
// or x, %g0, y -> mov T1, x; mov y, T1
rs2 = GET_FIELD(insn, 27, 31);
@@ -2104,8 +2036,8 @@
gen_op_or_T1_T0();
}
}
- gen_movl_T0_reg(rd);
}
+ gen_movl_T0_reg(rd);
#endif
#ifdef TARGET_SPARC64
} else if (xop == 0x25) { /* sll, V9 sllx */
@@ -2113,45 +2045,72 @@
gen_movl_reg_T0(rs1);
if (IS_IMM) { /* immediate */
rs2 = GET_FIELDs(insn, 20, 31);
- gen_movl_simm_T1(rs2);
+ if (insn & (1 << 12)) {
+ tcg_gen_shli_i64(cpu_T[0], cpu_T[0], rs2 & 0x3f);
+ } else {
+ tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffff);
+ tcg_gen_shli_i32(cpu_T[0], cpu_T[0], rs2 & 0x1f);
+ }
} else { /* register */
rs2 = GET_FIELD(insn, 27, 31);
gen_movl_reg_T1(rs2);
+ if (insn & (1 << 12)) {
+ tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x3f);
+ tcg_gen_shl_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
+ } else {
+ tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x1f);
+ tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffff);
+ tcg_gen_shl_i32(cpu_T[0], cpu_T[0], cpu_T[1]);
+ }
}
- if (insn & (1 << 12))
- gen_op_sllx();
- else
- gen_op_sll();
gen_movl_T0_reg(rd);
} else if (xop == 0x26) { /* srl, V9 srlx */
rs1 = GET_FIELD(insn, 13, 17);
gen_movl_reg_T0(rs1);
if (IS_IMM) { /* immediate */
rs2 = GET_FIELDs(insn, 20, 31);
- gen_movl_simm_T1(rs2);
+ if (insn & (1 << 12)) {
+ tcg_gen_shri_i64(cpu_T[0], cpu_T[0], rs2 & 0x3f);
+ } else {
+ tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffff);
+ tcg_gen_shri_i32(cpu_T[0], cpu_T[0], rs2 & 0x1f);
+ }
} else { /* register */
rs2 = GET_FIELD(insn, 27, 31);
gen_movl_reg_T1(rs2);
+ if (insn & (1 << 12)) {
+ tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x3f);
+ tcg_gen_shr_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
+ } else {
+ tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x1f);
+ tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffff);
+ tcg_gen_shr_i32(cpu_T[0], cpu_T[0], cpu_T[1]);
+ }
}
- if (insn & (1 << 12))
- gen_op_srlx();
- else
- gen_op_srl();
gen_movl_T0_reg(rd);
} else if (xop == 0x27) { /* sra, V9 srax */
rs1 = GET_FIELD(insn, 13, 17);
gen_movl_reg_T0(rs1);
if (IS_IMM) { /* immediate */
rs2 = GET_FIELDs(insn, 20, 31);
- gen_movl_simm_T1(rs2);
+ if (insn & (1 << 12)) {
+ tcg_gen_sari_i64(cpu_T[0], cpu_T[0], rs2 & 0x3f);
+ } else {
+ tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffff);
+ tcg_gen_sari_i32(cpu_T[0], cpu_T[0], rs2 & 0x1f);
+ }
} else { /* register */
rs2 = GET_FIELD(insn, 27, 31);
gen_movl_reg_T1(rs2);
+ if (insn & (1 << 12)) {
+ tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x3f);
+ tcg_gen_sar_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
+ } else {
+ tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x1f);
+ tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffff);
+ tcg_gen_sar_i32(cpu_T[0], cpu_T[0], cpu_T[1]);
+ }
}
- if (insn & (1 << 12))
- gen_op_srax();
- else
- gen_op_sra();
gen_movl_T0_reg(rd);
#endif
} else if (xop < 0x36) {
@@ -2173,17 +2132,17 @@
gen_op_add_T1_T0();
break;
case 0x1:
- gen_op_and_T1_T0();
+ tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
if (xop & 0x10)
gen_op_logic_T0_cc();
break;
case 0x2:
- gen_op_or_T1_T0();
+ tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
if (xop & 0x10)
gen_op_logic_T0_cc();
break;
case 0x3:
- gen_op_xor_T1_T0();
+ tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
if (xop & 0x10)
gen_op_logic_T0_cc();
break;
@@ -2191,7 +2150,7 @@
if (xop & 0x10)
gen_op_sub_T1_T0_cc();
else
- gen_op_sub_T1_T0();
+ tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
break;
case 0x5:
gen_op_andn_T1_T0();
@@ -2216,7 +2175,7 @@
break;
#ifdef TARGET_SPARC64
case 0x9: /* V9 mulx */
- gen_op_mulx_T1_T0();
+ tcg_gen_mul_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
break;
#endif
case 0xa:
@@ -2280,15 +2239,18 @@
break;
#ifndef TARGET_SPARC64
case 0x25: /* sll */
- gen_op_sll();
+ tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0x1f);
+ tcg_gen_shl_i32(cpu_T[0], cpu_T[0], cpu_T[1]);
gen_movl_T0_reg(rd);
break;
case 0x26: /* srl */
- gen_op_srl();
+ tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0x1f);
+ tcg_gen_shr_i32(cpu_T[0], cpu_T[0], cpu_T[1]);
gen_movl_T0_reg(rd);
break;
case 0x27: /* sra */
- gen_op_sra();
+ tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0x1f);
+ tcg_gen_sar_i32(cpu_T[0], cpu_T[0], cpu_T[1]);
gen_movl_T0_reg(rd);
break;
#endif
@@ -2329,7 +2291,7 @@
case 0xf: /* V9 sir, nop if user */
#if !defined(CONFIG_USER_ONLY)
if (supervisor(dc))
- gen_op_sir();
+ ; // XXX
#endif
break;
case 0x13: /* Graphics Status */
@@ -2400,7 +2362,7 @@
}
#else
gen_op_xor_T1_T0();
- gen_op_wrpsr();
+ tcg_gen_helper_0_1(helper_wrpsr, cpu_T[0]);
save_state(dc);
gen_op_next_insn();
tcg_gen_exit_tb(0);
@@ -2434,8 +2396,8 @@
gen_op_movtl_env_T0(offsetof(CPUSPARCState, tbr));
break;
case 6: // pstate
- gen_op_wrpstate();
save_state(dc);
+ tcg_gen_helper_0_1(helper_wrpstate, cpu_T[0]);
gen_op_next_insn();
tcg_gen_exit_tb(0);
dc->is_br = 1;
@@ -2476,7 +2438,8 @@
goto illegal_insn;
}
#else
- gen_op_wrwim();
+ tcg_gen_andi_i32(cpu_T[0], cpu_T[0], ((1 << NWINDOWS) - 1));
+ gen_op_movl_env_T0(offsetof(CPUSPARCState, wim));
#endif
}
break;
@@ -2564,7 +2527,8 @@
rs2 = GET_FIELD_SP(insn, 0, 4);
gen_movl_reg_T1(rs2);
}
- gen_op_popc();
+ tcg_gen_helper_1_1(helper_popc, cpu_T[0],
+ cpu_T[1]);
gen_movl_T0_reg(rd);
}
case 0x2f: /* V9 movr */
@@ -3003,14 +2967,7 @@
gen_movl_reg_T0(rs1);
if (IS_IMM) { /* immediate */
rs2 = GET_FIELDs(insn, 19, 31);
-#if defined(OPTIM)
- if (rs2) {
-#endif
- gen_movl_simm_T1(rs2);
- gen_op_add_T1_T0();
-#if defined(OPTIM)
- }
-#endif
+ tcg_gen_addi_tl(cpu_T[0], cpu_T[0], rs2);
} else { /* register */
rs2 = GET_FIELD(insn, 27, 31);
#if defined(OPTIM)
@@ -3025,7 +2982,7 @@
gen_op_restore();
gen_mov_pc_npc(dc);
gen_op_check_align_T0_3();
- gen_op_movl_npc_T0();
+ tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUSPARCState, npc));
dc->npc = DYNAMIC_PC;
goto jmp_insn;
#endif
@@ -3034,14 +2991,7 @@
gen_movl_reg_T0(rs1);
if (IS_IMM) { /* immediate */
rs2 = GET_FIELDs(insn, 19, 31);
-#if defined(OPTIM)
- if (rs2) {
-#endif
- gen_movl_simm_T1(rs2);
- gen_op_add_T1_T0();
-#if defined(OPTIM)
- }
-#endif
+ tcg_gen_addi_tl(cpu_T[0], cpu_T[0], rs2);
} else { /* register */
rs2 = GET_FIELD(insn, 27, 31);
#if defined(OPTIM)
@@ -3057,20 +3007,12 @@
case 0x38: /* jmpl */
{
if (rd != 0) {
-#ifdef TARGET_SPARC64
- if (dc->pc == (uint32_t)dc->pc) {
- gen_op_movl_T1_im(dc->pc);
- } else {
- gen_op_movq_T1_im64(dc->pc >> 32, dc->pc);
- }
-#else
- gen_op_movl_T1_im(dc->pc);
-#endif
+ tcg_gen_movi_tl(cpu_T[1], dc->pc);
gen_movl_T1_reg(rd);
}
gen_mov_pc_npc(dc);
gen_op_check_align_T0_3();
- gen_op_movl_npc_T0();
+ tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUSPARCState, npc));
dc->npc = DYNAMIC_PC;
}
goto jmp_insn;
@@ -3081,14 +3023,14 @@
goto priv_insn;
gen_mov_pc_npc(dc);
gen_op_check_align_T0_3();
- gen_op_movl_npc_T0();
+ tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUSPARCState, npc));
dc->npc = DYNAMIC_PC;
- gen_op_rett();
+ tcg_gen_helper_0_0(helper_rett);
}
goto jmp_insn;
#endif
case 0x3b: /* flush */
- gen_op_flush_T0();
+ tcg_gen_helper_0_1(helper_flush, cpu_T[0]);
break;
case 0x3c: /* save */
save_state(dc);
@@ -3109,14 +3051,14 @@
goto priv_insn;
dc->npc = DYNAMIC_PC;
dc->pc = DYNAMIC_PC;
- gen_op_done();
+ tcg_gen_helper_0_0(helper_done);
goto jmp_insn;
case 1:
if (!supervisor(dc))
goto priv_insn;
dc->npc = DYNAMIC_PC;
dc->pc = DYNAMIC_PC;
- gen_op_retry();
+ tcg_gen_helper_0_0(helper_retry);
goto jmp_insn;
default:
goto illegal_insn;
@@ -3144,14 +3086,7 @@
}
else if (IS_IMM) { /* immediate */
rs2 = GET_FIELDs(insn, 19, 31);
-#if defined(OPTIM)
- if (rs2 != 0) {
-#endif
- gen_movl_simm_T1(rs2);
- gen_op_add_T1_T0();
-#if defined(OPTIM)
- }
-#endif
+ tcg_gen_addi_tl(cpu_T[0], cpu_T[0], rs2);
} else { /* register */
rs2 = GET_FIELD(insn, 27, 31);
#if defined(OPTIM)
@@ -3167,42 +3102,58 @@
(xop > 0x17 && xop <= 0x1d ) ||
(xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) {
switch (xop) {
- case 0x0: /* load word */
+ case 0x0: /* load unsigned word */
gen_op_check_align_T0_3();
-#ifndef TARGET_SPARC64
- gen_op_ldst(ld);
-#else
- gen_op_ldst(lduw);
-#endif
+ ABI32_MASK(cpu_T[0]);
+ tcg_gen_qemu_ld32u(cpu_T[1], cpu_T[0], dc->mem_idx);
break;
case 0x1: /* load unsigned byte */
- gen_op_ldst(ldub);
+ ABI32_MASK(cpu_T[0]);
+ tcg_gen_qemu_ld8u(cpu_T[1], cpu_T[0], dc->mem_idx);
break;
case 0x2: /* load unsigned halfword */
gen_op_check_align_T0_1();
- gen_op_ldst(lduh);
+ ABI32_MASK(cpu_T[0]);
+ tcg_gen_qemu_ld16u(cpu_T[1], cpu_T[0], dc->mem_idx);
break;
case 0x3: /* load double word */
if (rd & 1)
goto illegal_insn;
- gen_op_check_align_T0_7();
- gen_op_ldst(ldd);
- gen_movl_T0_reg(rd + 1);
+ else {
+ TCGv r_dword;
+
+ r_dword = tcg_temp_new(TCG_TYPE_I64);
+ gen_op_check_align_T0_7();
+ ABI32_MASK(cpu_T[0]);
+ tcg_gen_qemu_ld64(r_dword, cpu_T[0], dc->mem_idx);
+ tcg_gen_trunc_i64_i32(cpu_T[0], r_dword);
+ gen_movl_T0_reg(rd + 1);
+ tcg_gen_shri_i64(r_dword, r_dword, 32);
+ tcg_gen_trunc_i64_i32(cpu_T[1], r_dword);
+ }
break;
case 0x9: /* load signed byte */
- gen_op_ldst(ldsb);
+ ABI32_MASK(cpu_T[0]);
+ tcg_gen_qemu_ld8s(cpu_T[1], cpu_T[0], dc->mem_idx);
break;
case 0xa: /* load signed halfword */
gen_op_check_align_T0_1();
- gen_op_ldst(ldsh);
+ ABI32_MASK(cpu_T[0]);
+ tcg_gen_qemu_ld16s(cpu_T[1], cpu_T[0], dc->mem_idx);
break;
case 0xd: /* ldstub -- XXX: should be atomically */
- gen_op_ldst(ldstub);
+ tcg_gen_movi_i32(cpu_tmp0, 0xff);
+ ABI32_MASK(cpu_T[0]);
+ tcg_gen_qemu_ld8s(cpu_T[1], cpu_T[0], dc->mem_idx);
+ tcg_gen_qemu_st8(cpu_tmp0, cpu_T[0], dc->mem_idx);
break;
case 0x0f: /* swap register with memory. Also atomically */
gen_op_check_align_T0_3();
gen_movl_reg_T1(rd);
- gen_op_ldst(swap);
+ ABI32_MASK(cpu_T[0]);
+ tcg_gen_qemu_ld32u(cpu_tmp0, cpu_T[0], dc->mem_idx);
+ tcg_gen_qemu_st32(cpu_T[1], cpu_T[0], dc->mem_idx);
+ tcg_gen_mov_i32(cpu_T[1], cpu_tmp0);
break;
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
case 0x10: /* load word alternate */
@@ -3297,11 +3248,13 @@
#ifdef TARGET_SPARC64
case 0x08: /* V9 ldsw */
gen_op_check_align_T0_3();
- gen_op_ldst(ldsw);
+ ABI32_MASK(cpu_T[0]);
+ tcg_gen_qemu_ld32s(cpu_T[1], cpu_T[0], dc->mem_idx);
break;
case 0x0b: /* V9 ldx */
gen_op_check_align_T0_7();
- gen_op_ldst(ldx);
+ ABI32_MASK(cpu_T[0]);
+ tcg_gen_qemu_ld64(cpu_T[1], cpu_T[0], dc->mem_idx);
break;
case 0x18: /* V9 ldswa */
gen_op_check_align_T0_3();
@@ -3374,27 +3327,37 @@
xop == 0xe || xop == 0x1e) {
gen_movl_reg_T1(rd);
switch (xop) {
- case 0x4:
+ case 0x4: /* store word */
gen_op_check_align_T0_3();
- gen_op_ldst(st);
+ ABI32_MASK(cpu_T[0]);
+ tcg_gen_qemu_st32(cpu_T[1], cpu_T[0], dc->mem_idx);
break;
- case 0x5:
- gen_op_ldst(stb);
+ case 0x5: /* store byte */
+ ABI32_MASK(cpu_T[0]);
+ tcg_gen_qemu_st8(cpu_T[1], cpu_T[0], dc->mem_idx);
break;
- case 0x6:
+ case 0x6: /* store halfword */
gen_op_check_align_T0_1();
- gen_op_ldst(sth);
+ ABI32_MASK(cpu_T[0]);
+ tcg_gen_qemu_st16(cpu_T[1], cpu_T[0], dc->mem_idx);
break;
- case 0x7:
+ case 0x7: /* store double word */
if (rd & 1)
goto illegal_insn;
- gen_op_check_align_T0_7();
- flush_T2(dc);
- gen_movl_reg_T2(rd + 1);
- gen_op_ldst(std);
+ else {
+ TCGv r_dword, r_low;
+
+ gen_op_check_align_T0_7();
+ r_dword = tcg_temp_new(TCG_TYPE_I64);
+ r_low = tcg_temp_new(TCG_TYPE_I32);
+ gen_movl_reg_TN(rd + 1, r_low);
+ tcg_gen_helper_1_2(helper_pack64, r_dword, cpu_T[1],
+ r_low);
+ tcg_gen_qemu_st64(r_dword, cpu_T[0], dc->mem_idx);
+ }
break;
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
- case 0x14:
+ case 0x14: /* store word alternate */
#ifndef TARGET_SPARC64
if (IS_IMM)
goto illegal_insn;
@@ -3404,7 +3367,7 @@
gen_op_check_align_T0_3();
gen_st_asi(insn, 4);
break;
- case 0x15:
+ case 0x15: /* store byte alternate */
#ifndef TARGET_SPARC64
if (IS_IMM)
goto illegal_insn;
@@ -3413,7 +3376,7 @@
#endif
gen_st_asi(insn, 1);
break;
- case 0x16:
+ case 0x16: /* store halfword alternate */
#ifndef TARGET_SPARC64
if (IS_IMM)
goto illegal_insn;
@@ -3423,7 +3386,7 @@
gen_op_check_align_T0_1();
gen_st_asi(insn, 2);
break;
- case 0x17:
+ case 0x17: /* store double word alternate */
#ifndef TARGET_SPARC64
if (IS_IMM)
goto illegal_insn;
@@ -3432,16 +3395,41 @@
#endif
if (rd & 1)
goto illegal_insn;
- gen_op_check_align_T0_7();
- flush_T2(dc);
- gen_movl_reg_T2(rd + 1);
- gen_stda_asi(insn);
+ else {
+ int asi;
+ TCGv r_dword, r_temp, r_size;
+
+ gen_op_check_align_T0_7();
+ r_dword = tcg_temp_new(TCG_TYPE_I64);
+ r_temp = tcg_temp_new(TCG_TYPE_I32);
+ r_size = tcg_temp_new(TCG_TYPE_I32);
+ gen_movl_reg_TN(rd + 1, r_temp);
+ tcg_gen_helper_1_2(helper_pack64, r_dword, cpu_T[1],
+ r_temp);
+#ifdef TARGET_SPARC64
+ if (IS_IMM) {
+ int offset;
+
+ offset = GET_FIELD(insn, 25, 31);
+ tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
+ tcg_gen_ld_i32(r_dword, cpu_env, offsetof(CPUSPARCState, asi));
+ } else {
+#endif
+ asi = GET_FIELD(insn, 19, 26);
+ tcg_gen_movi_i32(r_temp, asi);
+#ifdef TARGET_SPARC64
+ }
+#endif
+ tcg_gen_movi_i32(r_size, 8);
+ tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], r_dword, r_temp, r_size);
+ }
break;
#endif
#ifdef TARGET_SPARC64
case 0x0e: /* V9 stx */
gen_op_check_align_T0_7();
- gen_op_ldst(stx);
+ ABI32_MASK(cpu_T[0]);
+ tcg_gen_qemu_st64(cpu_T[1], cpu_T[0], dc->mem_idx);
break;
case 0x1e: /* V9 stxa */
gen_op_check_align_T0_7();
@@ -3522,16 +3510,12 @@
break;
case 0x3c: /* V9 casa */
gen_op_check_align_T0_3();
- flush_T2(dc);
- gen_movl_reg_T2(rd);
- gen_cas_asi(insn);
+ gen_cas_asi(insn, rd);
gen_movl_T1_reg(rd);
break;
case 0x3e: /* V9 casxa */
gen_op_check_align_T0_7();
- flush_T2(dc);
- gen_movl_reg_T2(rd);
- gen_casx_asi(insn);
+ gen_casx_asi(insn, rd);
gen_movl_T1_reg(rd);
break;
#else
@@ -3597,6 +3581,10 @@
#endif
}
+static void tcg_macro_func(TCGContext *s, int macro_id, const int *dead_args)
+{
+}
+
static inline int gen_intermediate_code_internal(TranslationBlock * tb,
int spc, CPUSPARCState *env)
{
@@ -3615,13 +3603,16 @@
dc->fpu_enabled = cpu_fpu_enabled(env);
gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
+ cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
+ cpu_regwptr = tcg_temp_new(TCG_TYPE_PTR); // XXX
+
do {
if (env->nb_breakpoints > 0) {
for(j = 0; j < env->nb_breakpoints; j++) {
if (env->breakpoints[j] == dc->pc) {
if (dc->pc != pc_start)
save_state(dc);
- gen_op_debug();
+ tcg_gen_helper_0_0(helper_debug);
tcg_gen_exit_tb(0);
dc->is_br = 1;
goto exit_gen_loop;
@@ -3748,6 +3739,7 @@
{
CPUSPARCState *env;
const sparc_def_t *def;
+ static int inited;
def = cpu_sparc_find_by_name(cpu_model);
if (!def)
@@ -3769,6 +3761,28 @@
env->mmuregs[0] |= def->mmu_version;
cpu_sparc_set_id(env, 0);
#endif
+
+ /* init various static tables */
+ if (!inited) {
+ inited = 1;
+
+ tcg_set_macro_func(&tcg_ctx, tcg_macro_func);
+ cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
+ //#if TARGET_LONG_BITS > HOST_LONG_BITS
+#ifdef TARGET_SPARC64
+ cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
+ TCG_AREG0, offsetof(CPUState, t0), "T0");
+ cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
+ TCG_AREG0, offsetof(CPUState, t1), "T1");
+ cpu_T[2] = tcg_global_mem_new(TCG_TYPE_TL,
+ TCG_AREG0, offsetof(CPUState, t2), "T2");
+#else
+ cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
+ cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
+ cpu_T[2] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "T2");
+#endif
+ }
+
cpu_reset(env);
return env;
Index: qemu/target-sparc/op.c
===================================================================
--- qemu.orig/target-sparc/op.c 2008-02-22 16:16:21.000000000 +0000
+++ qemu/target-sparc/op.c 2008-02-23 16:47:29.000000000 +0000
@@ -19,104 +19,7 @@
*/
#include "exec.h"
-
- /*XXX*/
-#define REGNAME g0
-#define REG (env->gregs[0])
-#include "op_template.h"
-#define REGNAME g1
-#define REG (env->gregs[1])
-#include "op_template.h"
-#define REGNAME g2
-#define REG (env->gregs[2])
-#include "op_template.h"
-#define REGNAME g3
-#define REG (env->gregs[3])
-#include "op_template.h"
-#define REGNAME g4
-#define REG (env->gregs[4])
-#include "op_template.h"
-#define REGNAME g5
-#define REG (env->gregs[5])
-#include "op_template.h"
-#define REGNAME g6
-#define REG (env->gregs[6])
-#include "op_template.h"
-#define REGNAME g7
-#define REG (env->gregs[7])
-#include "op_template.h"
-#define REGNAME i0
-#define REG (REGWPTR[16])
-#include "op_template.h"
-#define REGNAME i1
-#define REG (REGWPTR[17])
-#include "op_template.h"
-#define REGNAME i2
-#define REG (REGWPTR[18])
-#include "op_template.h"
-#define REGNAME i3
-#define REG (REGWPTR[19])
-#include "op_template.h"
-#define REGNAME i4
-#define REG (REGWPTR[20])
-#include "op_template.h"
-#define REGNAME i5
-#define REG (REGWPTR[21])
-#include "op_template.h"
-#define REGNAME i6
-#define REG (REGWPTR[22])
-#include "op_template.h"
-#define REGNAME i7
-#define REG (REGWPTR[23])
-#include "op_template.h"
-#define REGNAME l0
-#define REG (REGWPTR[8])
-#include "op_template.h"
-#define REGNAME l1
-#define REG (REGWPTR[9])
-#include "op_template.h"
-#define REGNAME l2
-#define REG (REGWPTR[10])
-#include "op_template.h"
-#define REGNAME l3
-#define REG (REGWPTR[11])
-#include "op_template.h"
-#define REGNAME l4
-#define REG (REGWPTR[12])
-#include "op_template.h"
-#define REGNAME l5
-#define REG (REGWPTR[13])
-#include "op_template.h"
-#define REGNAME l6
-#define REG (REGWPTR[14])
-#include "op_template.h"
-#define REGNAME l7
-#define REG (REGWPTR[15])
-#include "op_template.h"
-#define REGNAME o0
-#define REG (REGWPTR[0])
-#include "op_template.h"
-#define REGNAME o1
-#define REG (REGWPTR[1])
-#include "op_template.h"
-#define REGNAME o2
-#define REG (REGWPTR[2])
-#include "op_template.h"
-#define REGNAME o3
-#define REG (REGWPTR[3])
-#include "op_template.h"
-#define REGNAME o4
-#define REG (REGWPTR[4])
-#include "op_template.h"
-#define REGNAME o5
-#define REG (REGWPTR[5])
-#include "op_template.h"
-#define REGNAME o6
-#define REG (REGWPTR[6])
-#include "op_template.h"
-#define REGNAME o7
-#define REG (REGWPTR[7])
-#include "op_template.h"
+#include "helper.h"
#define REGNAME f0
#define REG (env->fpr[0])
@@ -267,106 +170,11 @@
#endif
#ifdef TARGET_SPARC64
-#ifdef WORDS_BIGENDIAN
-typedef union UREG64 {
- struct { uint16_t v3, v2, v1, v0; } w;
- struct { uint32_t v1, v0; } l;
- uint64_t q;
-} UREG64;
-#else
-typedef union UREG64 {
- struct { uint16_t v0, v1, v2, v3; } w;
- struct { uint32_t v0, v1; } l;
- uint64_t q;
-} UREG64;
-#endif
-
-#define PARAMQ1 \
-({\
- UREG64 __p;\
- __p.l.v1 = PARAM1;\
- __p.l.v0 = PARAM2;\
- __p.q;\
-})
-
-void OPPROTO op_movq_T0_im64(void)
-{
- T0 = PARAMQ1;
-}
-
-void OPPROTO op_movq_T1_im64(void)
-{
- T1 = PARAMQ1;
-}
-
#define XFLAG_SET(x) ((env->xcc&x)?1:0)
-
-#else
-#define EIP (env->pc)
#endif
#define FLAG_SET(x) ((env->psr&x)?1:0)
-void OPPROTO op_movl_T0_0(void)
-{
- T0 = 0;
-}
-
-void OPPROTO op_movl_T0_im(void)
-{
- T0 = (uint32_t)PARAM1;
-}
-
-void OPPROTO op_movl_T1_im(void)
-{
- T1 = (uint32_t)PARAM1;
-}
-
-void OPPROTO op_movl_T2_im(void)
-{
- T2 = (uint32_t)PARAM1;
-}
-
-void OPPROTO op_movl_T0_sim(void)
-{
- T0 = (int32_t)PARAM1;
-}
-
-void OPPROTO op_movl_T1_sim(void)
-{
- T1 = (int32_t)PARAM1;
-}
-
-void OPPROTO op_movl_T2_sim(void)
-{
- T2 = (int32_t)PARAM1;
-}
-
-void OPPROTO op_movl_T0_env(void)
-{
- T0 = *(uint32_t *)((char *)env + PARAM1);
-}
-
-void OPPROTO op_movl_env_T0(void)
-{
- *(uint32_t *)((char *)env + PARAM1) = T0;
-}
-
-void OPPROTO op_movtl_T0_env(void)
-{
- T0 = *(target_ulong *)((char *)env + PARAM1);
-}
-
-void OPPROTO op_movtl_env_T0(void)
-{
- *(target_ulong *)((char *)env + PARAM1) = T0;
-}
-
-void OPPROTO op_add_T1_T0(void)
-{
- T0 += T1;
-}
-
void OPPROTO op_add_T1_T0_cc(void)
{
target_ulong src1;
@@ -565,11 +373,6 @@
FORCE_RET();
}
-void OPPROTO op_sub_T1_T0(void)
-{
- T0 -= T1;
-}
-
void OPPROTO op_sub_T1_T0_cc(void)
{
target_ulong src1;
@@ -765,21 +568,6 @@
FORCE_RET();
}
-void OPPROTO op_and_T1_T0(void)
-{
- T0 &= T1;
-}
-
-void OPPROTO op_or_T1_T0(void)
-{
- T0 |= T1;
-}
-
-void OPPROTO op_xor_T1_T0(void)
-{
- T0 ^= T1;
-}
-
void OPPROTO op_andn_T1_T0(void)
{
T0 &= ~T1;
@@ -921,12 +709,6 @@
}
#ifdef TARGET_SPARC64
-void OPPROTO op_mulx_T1_T0(void)
-{
- T0 *= T1;
- FORCE_RET();
-}
-
void OPPROTO op_udivx_T1_T0(void)
{
if (T1 == 0) {
@@ -972,48 +754,6 @@
FORCE_RET();
}
-void OPPROTO op_sll(void)
-{
- T0 <<= (T1 & 0x1f);
-}
-
-#ifdef TARGET_SPARC64
-void OPPROTO op_sllx(void)
-{
- T0 <<= (T1 & 0x3f);
-}
-
-void OPPROTO op_srl(void)
-{
- T0 = (T0 & 0xffffffff) >> (T1 & 0x1f);
-}
-
-void OPPROTO op_srlx(void)
-{
- T0 >>= (T1 & 0x3f);
-}
-
-void OPPROTO op_sra(void)
-{
- T0 = ((int32_t) (T0 & 0xffffffff)) >> (T1 & 0x1f);
-}
-
-void OPPROTO op_srax(void)
-{
- T0 = ((int64_t) T0) >> (T1 & 0x3f);
-}
-#else
-void OPPROTO op_srl(void)
-{
- T0 >>= (T1 & 0x1f);
-}
-
-void OPPROTO op_sra(void)
-{
- T0 = ((int32_t) T0) >> (T1 & 0x1f);
-}
-#endif
-
/* Load and store */
#define MEMSUFFIX _raw
#include "op_mem.h"
@@ -1042,32 +782,6 @@
}
#ifndef TARGET_SPARC64
-void OPPROTO op_rdpsr(void)
-{
- do_rdpsr();
-}
-
-void OPPROTO op_wrpsr(void)
-{
- do_wrpsr();
- FORCE_RET();
-}
-
-void OPPROTO op_wrwim(void)
-{
-#if NWINDOWS == 32
- env->wim = T0;
-#else
- env->wim = T0 & ((1 << NWINDOWS) - 1);
-#endif
-}
-
-void OPPROTO op_rett(void)
-{
- helper_rett();
- FORCE_RET();
-}
-
/* XXX: use another pointer for %iN registers to avoid slow wrapping
handling ? */
void OPPROTO op_save(void)
@@ -1178,16 +892,6 @@
env->tt[env->tl] = T0;
}
-void OPPROTO op_rdpstate(void)
-{
- T0 = env->pstate;
-}
-
-void OPPROTO op_wrpstate(void)
-{
- do_wrpstate();
-}
-
// CWP handling is reversed in V9, but we still use the V8 register
// order.
void OPPROTO op_rdcwp(void)
@@ -1247,22 +951,6 @@
FORCE_RET();
}
-void OPPROTO op_trap_T0(void)
-{
- env->exception_index = TT_TRAP + (T0 & 0x7f);
- cpu_loop_exit();
- FORCE_RET();
-}
-
-void OPPROTO op_trapcc_T0(void)
-{
- if (T2) {
- env->exception_index = TT_TRAP + (T0 & 0x7f);
- cpu_loop_exit();
- }
- FORCE_RET();
-}
-
void OPPROTO op_fpexception_im(void)
{
env->exception_index = TT_FP_EXCP;
@@ -1272,11 +960,6 @@
FORCE_RET();
}
-void OPPROTO op_debug(void)
-{
- helper_debug();
-}
-
void OPPROTO op_eval_ba(void)
{
T2 = 1;
@@ -1499,33 +1182,8 @@
{
T2 = ((int64_t)T0 >= 0);
}
-
-void OPPROTO op_jmp_im64(void)
-{
- env->pc = PARAMQ1;
-}
-
-void OPPROTO op_movq_npc_im64(void)
-{
- env->npc = PARAMQ1;
-}
#endif
-void OPPROTO op_jmp_im(void)
-{
- env->pc = (uint32_t)PARAM1;
-}
-
-void OPPROTO op_movl_npc_im(void)
-{
- env->npc = (uint32_t)PARAM1;
-}
-
-void OPPROTO op_movl_npc_T0(void)
-{
- env->npc = T0;
-}
-
void OPPROTO op_mov_pc_npc(void)
{
env->pc = env->npc;
@@ -1556,11 +1214,6 @@
FORCE_RET();
}
-void OPPROTO op_flush_T0(void)
-{
- helper_flush(T0);
-}
-
void OPPROTO op_clear_ieee_excp_and_FTT(void)
{
env->fsr &= ~(FSR_FTT_MASK | FSR_CEXC_MASK);;
@@ -1993,210 +1646,6 @@
env->otherwin--;
FORCE_RET();
}
-
-void OPPROTO op_popc(void)
-{
- do_popc();
-}
-
-void OPPROTO op_done(void)
-{
- do_done();
-}
-
-void OPPROTO op_retry(void)
-{
- do_retry();
-}
-
-void OPPROTO op_sir(void)
-{
- T0 = 0; // XXX
-}
-
-void OPPROTO op_ld_asi_reg()
-{
- T0 += PARAM1;
- helper_ld_asi(env->asi, PARAM2, PARAM3);
-}
-
-void OPPROTO op_st_asi_reg()
-{
- T0 += PARAM1;
- helper_st_asi(env->asi, PARAM2);
-}
-
-void OPPROTO op_ldf_asi_reg()
-{
- T0 += PARAM1;
- helper_ldf_asi(env->asi, PARAM2, PARAM3);
-}
-
-void OPPROTO op_stf_asi_reg()
-{
- T0 += PARAM1;
- helper_stf_asi(env->asi, PARAM2, PARAM3);
-}
-
-void OPPROTO op_ldf_asi()
-{
- helper_ldf_asi(PARAM1, PARAM2, PARAM3);
-}
-
-void OPPROTO op_stf_asi()
-{
- helper_stf_asi(PARAM1, PARAM2, PARAM3);
-}
-
-void OPPROTO op_ldstub_asi_reg() /* XXX: should be atomically */
-{
- target_ulong tmp;
-
- T0 += PARAM1;
- helper_ld_asi(env->asi, 1, 0);
- tmp = T1;
- T1 = 0xff;
- helper_st_asi(env->asi, 1);
- T1 = tmp;
-}
-
-void OPPROTO op_swap_asi_reg() /* XXX: should be atomically */
-{
- target_ulong tmp1, tmp2;
-
- T0 += PARAM1;
- tmp1 = T1;
- helper_ld_asi(env->asi, 4, 0);
- tmp2 = T1;
- T1 = tmp1;
- helper_st_asi(env->asi, 4);
- T1 = tmp2;
-}
-
-void OPPROTO op_ldda_asi()
-{
- helper_ld_asi(PARAM1, 8, 0);
- T0 = T1 & 0xffffffffUL;
- T1 >>= 32;
-}
-
-void OPPROTO op_ldda_asi_reg()
-{
- T0 += PARAM1;
- helper_ld_asi(env->asi, 8, 0);
- T0 = T1 & 0xffffffffUL;
- T1 >>= 32;
-}
-
-void OPPROTO op_stda_asi()
-{
- T1 <<= 32;
- T1 += T2 & 0xffffffffUL;
- helper_st_asi(PARAM1, 8);
-}
-
-void OPPROTO op_stda_asi_reg()
-{
- T0 += PARAM1;
- T1 <<= 32;
- T1 += T2 & 0xffffffffUL;
- helper_st_asi(env->asi, 8);
-}
-
-void OPPROTO op_cas_asi() /* XXX: should be atomically */
-{
- target_ulong tmp;
-
- tmp = T1 & 0xffffffffUL;
- helper_ld_asi(PARAM1, 4, 0);
- if (tmp == T1) {
- tmp = T1;
- T1 = T2 & 0xffffffffUL;
- helper_st_asi(PARAM1, 4);
- T1 = tmp;
- }
- T1 &= 0xffffffffUL;
-}
-
-void OPPROTO op_cas_asi_reg() /* XXX: should be atomically */
-{
- target_ulong tmp;
-
- T0 += PARAM1;
- tmp = T1 & 0xffffffffUL;
- helper_ld_asi(env->asi, 4, 0);
- if (tmp == T1) {
- tmp = T1;
- T1 = T2 & 0xffffffffUL;
- helper_st_asi(env->asi, 4);
- T1 = tmp;
- }
- T1 &= 0xffffffffUL;
-}
-
-void OPPROTO op_casx_asi() /* XXX: should be atomically */
-{
- target_ulong tmp;
-
- tmp = T1;
- helper_ld_asi(PARAM1, 8, 0);
- if (tmp == T1) {
- tmp = T1;
- T1 = T2;
- helper_st_asi(PARAM1, 8);
- T1 = tmp;
- }
-}
-
-void OPPROTO op_casx_asi_reg() /* XXX: should be atomically */
-{
- target_ulong tmp;
-
- T0 += PARAM1;
- tmp = T1;
- helper_ld_asi(env->asi, 8, 0);
- if (tmp == T1) {
- tmp = T1;
- T1 = T2;
- helper_st_asi(env->asi, 8);
- T1 = tmp;
- }
-}
-#endif
-
-#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
-void OPPROTO op_ld_asi()
-{
- helper_ld_asi(PARAM1, PARAM2, PARAM3);
-}
-
-void OPPROTO op_st_asi()
-{
- helper_st_asi(PARAM1, PARAM2);
-}
-
-void OPPROTO op_ldstub_asi() /* XXX: should be atomically */
-{
- target_ulong tmp;
-
- helper_ld_asi(PARAM1, 1, 0);
- tmp = T1;
- T1 = 0xff;
- helper_st_asi(PARAM1, 1);
- T1 = tmp;
-}
-
-void OPPROTO op_swap_asi() /* XXX: should be atomically */
-{
- target_ulong tmp1, tmp2;
-
- tmp1 = T1;
- helper_ld_asi(PARAM1, 4, 0);
- tmp2 = T1;
- T1 = tmp1;
- helper_st_asi(PARAM1, 4);
- T1 = tmp2;
-}
#endif
#ifdef TARGET_SPARC64
Index: qemu/target-sparc/op_template.h
===================================================================
--- qemu.orig/target-sparc/op_template.h 2008-02-22 16:16:21.000000000 +0000
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,48 +0,0 @@
-/*
- * SPARC micro operations (templates for various register related
- * operations)
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-void OPPROTO glue(op_movl_T0_, REGNAME)(void)
-{
- T0 = REG;
-}
-
-void OPPROTO glue(op_movl_T1_, REGNAME)(void)
-{
- T1 = REG;
-}
-
-void OPPROTO glue(op_movl_T2_, REGNAME)(void)
-{
- T2 = REG;
-}
-
-void OPPROTO glue(glue(op_movl_, REGNAME), _T0)(void)
-{
- REG = T0;
-}
-
-void OPPROTO glue(glue(op_movl_, REGNAME), _T1)(void)
-{
- REG = T1;
-}
-
-#undef REG
-#undef REGNAME
Index: qemu/target-sparc/helper.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ qemu/target-sparc/helper.h 2008-02-23 15:34:18.000000000 +0000
@@ -0,0 +1,32 @@
+#define TCG_HELPER_PROTO
+
+#ifndef TARGET_SPARC64
+void TCG_HELPER_PROTO helper_rett(void);
+void TCG_HELPER_PROTO helper_wrpsr(target_ulong new_psr);
+target_ulong TCG_HELPER_PROTO helper_rdpsr(void);
+#else
+void TCG_HELPER_PROTO helper_wrpstate(target_ulong new_state);
+void TCG_HELPER_PROTO helper_done(void);
+void TCG_HELPER_PROTO helper_retry(void);
+target_ulong TCG_HELPER_PROTO helper_popc(target_ulong val);
+void TCG_HELPER_PROTO helper_ldf_asi(target_ulong addr, int asi, int size,
+ int rd);
+void TCG_HELPER_PROTO helper_stf_asi(target_ulong addr, int asi, int size,
+ int rd);
+target_ulong TCG_HELPER_PROTO
+helper_cas_asi(target_ulong addr, target_ulong val1,
+ target_ulong val2, uint32_t asi);
+target_ulong TCG_HELPER_PROTO
+helper_casx_asi(target_ulong addr, target_ulong val1,
+ target_ulong val2, uint32_t asi);
+#endif
+void TCG_HELPER_PROTO helper_trap(target_ulong nb_trap);
+void TCG_HELPER_PROTO helper_trapcc(target_ulong nb_trap,
+ target_ulong do_trap);
+void TCG_HELPER_PROTO helper_debug(void);
+void TCG_HELPER_PROTO helper_flush(target_ulong addr);
+uint64_t TCG_HELPER_PROTO helper_pack64(target_ulong high, target_ulong low);
+uint64_t TCG_HELPER_PROTO helper_ld_asi(target_ulong addr, int asi,
+ int size, int sign);
+void TCG_HELPER_PROTO helper_st_asi(target_ulong addr, uint64_t val, int asi,
+ int size);
Index: qemu/target-sparc/op_helper.c
===================================================================
--- qemu.orig/target-sparc/op_helper.c 2008-02-22 18:30:46.000000000 +0000
+++ qemu/target-sparc/op_helper.c 2008-02-23 16:01:45.000000000 +0000
@@ -1,7 +1,8 @@
#include "exec.h"
#include "host-utils.h"
+#include "helper.h"
-//#define DEBUG_PCALL
+#define DEBUG_PCALL
//#define DEBUG_MMU
//#define DEBUG_MXCC
//#define DEBUG_UNALIGNED
@@ -35,35 +36,47 @@
cpu_loop_exit();
}
-void check_ieee_exceptions()
+void helper_trap(target_ulong nb_trap)
{
- T0 = get_float_exception_flags(&env->fp_status);
- if (T0)
- {
+ env->exception_index = TT_TRAP + (nb_trap & 0x7f);
+ cpu_loop_exit();
+}
+
+void helper_trapcc(target_ulong nb_trap, target_ulong do_trap)
+{
+ if (do_trap) {
+ env->exception_index = TT_TRAP + (nb_trap & 0x7f);
+ cpu_loop_exit();
+ }
+}
+
+void check_ieee_exceptions(void)
+{
+ target_ulong status;
+
+ status = get_float_exception_flags(&env->fp_status);
+ if (status) {
/* Copy IEEE 754 flags into FSR */
- if (T0 & float_flag_invalid)
+ if (status & float_flag_invalid)
env->fsr |= FSR_NVC;
- if (T0 & float_flag_overflow)
+ if (status & float_flag_overflow)
env->fsr |= FSR_OFC;
- if (T0 & float_flag_underflow)
+ if (status & float_flag_underflow)
env->fsr |= FSR_UFC;
- if (T0 & float_flag_divbyzero)
+ if (status & float_flag_divbyzero)
env->fsr |= FSR_DZC;
- if (T0 & float_flag_inexact)
+ if (status & float_flag_inexact)
env->fsr |= FSR_NXC;
- if ((env->fsr & FSR_CEXC_MASK) & ((env->fsr & FSR_TEM_MASK) >> 23))
- {
+ if ((env->fsr & FSR_CEXC_MASK) & ((env->fsr & FSR_TEM_MASK) >> 23)) {
/* Unmasked exception, generate a trap */
env->fsr |= FSR_FTT_IEEE_EXCP;
raise_exception(TT_FP_EXCP);
- }
- else
- {
+ } else {
/* Accumulate exceptions */
env->fsr |= (env->fsr & FSR_CEXC_MASK) << 5;
}
- }
+ }
}
#ifdef USE_INT_TO_FLOAT_HELPERS
@@ -157,12 +170,14 @@
#define GEN_FCMP(name, size, reg1, reg2, FS, TRAP) \
void glue(do_, name) (void) \
{ \
+ target_ulong new_fsr; \
+ \
env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \
switch (glue(size, _compare) (reg1, reg2, &env->fp_status)) { \
case float_relation_unordered: \
- T0 = (FSR_FCC1 | FSR_FCC0) << FS; \
+ new_fsr = (FSR_FCC1 | FSR_FCC0) << FS; \
if ((env->fsr & FSR_NVM) || TRAP) { \
- env->fsr |= T0; \
+ env->fsr |= new_fsr; \
env->fsr |= FSR_NVC; \
env->fsr |= FSR_FTT_IEEE_EXCP; \
raise_exception(TT_FP_EXCP); \
@@ -171,16 +186,16 @@
} \
break; \
case float_relation_less: \
- T0 = FSR_FCC0 << FS; \
+ new_fsr = FSR_FCC0 << FS; \
break; \
case float_relation_greater: \
- T0 = FSR_FCC1 << FS; \
+ new_fsr = FSR_FCC1 << FS; \
break; \
default: \
- T0 = 0; \
+ new_fsr = 0; \
break; \
} \
- env->fsr |= T0; \
+ env->fsr |= new_fsr; \
}
GEN_FCMP(fcmps, float32, FT0, FT1, 0, 0);
@@ -222,10 +237,7 @@
#endif
#endif
-#ifndef TARGET_SPARC64
-#ifndef CONFIG_USER_ONLY
-
-#ifdef DEBUG_MXCC
+#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) && defined(DEBUG_MXCC)
static void dump_mxcc(CPUState *env)
{
printf("mxccdata: %016llx %016llx %016llx %016llx\n",
@@ -237,74 +249,76 @@
}
#endif
-#ifdef DEBUG_ASI
-static void dump_asi(const char * txt, uint32_t addr, int asi, int size,
- uint32_t r1, uint32_t r2)
+#if (defined(TARGET_SPARC64) || !defined(CONFIG_USER_ONLY)) \
+ && defined(DEBUG_ASI)
+static void dump_asi(const char *txt, target_ulong addr, int asi, int size,
+ uint64_t r1)
{
switch (size)
{
case 1:
- DPRINTF_ASI("%s %08x asi 0x%02x = %02x\n", txt, addr, asi, r1 & 0xff);
+ DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %02" PRIx64 "\n", txt,
+ addr, asi, r1 & 0xff);
break;
case 2:
- DPRINTF_ASI("%s %08x asi 0x%02x = %04x\n", txt, addr, asi, r1 & 0xffff);
+ DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %04" PRIx64 "\n", txt,
+ addr, asi, r1 & 0xffff);
break;
case 4:
- DPRINTF_ASI("%s %08x asi 0x%02x = %08x\n", txt, addr, asi, r1);
+ DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %08" PRIx64 "\n", txt,
+ addr, asi, r1 & 0xffffffff);
break;
case 8:
- DPRINTF_ASI("%s %08x asi 0x%02x = %016llx\n", txt, addr, asi,
- r2 | ((uint64_t)r1 << 32));
+ DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %016" PRIx64 "\n", txt,
+ addr, asi, r1);
break;
}
}
#endif
-void helper_ld_asi(int asi, int size, int sign)
+#ifndef TARGET_SPARC64
+#ifndef CONFIG_USER_ONLY
+uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
{
- uint32_t ret = 0;
- uint64_t tmp;
+ uint64_t ret = 0;
#if defined(DEBUG_MXCC) || defined(DEBUG_ASI)
- uint32_t last_T0 = T0;
+ uint32_t last_addr = addr;
#endif
switch (asi) {
case 2: /* SuperSparc MXCC registers */
- switch (T0) {
+ switch (addr) {
case 0x01c00a00: /* MXCC control register */
- if (size == 8) {
- ret = env->mxccregs[3] >> 32;
- T0 = env->mxccregs[3];
- } else
- DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
+ if (size == 8)
+ ret = env->mxccregs[3];
+ else
+ DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr, size);
break;
case 0x01c00a04: /* MXCC control register */
if (size == 4)
ret = env->mxccregs[3];
else
- DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
+ DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr, size);
break;
case 0x01c00c00: /* Module reset register */
if (size == 8) {
- ret = env->mxccregs[5] >> 32;
- T0 = env->mxccregs[5];
+ ret = env->mxccregs[5];
// should we do something here?
} else
- DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
+ DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr, size);
break;
case 0x01c00f00: /* MBus port address register */
- if (size == 8) {
- ret = env->mxccregs[7] >> 32;
- T0 = env->mxccregs[7];
- } else
- DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
+ if (size == 8)
+ ret = env->mxccregs[7];
+ else
+ DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr, size);
break;
default:
- DPRINTF_MXCC("%08x: unimplemented address, size: %d\n", T0, size);
+ DPRINTF_MXCC("%08x: unimplemented address, size: %d\n", addr, size);
break;
}
- DPRINTF_MXCC("asi = %d, size = %d, sign = %d, T0 = %08x -> ret = %08x,"
- "T0 = %08x\n", asi, size, sign, last_T0, ret, T0);
+ DPRINTF_MXCC("asi = %d, size = %d, sign = %d, addr = %08x -> ret = %08x,"
+ "addr = %08x\n", asi, size, sign, last_addr, ret, addr);
#ifdef DEBUG_MXCC
dump_mxcc(env);
#endif
@@ -313,19 +327,18 @@
{
int mmulev;
- mmulev = (T0 >> 8) & 15;
+ mmulev = (addr >> 8) & 15;
if (mmulev > 4)
ret = 0;
- else {
- ret = mmu_probe(env, T0, mmulev);
- //bswap32s(&ret);
- }
- DPRINTF_MMU("mmu_probe: 0x%08x (lev %d) -> 0x%08x\n", T0, mmulev, ret);
+ else
+ ret = mmu_probe(env, addr, mmulev);
+ DPRINTF_MMU("mmu_probe: 0x%08x (lev %d) -> 0x%08" PRIx64 "\n",
+ addr, mmulev, ret);
}
break;
case 4: /* read MMU regs */
{
- int reg = (T0 >> 8) & 0x1f;
+ int reg = (addr >> 8) & 0x1f;
ret = env->mmuregs[reg];
if (reg == 3) /* Fault status cleared on read */
@@ -334,7 +347,7 @@
ret = env->mmuregs[3];
else if (reg == 0x14) /* Fault address read */
ret = env->mmuregs[4];
- DPRINTF_MMU("mmu_read: reg[%d] = 0x%08x\n", reg, ret);
+ DPRINTF_MMU("mmu_read: reg[%d] = 0x%08" PRIx64 "\n", reg, ret);
}
break;
case 5: // Turbosparc ITLB Diagnostic
@@ -344,57 +357,51 @@
case 9: /* Supervisor code access */
switch(size) {
case 1:
- ret = ldub_code(T0);
+ ret = ldub_code(addr);
break;
case 2:
- ret = lduw_code(T0 & ~1);
+ ret = lduw_code(addr & ~1);
break;
default:
case 4:
- ret = ldl_code(T0 & ~3);
+ ret = ldl_code(addr & ~3);
break;
case 8:
- tmp = ldq_code(T0 & ~7);
- ret = tmp >> 32;
- T0 = tmp;
+ ret = ldq_code(addr & ~7);
break;
}
break;
case 0xa: /* User data access */
switch(size) {
case 1:
- ret = ldub_user(T0);
+ ret = ldub_user(addr);
break;
case 2:
- ret = lduw_user(T0 & ~1);
+ ret = lduw_user(addr & ~1);
break;
default:
case 4:
- ret = ldl_user(T0 & ~3);
+ ret = ldl_user(addr & ~3);
break;
case 8:
- tmp = ldq_user(T0 & ~7);
- ret = tmp >> 32;
- T0 = tmp;
+ ret = ldq_user(addr & ~7);
break;
}
break;
case 0xb: /* Supervisor data access */
switch(size) {
case 1:
- ret = ldub_kernel(T0);
+ ret = ldub_kernel(addr);
break;
case 2:
- ret = lduw_kernel(T0 & ~1);
+ ret = lduw_kernel(addr & ~1);
break;
default:
case 4:
- ret = ldl_kernel(T0 & ~3);
+ ret = ldl_kernel(addr & ~3);
break;
case 8:
- tmp = ldq_kernel(T0 & ~7);
- ret = tmp >> 32;
- T0 = tmp;
+ ret = ldq_kernel(addr & ~7);
break;
}
break;
@@ -406,42 +413,38 @@
case 0x20: /* MMU passthrough */
switch(size) {
case 1:
- ret = ldub_phys(T0);
+ ret = ldub_phys(addr);
break;
case 2:
- ret = lduw_phys(T0 & ~1);
+ ret = lduw_phys(addr & ~1);
break;
default:
case 4:
- ret = ldl_phys(T0 & ~3);
+ ret = ldl_phys(addr & ~3);
break;
case 8:
- tmp = ldq_phys(T0 & ~7);
- ret = tmp >> 32;
- T0 = tmp;
+ ret = ldq_phys(addr & ~7);
break;
}
break;
case 0x21 ... 0x2f: /* MMU passthrough, 0x100000000 to 0xfffffffff */
switch(size) {
case 1:
- ret = ldub_phys((target_phys_addr_t)T0
+ ret = ldub_phys((target_phys_addr_t)addr
| ((target_phys_addr_t)(asi & 0xf) << 32));
break;
case 2:
- ret = lduw_phys((target_phys_addr_t)(T0 & ~1)
+ ret = lduw_phys((target_phys_addr_t)(addr & ~1)
| ((target_phys_addr_t)(asi & 0xf) << 32));
break;
default:
case 4:
- ret = ldl_phys((target_phys_addr_t)(T0 & ~3)
+ ret = ldl_phys((target_phys_addr_t)(addr & ~3)
| ((target_phys_addr_t)(asi & 0xf) << 32));
break;
case 8:
- tmp = ldq_phys((target_phys_addr_t)(T0 & ~7)
+ ret = ldq_phys((target_phys_addr_t)(addr & ~7)
| ((target_phys_addr_t)(asi & 0xf) << 32));
- ret = tmp >> 32;
- T0 = tmp;
break;
}
break;
@@ -453,64 +456,65 @@
break;
case 8: /* User code access, XXX */
default:
- do_unassigned_access(T0, 0, 0, asi);
+ do_unassigned_access(addr, 0, 0, asi);
ret = 0;
break;
}
if (sign) {
switch(size) {
case 1:
- T1 = (int8_t) ret;
+ ret = (int8_t) ret;
break;
case 2:
- T1 = (int16_t) ret;
+ ret = (int16_t) ret;
+ break;
+ case 4:
+ ret = (int32_t) ret;
break;
default:
- T1 = ret;
break;
}
}
- else
- T1 = ret;
#ifdef DEBUG_ASI
- dump_asi("read ", last_T0, asi, size, T1, T0);
+ dump_asi("read ", last_addr, asi, size, ret);
#endif
+ return ret;
}
-void helper_st_asi(int asi, int size)
+void helper_st_asi(target_ulong addr, uint64_t val, int asi, int size)
{
switch(asi) {
case 2: /* SuperSparc MXCC registers */
- switch (T0) {
+ switch (addr) {
case 0x01c00000: /* MXCC stream data register 0 */
if (size == 8)
- env->mxccdata[0] = ((uint64_t)T1 << 32) | T2;
+ env->mxccdata[0] = val;
else
- DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
+ DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr, size);
break;
case 0x01c00008: /* MXCC stream data register 1 */
if (size == 8)
- env->mxccdata[1] = ((uint64_t)T1 << 32) | T2;
+ env->mxccdata[1] = val;
else
- DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
+ DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr, size);
break;
case 0x01c00010: /* MXCC stream data register 2 */
if (size == 8)
- env->mxccdata[2] = ((uint64_t)T1 << 32) | T2;
+ env->mxccdata[2] = val;
else
- DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
+ DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr, size);
break;
case 0x01c00018: /* MXCC stream data register 3 */
if (size == 8)
- env->mxccdata[3] = ((uint64_t)T1 << 32) | T2;
+ env->mxccdata[3] = val;
else
- DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
+ DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr, size);
break;
case 0x01c00100: /* MXCC stream source */
if (size == 8)
- env->mxccregs[0] = ((uint64_t)T1 << 32) | T2;
+ env->mxccregs[0] = val;
else
- DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
+ DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr, size);
env->mxccdata[0] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) + 0);
env->mxccdata[1] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) + 8);
env->mxccdata[2] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) + 16);
@@ -518,9 +522,9 @@
break;
case 0x01c00200: /* MXCC stream destination */
if (size == 8)
- env->mxccregs[1] = ((uint64_t)T1 << 32) | T2;
+ env->mxccregs[1] = val;
else
- DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
+ DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr, size);
stq_phys((env->mxccregs[1] & 0xffffffffULL) + 0, env->mxccdata[0]);
stq_phys((env->mxccregs[1] & 0xffffffffULL) + 8, env->mxccdata[1]);
stq_phys((env->mxccregs[1] & 0xffffffffULL) + 16, env->mxccdata[2]);
@@ -528,34 +532,34 @@
break;
case 0x01c00a00: /* MXCC control register */
if (size == 8)
- env->mxccregs[3] = ((uint64_t)T1 << 32) | T2;
+ env->mxccregs[3] = val;
else
- DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
+ DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr, size);
break;
case 0x01c00a04: /* MXCC control register */
if (size == 4)
- env->mxccregs[3] = (env->mxccregs[0xa] & 0xffffffff00000000ULL) | T1;
+ env->mxccregs[3] = (env->mxccregs[0xa] & 0xffffffff00000000ULL) | val;
else
- DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
+ DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr, size);
break;
case 0x01c00e00: /* MXCC error register */
// writing a 1 bit clears the error
if (size == 8)
- env->mxccregs[6] &= ~(((uint64_t)T1 << 32) | T2);
+ env->mxccregs[6] &= ~val;
else
- DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
+ DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr, size);
break;
case 0x01c00f00: /* MBus port address register */
if (size == 8)
- env->mxccregs[7] = ((uint64_t)T1 << 32) | T2;
+ env->mxccregs[7] = val;
else
- DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
+ DPRINTF_MXCC("%08x: unimplemented access size: %d\n", addr, size);
break;
default:
- DPRINTF_MXCC("%08x: unimplemented address, size: %d\n", T0, size);
+ DPRINTF_MXCC("%08x: unimplemented address, size: %d\n", addr, size);
break;
}
- DPRINTF_MXCC("asi = %d, size = %d, T0 = %08x, T1 = %08x\n", asi, size, T0, T1);
+ DPRINTF_MXCC("asi = %d, size = %d, addr = %08x, val = %08x\n", asi, size, addr, val);
#ifdef DEBUG_MXCC
dump_mxcc(env);
#endif
@@ -564,11 +568,11 @@
{
int mmulev;
- mmulev = (T0 >> 8) & 15;
+ mmulev = (addr >> 8) & 15;
DPRINTF_MMU("mmu flush level %d\n", mmulev);
switch (mmulev) {
case 0: // flush page
- tlb_flush_page(env, T0 & 0xfffff000);
+ tlb_flush_page(env, addr & 0xfffff000);
break;
case 1: // flush segment (256k)
case 2: // flush region (16M)
@@ -586,14 +590,14 @@
break;
case 4: /* write MMU regs */
{
- int reg = (T0 >> 8) & 0x1f;
+ int reg = (addr >> 8) & 0x1f;
uint32_t oldreg;
oldreg = env->mmuregs[reg];
switch(reg) {
case 0: // Control Register
env->mmuregs[reg] = (env->mmuregs[reg] & 0xff000000) |
- (T1 & 0x00ffffff);
+ (val & 0x00ffffff);
// Mappings generated during no-fault mode or MMU
// disabled mode are invalid in normal mode
if ((oldreg & (MMU_E | MMU_NF | env->mmu_bm)) !=
@@ -601,10 +605,10 @@
tlb_flush(env, 1);
break;
case 1: // Context Table Pointer Register
- env->mmuregs[reg] = T1 & env->mmu_ctpr_mask;
+ env->mmuregs[reg] = val & env->mmu_ctpr_mask;
break;
case 2: // Context Register
- env->mmuregs[reg] = T1 & env->mmu_cxr_mask;
+ env->mmuregs[reg] = val & env->mmu_cxr_mask;
if (oldreg != env->mmuregs[reg]) {
/* we flush when the MMU context changes because
QEMU has no MMU context support */
@@ -615,16 +619,16 @@
case 4: // Synchronous Fault Address Register
break;
case 0x10: // TLB Replacement Control Register
- env->mmuregs[reg] = T1 & env->mmu_trcr_mask;
+ env->mmuregs[reg] = val & env->mmu_trcr_mask;
break;
case 0x13: // Synchronous Fault Status Register with Read and Clear
- env->mmuregs[3] = T1 & env->mmu_sfsr_mask;
+ env->mmuregs[3] = val & env->mmu_sfsr_mask;
break;
case 0x14: // Synchronous Fault Address Register
- env->mmuregs[4] = T1;
+ env->mmuregs[4] = val;
break;
default:
- env->mmuregs[reg] = T1;
+ env->mmuregs[reg] = val;
break;
}
if (oldreg != env->mmuregs[reg]) {
@@ -642,34 +646,34 @@
case 0xa: /* User data access */
switch(size) {
case 1:
- stb_user(T0, T1);
+ stb_user(addr, val);
break;
case 2:
- stw_user(T0 & ~1, T1);
+ stw_user(addr & ~1, val);
break;
default:
case 4:
- stl_user(T0 & ~3, T1);
+ stl_user(addr & ~3, val);
break;
case 8:
- stq_user(T0 & ~7, ((uint64_t)T1 << 32) | T2);
+ stq_user(addr & ~7, val);
break;
}
break;
case 0xb: /* Supervisor data access */
switch(size) {
case 1:
- stb_kernel(T0, T1);
+ stb_kernel(addr, val);
break;
case 2:
- stw_kernel(T0 & ~1, T1);
+ stw_kernel(addr & ~1, val);
break;
default:
case 4:
- stl_kernel(T0 & ~3, T1);
+ stl_kernel(addr & ~3, val);
break;
case 8:
- stq_kernel(T0 & ~7, ((uint64_t)T1 << 32) | T2);
+ stq_kernel(addr & ~7, val);
break;
}
break;
@@ -685,11 +689,11 @@
break;
case 0x17: /* Block copy, sta access */
{
- // value (T1) = src
- // address (T0) = dst
+ // val = src
+ // addr = dst
// copy 32 bytes
unsigned int i;
- uint32_t src = T1 & ~3, dst = T0 & ~3, temp;
+ uint32_t src = val & ~3, dst = addr & ~3, temp;
for (i = 0; i < 32; i += 4, src += 4, dst += 4) {
temp = ldl_kernel(src);
@@ -699,14 +703,10 @@
break;
case 0x1f: /* Block fill, stda access */
{
- // value (T1, T2)
- // address (T0) = dst
- // fill 32 bytes
+ // addr = dst
+ // fill 32 bytes with val
unsigned int i;
- uint32_t dst = T0 & 7;
- uint64_t val;
-
- val = (((uint64_t)T1) << 32) | T2;
+ uint32_t dst = addr & 7;
for (i = 0; i < 32; i += 8, dst += 8)
stq_kernel(dst, val);
@@ -716,17 +716,17 @@
{
switch(size) {
case 1:
- stb_phys(T0, T1);
+ stb_phys(addr, val);
break;
case 2:
- stw_phys(T0 & ~1, T1);
+ stw_phys(addr & ~1, val);
break;
case 4:
default:
- stl_phys(T0 & ~3, T1);
+ stl_phys(addr & ~3, val);
break;
case 8:
- stq_phys(T0 & ~7, ((uint64_t)T1 << 32) | T2);
+ stq_phys(addr & ~7, val);
break;
}
}
@@ -735,22 +735,21 @@
{
switch(size) {
case 1:
- stb_phys((target_phys_addr_t)T0
- | ((target_phys_addr_t)(asi & 0xf) << 32), T1);
+ stb_phys((target_phys_addr_t)addr
+ | ((target_phys_addr_t)(asi & 0xf) << 32), val);
break;
case 2:
- stw_phys((target_phys_addr_t)(T0 & ~1)
- | ((target_phys_addr_t)(asi & 0xf) << 32), T1);
+ stw_phys((target_phys_addr_t)(addr & ~1)
+ | ((target_phys_addr_t)(asi & 0xf) << 32), val);
break;
case 4:
default:
- stl_phys((target_phys_addr_t)(T0 & ~3)
- | ((target_phys_addr_t)(asi & 0xf) << 32), T1);
+ stl_phys((target_phys_addr_t)(addr & ~3)
+ | ((target_phys_addr_t)(asi & 0xf) << 32), val);
break;
case 8:
- stq_phys((target_phys_addr_t)(T0 & ~7)
- | ((target_phys_addr_t)(asi & 0xf) << 32),
- ((uint64_t)T1 << 32) | T2);
+ stq_phys((target_phys_addr_t)(addr & ~7)
+ | ((target_phys_addr_t)(asi & 0xf) << 32), val);
break;
}
}
@@ -767,11 +766,11 @@
case 8: /* User code access, XXX */
case 9: /* Supervisor code access, XXX */
default:
- do_unassigned_access(T0, 1, 0, asi);
+ do_unassigned_access(addr, 1, 0, asi);
break;
}
#ifdef DEBUG_ASI
- dump_asi("write", T0, asi, size, T1, T2);
+ dump_asi("write", addr, asi, size, val);
#endif
}
@@ -779,9 +778,12 @@
#else /* TARGET_SPARC64 */
#ifdef CONFIG_USER_ONLY
-void helper_ld_asi(int asi, int size, int sign)
+uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
{
uint64_t ret = 0;
+#if defined(DEBUG_ASI)
+ target_ulong last_addr = addr;
+#endif
if (asi < 0x80)
raise_exception(TT_PRIV_ACT);
@@ -794,17 +796,17 @@
{
switch(size) {
case 1:
- ret = ldub_raw(T0);
+ ret = ldub_raw(addr);
break;
case 2:
- ret = lduw_raw(T0 & ~1);
+ ret = lduw_raw(addr & ~1);
break;
case 4:
- ret = ldl_raw(T0 & ~3);
+ ret = ldl_raw(addr & ~3);
break;
default:
case 8:
- ret = ldq_raw(T0 & ~7);
+ ret = ldq_raw(addr & ~7);
break;
}
}
@@ -858,11 +860,17 @@
break;
}
}
- T1 = ret;
+#ifdef DEBUG_ASI
+ dump_asi("read ", last_addr, asi, size, ret);
+#endif
+ return ret;
}
-void helper_st_asi(int asi, int size)
+void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
{
+#ifdef DEBUG_ASI
+ dump_asi("write", addr, asi, size, val);
+#endif
if (asi < 0x80)
raise_exception(TT_PRIV_ACT);
@@ -872,13 +880,13 @@
case 0x89: // Secondary LE
switch(size) {
case 2:
- T0 = bswap16(T0);
+ addr = bswap16(addr);
break;
case 4:
- T0 = bswap32(T0);
+ addr = bswap32(addr);
break;
case 8:
- T0 = bswap64(T0);
+ addr = bswap64(addr);
break;
default:
break;
@@ -893,17 +901,17 @@
{
switch(size) {
case 1:
- stb_raw(T0, T1);
+ stb_raw(addr, val);
break;
case 2:
- stw_raw(T0 & ~1, T1);
+ stw_raw(addr & ~1, val);
break;
case 4:
- stl_raw(T0 & ~3, T1);
+ stl_raw(addr & ~3, val);
break;
case 8:
default:
- stq_raw(T0 & ~7, T1);
+ stq_raw(addr & ~7, val);
break;
}
}
@@ -918,16 +926,19 @@
case 0x8a: // Primary no-fault LE, RO
case 0x8b: // Secondary no-fault LE, RO
default:
- do_unassigned_access(T0, 1, 0, 1);
+ do_unassigned_access(addr, 1, 0, 1);
return;
}
}
#else /* CONFIG_USER_ONLY */
-void helper_ld_asi(int asi, int size, int sign)
+uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
{
uint64_t ret = 0;
+#if defined(DEBUG_ASI)
+ target_ulong last_addr = addr;
+#endif
if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
|| (asi >= 0x30 && asi < 0x80 && !(env->hpstate & HS_PRIV)))
@@ -944,50 +955,50 @@
if (env->hpstate & HS_PRIV) {
switch(size) {
case 1:
- ret = ldub_hypv(T0);
+ ret = ldub_hypv(addr);
break;
case 2:
- ret = lduw_hypv(T0 & ~1);
+ ret = lduw_hypv(addr & ~1);
break;
case 4:
- ret = ldl_hypv(T0 & ~3);
+ ret = ldl_hypv(addr & ~3);
break;
default:
case 8:
- ret = ldq_hypv(T0 & ~7);
+ ret = ldq_hypv(addr & ~7);
break;
}
} else {
switch(size) {
case 1:
- ret = ldub_kernel(T0);
+ ret = ldub_kernel(addr);
break;
case 2:
- ret = lduw_kernel(T0 & ~1);
+ ret = lduw_kernel(addr & ~1);
break;
case 4:
- ret = ldl_kernel(T0 & ~3);
+ ret = ldl_kernel(addr & ~3);
break;
default:
case 8:
- ret = ldq_kernel(T0 & ~7);
+ ret = ldq_kernel(addr & ~7);
break;
}
}
} else {
switch(size) {
case 1:
- ret = ldub_user(T0);
+ ret = ldub_user(addr);
break;
case 2:
- ret = lduw_user(T0 & ~1);
+ ret = lduw_user(addr & ~1);
break;
case 4:
- ret = ldl_user(T0 & ~3);
+ ret = ldl_user(addr & ~3);
break;
default:
case 8:
- ret = ldq_user(T0 & ~7);
+ ret = ldq_user(addr & ~7);
break;
}
}
@@ -999,17 +1010,17 @@
{
switch(size) {
case 1:
- ret = ldub_phys(T0);
+ ret = ldub_phys(addr);
break;
case 2:
- ret = lduw_phys(T0 & ~1);
+ ret = lduw_phys(addr & ~1);
break;
case 4:
- ret = ldl_phys(T0 & ~3);
+ ret = ldl_phys(addr & ~3);
break;
default:
case 8:
- ret = ldq_phys(T0 & ~7);
+ ret = ldq_phys(addr & ~7);
break;
}
break;
@@ -1032,7 +1043,7 @@
break;
case 0x50: // I-MMU regs
{
- int reg = (T0 >> 3) & 0xf;
+ int reg = (addr >> 3) & 0xf;
ret = env->immuregs[reg];
break;
@@ -1049,7 +1060,7 @@
for (i = 0; i < 64; i++) {
// Valid, ctx match, vaddr match
if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0 &&
- env->itlb_tag[i] == T0) {
+ env->itlb_tag[i] == addr) {
ret = env->itlb_tag[i];
break;
}
@@ -1058,7 +1069,7 @@
}
case 0x58: // D-MMU regs
{
- int reg = (T0 >> 3) & 0xf;
+ int reg = (addr >> 3) & 0xf;
ret = env->dmmuregs[reg];
break;
@@ -1070,7 +1081,7 @@
for (i = 0; i < 64; i++) {
// Valid, ctx match, vaddr match
if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0 &&
- env->dtlb_tag[i] == T0) {
+ env->dtlb_tag[i] == addr) {
ret = env->dtlb_tag[i];
break;
}
@@ -1092,7 +1103,7 @@
case 0x5f: // D-MMU demap, WO
case 0x77: // Interrupt vector, WO
default:
- do_unassigned_access(T0, 0, 0, 1);
+ do_unassigned_access(addr, 0, 0, 1);
ret = 0;
break;
}
@@ -1141,11 +1152,17 @@
break;
}
}
- T1 = ret;
+#ifdef DEBUG_ASI
+ dump_asi("read ", last_addr, asi, size, ret);
+#endif
+ return ret;
}
-void helper_st_asi(int asi, int size)
+void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
{
+#ifdef DEBUG_ASI
+ dump_asi("write", addr, asi, size, val);
+#endif
if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
|| (asi >= 0x30 && asi < 0x80 && !(env->hpstate & HS_PRIV)))
raise_exception(TT_PRIV_ACT);
@@ -1161,13 +1178,13 @@
case 0x89: // Secondary LE
switch(size) {
case 2:
- T0 = bswap16(T0);
+ addr = bswap16(addr);
break;
case 4:
- T0 = bswap32(T0);
+ addr = bswap32(addr);
break;
case 8:
- T0 = bswap64(T0);
+ addr = bswap64(addr);
break;
default:
break;
@@ -1185,50 +1202,50 @@
if (env->hpstate & HS_PRIV) {
switch(size) {
case 1:
- stb_hypv(T0, T1);
+ stb_hypv(addr, val);
break;
case 2:
- stw_hypv(T0 & ~1, T1);
+ stw_hypv(addr & ~1, val);
break;
case 4:
- stl_hypv(T0 & ~3, T1);
+ stl_hypv(addr & ~3, val);
break;
case 8:
default:
- stq_hypv(T0 & ~7, T1);
+ stq_hypv(addr & ~7, val);
break;
}
} else {
switch(size) {
case 1:
- stb_kernel(T0, T1);
+ stb_kernel(addr, val);
break;
case 2:
- stw_kernel(T0 & ~1, T1);
+ stw_kernel(addr & ~1, val);
break;
case 4:
- stl_kernel(T0 & ~3, T1);
+ stl_kernel(addr & ~3, val);
break;
case 8:
default:
- stq_kernel(T0 & ~7, T1);
+ stq_kernel(addr & ~7, val);
break;
}
}
} else {
switch(size) {
case 1:
- stb_user(T0, T1);
+ stb_user(addr, val);
break;
case 2:
- stw_user(T0 & ~1, T1);
+ stw_user(addr & ~1, val);
break;
case 4:
- stl_user(T0 & ~3, T1);
+ stl_user(addr & ~3, val);
break;
case 8:
default:
- stq_user(T0 & ~7, T1);
+ stq_user(addr & ~7, val);
break;
}
}
@@ -1240,17 +1257,17 @@
{
switch(size) {
case 1:
- stb_phys(T0, T1);
+ stb_phys(addr, val);
break;
case 2:
- stw_phys(T0 & ~1, T1);
+ stw_phys(addr & ~1, val);
break;
case 4:
- stl_phys(T0 & ~3, T1);
+ stl_phys(addr & ~3, val);
break;
case 8:
default:
- stq_phys(T0 & ~7, T1);
+ stq_phys(addr & ~7, val);
break;
}
}
@@ -1271,7 +1288,7 @@
uint64_t oldreg;
oldreg = env->lsu;
- env->lsu = T1 & (DMMU_E | IMMU_E);
+ env->lsu = val & (DMMU_E | IMMU_E);
// Mappings generated during D/I MMU disabled mode are
// invalid in normal mode
if (oldreg != env->lsu) {
@@ -1285,7 +1302,7 @@
}
case 0x50: // I-MMU regs
{
- int reg = (T0 >> 3) & 0xf;
+ int reg = (addr >> 3) & 0xf;
uint64_t oldreg;
oldreg = env->immuregs[reg];
@@ -1299,15 +1316,15 @@
case 8:
return;
case 3: // SFSR
- if ((T1 & 1) == 0)
- T1 = 0; // Clear SFSR
+ if ((val & 1) == 0)
+ val = 0; // Clear SFSR
break;
case 5: // TSB access
case 6: // Tag access
default:
break;
}
- env->immuregs[reg] = T1;
+ env->immuregs[reg] = val;
if (oldreg != env->immuregs[reg]) {
DPRINTF_MMU("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, oldreg, env->immuregs[reg]);
}
@@ -1324,7 +1341,7 @@
for (i = 0; i < 64; i++) {
if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0) {
env->itlb_tag[i] = env->immuregs[6];
- env->itlb_tte[i] = T1;
+ env->itlb_tte[i] = val;
return;
}
}
@@ -1332,7 +1349,7 @@
for (i = 0; i < 64; i++) {
if ((env->itlb_tte[i] & 0x40) == 0) {
env->itlb_tag[i] = env->immuregs[6];
- env->itlb_tte[i] = T1;
+ env->itlb_tte[i] = val;
return;
}
}
@@ -1341,10 +1358,10 @@
}
case 0x55: // I-MMU data access
{
- unsigned int i = (T0 >> 3) & 0x3f;
+ unsigned int i = (addr >> 3) & 0x3f;
env->itlb_tag[i] = env->immuregs[6];
- env->itlb_tte[i] = T1;
+ env->itlb_tte[i] = val;
return;
}
case 0x57: // I-MMU demap
@@ -1352,7 +1369,7 @@
return;
case 0x58: // D-MMU regs
{
- int reg = (T0 >> 3) & 0xf;
+ int reg = (addr >> 3) & 0xf;
uint64_t oldreg;
oldreg = env->dmmuregs[reg];
@@ -1361,11 +1378,11 @@
case 4:
return;
case 3: // SFSR
- if ((T1 & 1) == 0) {
- T1 = 0; // Clear SFSR, Fault address
+ if ((val & 1) == 0) {
+ val = 0; // Clear SFSR, Fault address
env->dmmuregs[4] = 0;
}
- env->dmmuregs[reg] = T1;
+ env->dmmuregs[reg] = val;
break;
case 1: // Primary context
case 2: // Secondary context
@@ -1376,7 +1393,7 @@
default:
break;
}
- env->dmmuregs[reg] = T1;
+ env->dmmuregs[reg] = val;
if (oldreg != env->dmmuregs[reg]) {
DPRINTF_MMU("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, oldreg, env->dmmuregs[reg]);
}
@@ -1393,7 +1410,7 @@
for (i = 0; i < 64; i++) {
if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0) {
env->dtlb_tag[i] = env->dmmuregs[6];
- env->dtlb_tte[i] = T1;
+ env->dtlb_tte[i] = val;
return;
}
}
@@ -1401,7 +1418,7 @@
for (i = 0; i < 64; i++) {
if ((env->dtlb_tte[i] & 0x40) == 0) {
env->dtlb_tag[i] = env->dmmuregs[6];
- env->dtlb_tte[i] = T1;
+ env->dtlb_tte[i] = val;
return;
}
}
@@ -1410,10 +1427,10 @@
}
case 0x5d: // D-MMU data access
{
- unsigned int i = (T0 >> 3) & 0x3f;
+ unsigned int i = (addr >> 3) & 0x3f;
env->dtlb_tag[i] = env->dmmuregs[6];
- env->dtlb_tte[i] = T1;
+ env->dtlb_tte[i] = val;
return;
}
case 0x5f: // D-MMU demap
@@ -1434,16 +1451,16 @@
case 0x8a: // Primary no-fault LE, RO
case 0x8b: // Secondary no-fault LE, RO
default:
- do_unassigned_access(T0, 1, 0, 1);
+ do_unassigned_access(addr, 1, 0, 1);
return;
}
}
#endif /* CONFIG_USER_ONLY */
-void helper_ldf_asi(int asi, int size, int rd)
+void helper_ldf_asi(target_ulong addr, int asi, int size, int rd)
{
- target_ulong tmp_T0 = T0, tmp_T1 = T1;
unsigned int i;
+ target_ulong val;
switch (asi) {
case 0xf0: // Block load primary
@@ -1454,31 +1471,28 @@
raise_exception(TT_ILL_INSN);
return;
}
- if (T0 & 0x3f) {
+ if (addr & 0x3f) {
raise_exception(TT_UNALIGNED);
return;
}
for (i = 0; i < 16; i++) {
- helper_ld_asi(asi & 0x8f, 4, 0);
- *(uint32_t *)&env->fpr[rd++] = T1;
- T0 += 4;
+ *(uint32_t *)&env->fpr[rd++] = helper_ld_asi(addr, asi & 0x8f, 4, 0);
+ addr += 4;
}
- T0 = tmp_T0;
- T1 = tmp_T1;
return;
default:
break;
}
- helper_ld_asi(asi, size, 0);
+ val = helper_ld_asi(addr, asi, size, 0);
switch(size) {
default:
case 4:
- *((uint32_t *)&FT0) = T1;
+ *((uint32_t *)&FT0) = val;
break;
case 8:
- *((int64_t *)&DT0) = T1;
+ *((int64_t *)&DT0) = val;
break;
#if defined(CONFIG_USER_ONLY)
case 16:
@@ -1486,13 +1500,12 @@
break;
#endif
}
- T1 = tmp_T1;
}
-void helper_stf_asi(int asi, int size, int rd)
+void helper_stf_asi(target_ulong addr, int asi, int size, int rd)
{
- target_ulong tmp_T0 = T0, tmp_T1 = T1;
unsigned int i;
+ target_ulong val = 0;
switch (asi) {
case 0xf0: // Block store primary
@@ -1503,17 +1516,15 @@
raise_exception(TT_ILL_INSN);
return;
}
- if (T0 & 0x3f) {
+ if (addr & 0x3f) {
raise_exception(TT_UNALIGNED);
return;
}
for (i = 0; i < 16; i++) {
- T1 = *(uint32_t *)&env->fpr[rd++];
- helper_st_asi(asi & 0x8f, 4);
- T0 += 4;
+ val = *(uint32_t *)&env->fpr[rd++];
+ helper_st_asi(addr, val, asi & 0x8f, 4);
+ addr += 4;
}
- T0 = tmp_T0;
- T1 = tmp_T1;
return;
default:
@@ -1523,10 +1534,10 @@
switch(size) {
default:
case 4:
- T1 = *((uint32_t *)&FT0);
+ val = *((uint32_t *)&FT0);
break;
case 8:
- T1 = *((int64_t *)&DT0);
+ val = *((int64_t *)&DT0);
break;
#if defined(CONFIG_USER_ONLY)
case 16:
@@ -1534,14 +1545,36 @@
break;
#endif
}
- helper_st_asi(asi, size);
- T1 = tmp_T1;
+ helper_st_asi(addr, val, asi, size);
}
+target_ulong helper_cas_asi(target_ulong addr, target_ulong val1,
+ target_ulong val2, uint32_t asi)
+{
+ target_ulong ret;
+
+ val1 &= 0xffffffffUL;
+ ret = helper_ld_asi(addr, asi, 4, 0);
+ ret &= 0xffffffffUL;
+ if (val1 == ret)
+ helper_st_asi(addr, val2 & 0xffffffffUL, asi, 4);
+ return ret;
+}
+
+target_ulong helper_casx_asi(target_ulong addr, target_ulong val1,
+ target_ulong val2, uint32_t asi)
+{
+ target_ulong ret;
+
+ ret = helper_ld_asi(addr, asi, 8, 0);
+ if (val1 == ret)
+ helper_st_asi(addr, val2, asi, 8);
+ return ret;
+}
#endif /* TARGET_SPARC64 */
#ifndef TARGET_SPARC64
-void helper_rett()
+void helper_rett(void)
{
unsigned int cwp;
@@ -1558,6 +1591,11 @@
}
#endif
+uint64_t helper_pack64(target_ulong high, target_ulong low)
+{
+ return ((uint64_t)high << 32) | (uint64_t)(low & 0xffffffff);
+}
+
void helper_ldfsr(void)
{
int rnd_mode;
@@ -1586,24 +1624,24 @@
}
#ifndef TARGET_SPARC64
-void do_wrpsr()
+void helper_wrpsr(target_ulong new_psr)
{
- if ((T0 & PSR_CWP) >= NWINDOWS)
+ if ((new_psr & PSR_CWP) >= NWINDOWS)
raise_exception(TT_ILL_INSN);
else
- PUT_PSR(env, T0);
+ PUT_PSR(env, new_psr);
}
-void do_rdpsr()
+target_ulong helper_rdpsr(void)
{
- T0 = GET_PSR(env);
+ return GET_PSR(env);
}
#else
-void do_popc()
+target_ulong helper_popc(target_ulong val)
{
- T0 = ctpop64(T1);
+ return ctpop64(val);
}
static inline uint64_t *get_gregset(uint64_t pstate)
@@ -1638,12 +1676,12 @@
env->pstate = new_pstate;
}
-void do_wrpstate(void)
+void helper_wrpstate(target_ulong new_state)
{
- change_pstate(T0 & 0xf3f);
+ change_pstate(new_state & 0xf3f);
}
-void do_done(void)
+void helper_done(void)
{
env->tl--;
env->pc = env->tnpc[env->tl];
@@ -1654,7 +1692,7 @@
PUT_CWP64(env, env->tstate[env->tl] & 0xff);
}
-void do_retry(void)
+void helper_retry(void)
{
env->tl--;
env->pc = env->tpc[env->tl];
Index: qemu/target-sparc/op_mem.h
===================================================================
--- qemu.orig/target-sparc/op_mem.h 2008-02-22 16:16:21.000000000 +0000
+++ qemu/target-sparc/op_mem.h 2008-02-22 20:05:22.000000000 +0000
@@ -4,65 +4,6 @@
#define ADDR(x) (x)
#endif
-/*** Integer load ***/
-#define SPARC_LD_OP(name, qp) \
-void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \
-{ \
- T1 = (target_ulong)glue(qp, MEMSUFFIX)(ADDR(T0)); \
-}
-
-#define SPARC_LD_OP_S(name, qp) \
- void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \
- { \
- T1 = (target_long)glue(qp, MEMSUFFIX)(ADDR(T0)); \
- }
-
-#define SPARC_ST_OP(name, op) \
-void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \
-{ \
- glue(op, MEMSUFFIX)(ADDR(T0), T1); \
-}
-
-SPARC_LD_OP(ld, ldl);
-SPARC_LD_OP(ldub, ldub);
-SPARC_LD_OP(lduh, lduw);
-SPARC_LD_OP_S(ldsb, ldsb);
-SPARC_LD_OP_S(ldsh, ldsw);
-
-/*** Integer store ***/
-SPARC_ST_OP(st, stl);
-SPARC_ST_OP(stb, stb);
-SPARC_ST_OP(sth, stw);
-
-void OPPROTO glue(op_std, MEMSUFFIX)(void)
-{
- uint64_t tmp = ((uint64_t)T1 << 32) | (uint64_t)(T2 & 0xffffffff);
-
- glue(stq, MEMSUFFIX)(ADDR(T0), tmp);
-}
-
-void OPPROTO glue(op_ldstub, MEMSUFFIX)(void)
-{
- T1 = glue(ldub, MEMSUFFIX)(ADDR(T0));
- glue(stb, MEMSUFFIX)(ADDR(T0), 0xff); /* XXX: Should be Atomically */
-}
-
-void OPPROTO glue(op_swap, MEMSUFFIX)(void)
-{
- target_ulong tmp = glue(ldl, MEMSUFFIX)(ADDR(T0));
- glue(stl, MEMSUFFIX)(ADDR(T0), T1); /* XXX: Should be Atomically */
- T1 = tmp;
-}
-
-void OPPROTO glue(op_ldd, MEMSUFFIX)(void)
-{
- uint64_t tmp;
-
- tmp = glue(ldq, MEMSUFFIX)(ADDR(T0));
- T1 = tmp >> 32;
- T0 = tmp & 0xffffffff;
-}
-
/*** Floating-point store ***/
void OPPROTO glue(op_stf, MEMSUFFIX) (void)
{
@@ -107,18 +48,4 @@
}
#endif
-#ifdef TARGET_SPARC64
-void OPPROTO glue(op_lduw, MEMSUFFIX)(void)
-{
- T1 = (uint64_t)(glue(ldl, MEMSUFFIX)(ADDR(T0)) & 0xffffffff);
-}
-
-void OPPROTO glue(op_ldsw, MEMSUFFIX)(void)
-{
- T1 = (int64_t)(glue(ldl, MEMSUFFIX)(ADDR(T0)) & 0xffffffff);
-}
-
-SPARC_LD_OP(ldx, ldq);
-SPARC_ST_OP(stx, stq);
-#endif
#undef MEMSUFFIX
Index: qemu/target-sparc/exec.h
===================================================================
--- qemu.orig/target-sparc/exec.h 2008-02-22 18:58:40.000000000 +0000
+++ qemu/target-sparc/exec.h 2008-02-23 16:34:38.000000000 +0000
@@ -52,12 +52,6 @@
void cpu_lock(void);
void cpu_unlock(void);
void cpu_loop_exit(void);
-void helper_flush(target_ulong addr);
-void helper_ld_asi(int asi, int size, int sign);
-void helper_st_asi(int asi, int size);
-void helper_ldf_asi(int asi, int size, int rd);
-void helper_stf_asi(int asi, int size, int rd);
-void helper_rett(void);
void helper_ldfsr(void);
void set_cwp(int new_cwp);
void do_fitos(void);
@@ -101,23 +95,13 @@
void do_fcmpeq_fcc2(void);
void do_fcmpeq_fcc3(void);
#endif
-void do_popc();
-void do_wrpstate();
-void do_done();
-void do_retry();
#endif
-void do_ldd_kernel(target_ulong addr);
-void do_ldd_user(target_ulong addr);
-void do_ldd_raw(target_ulong addr);
void do_interrupt(int intno);
void raise_exception(int tt);
void check_ieee_exceptions();
void memcpy32(target_ulong *dst, const target_ulong *src);
target_ulong mmu_probe(CPUState *env, target_ulong address, int mmulev);
void dump_mmu(CPUState *env);
-void helper_debug();
-void do_wrpsr();
-void do_rdpsr();
/* XXX: move that to a generic header */
#if !defined(CONFIG_USER_ONLY)
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Qemu-devel] Re: [PATCH, RFC, WIP] TCG for Qemu target Sparc32/64
2008-02-23 18:29 ` Blue Swirl
@ 2008-02-23 18:48 ` Fabrice Bellard
0 siblings, 0 replies; 8+ messages in thread
From: Fabrice Bellard @ 2008-02-23 18:48 UTC (permalink / raw)
To: Blue Swirl; +Cc: qemu-devel
> [...]
>> Another point is that you should define TCG globals for each SPARC GPR.
>> It was not done for i386 because I feared performance regressions when
>> accessing to 16 bit or 8 bit sub-registers. On SPARC you do not have
>> this issue.
>
> Nice idea. Would this also work for windowed registers?
Yes, provided you use a fixed register to store regwptr. Then you can
define the windowed registers as globals using this register as base.
The real problem is to save and restore this register in cpu_exec() and
in all the places where the regwptr CPU state field is accessed
directly. TCG will handle these problems generically soon, but before it
does it you can implement it "by hand".
Regards,
Fabrice.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] Re: [PATCH, RFC, WIP] TCG for Qemu target Sparc32/64
2008-02-23 18:23 ` [Qemu-devel] " Fabrice Bellard
2008-02-23 18:29 ` Blue Swirl
@ 2008-02-23 20:32 ` Paul Brook
2008-02-23 23:59 ` Stuart Brady
2 siblings, 0 replies; 8+ messages in thread
From: Paul Brook @ 2008-02-23 20:32 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl
> Another point is that you should define TCG globals for each SPARC GPR.
> It was not done for i386 because I feared performance regressions when
> accessing to 16 bit or 8 bit sub-registers. On SPARC you do not have
> this issue.
How would these be kept consistent with CPUState?
Paul
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] Re: [PATCH, RFC, WIP] TCG for Qemu target Sparc32/64
2008-02-23 18:23 ` [Qemu-devel] " Fabrice Bellard
2008-02-23 18:29 ` Blue Swirl
2008-02-23 20:32 ` Paul Brook
@ 2008-02-23 23:59 ` Stuart Brady
2 siblings, 0 replies; 8+ messages in thread
From: Stuart Brady @ 2008-02-23 23:59 UTC (permalink / raw)
To: qemu-devel
On Sat, Feb 23, 2008 at 07:23:49PM +0100, Fabrice Bellard wrote:
> But do not mix the target specific defines with target independent
> defines (in tcg-op.h there is a specific section for target specific
> defines).
Might it be worth moving that section into a new file?
--
Stuart Brady
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2008-02-23 23:59 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-02-21 20:27 [Qemu-devel] [PATCH, RFC, WIP] TCG for Qemu target Sparc32/64 Blue Swirl
2008-02-22 0:06 ` Thiemo Seufer
2008-02-22 16:13 ` Blue Swirl
2008-02-23 18:23 ` [Qemu-devel] " Fabrice Bellard
2008-02-23 18:29 ` Blue Swirl
2008-02-23 18:48 ` Fabrice Bellard
2008-02-23 20:32 ` Paul Brook
2008-02-23 23:59 ` Stuart Brady
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).