#include <inttypes.h>
#include "cpu.h"
-#include "disas.h"
+#include "disas/disas.h"
#include "helper.h"
#include "tcg-op.h"
#ifndef CONFIG_USER_ONLY
static TCGv cpu_tbr;
#endif
-static TCGv cpu_cond, cpu_dst;
+static TCGv cpu_cond;
#ifdef TARGET_SPARC64
static TCGv_i32 cpu_xcc, cpu_asi, cpu_fprs;
static TCGv cpu_gsr;
#else
static TCGv cpu_wim;
#endif
-/* local register indexes (only used inside old micro ops) */
-static TCGv cpu_tmp0;
-static TCGv_i64 cpu_tmp64;
/* Floating point registers */
static TCGv_i64 cpu_fpr[TARGET_DPREGS];
static target_ulong gen_opc_npc[OPC_BUF_SIZE];
static target_ulong gen_opc_jump_pc[2];
-#include "gen-icount.h"
+#include "exec/gen-icount.h"
typedef struct DisasContext {
target_ulong pc; /* current Program Counter: integer or DYNAMIC_PC */
case CC_OP_ADD:
case CC_OP_TADD:
case CC_OP_TADDTV:
-#if TCG_TARGET_REG_BITS == 32 && TARGET_LONG_BITS == 32
- {
- /* For 32-bit hosts, we can re-use the host's hardware carry
- generation by using an ADD2 opcode. We discard the low
- part of the output. Ideally we'd combine this operation
- with the add that generated the carry in the first place. */
- TCGv dst_low = tcg_temp_new();
- tcg_gen_op6_i32(INDEX_op_add2_i32, dst_low, dst,
- cpu_cc_src, src1, cpu_cc_src2, src2);
- tcg_temp_free(dst_low);
+ if (TARGET_LONG_BITS == 32) {
+ /* We can re-use the host's hardware carry generation by using
+ an ADD2 opcode. We discard the low part of the output.
+ Ideally we'd combine this operation with the add that
+ generated the carry in the first place. */
+ carry = tcg_temp_new();
+ tcg_gen_add2_tl(carry, dst, cpu_cc_src, src1, cpu_cc_src2, src2);
+ tcg_temp_free(carry);
goto add_done;
}
-#endif
carry_32 = gen_add32_carry32();
break;
tcg_temp_free(carry);
#endif
-#if TCG_TARGET_REG_BITS == 32 && TARGET_LONG_BITS == 32
add_done:
-#endif
if (update_cc) {
tcg_gen_mov_tl(cpu_cc_src, src1);
tcg_gen_mov_tl(cpu_cc_src2, src2);
case CC_OP_SUB:
case CC_OP_TSUB:
case CC_OP_TSUBTV:
-#if TCG_TARGET_REG_BITS == 32 && TARGET_LONG_BITS == 32
- {
- /* For 32-bit hosts, we can re-use the host's hardware carry
- generation by using a SUB2 opcode. We discard the low
- part of the output. Ideally we'd combine this operation
- with the add that generated the carry in the first place. */
- TCGv dst_low = tcg_temp_new();
- tcg_gen_op6_i32(INDEX_op_sub2_i32, dst_low, dst,
- cpu_cc_src, src1, cpu_cc_src2, src2);
- tcg_temp_free(dst_low);
+ if (TARGET_LONG_BITS == 32) {
+ /* We can re-use the host's hardware carry generation by using
+ a SUB2 opcode. We discard the low part of the output.
+ Ideally we'd combine this operation with the add that
+ generated the carry in the first place. */
+ carry = tcg_temp_new();
+ tcg_gen_sub2_tl(carry, dst, cpu_cc_src, src1, cpu_cc_src2, src2);
+ tcg_temp_free(carry);
goto sub_done;
}
-#endif
carry_32 = gen_sub32_carry32();
break;
tcg_temp_free(carry);
#endif
-#if TCG_TARGET_REG_BITS == 32 && TARGET_LONG_BITS == 32
sub_done:
-#endif
if (update_cc) {
tcg_gen_mov_tl(cpu_cc_src, src1);
tcg_gen_mov_tl(cpu_cc_src2, src2);
static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)
{
- TCGv r_temp, zero;
+ TCGv r_temp, zero, t0;
r_temp = tcg_temp_new();
+ t0 = tcg_temp_new();
/* old op:
if (!(env->y & 1))
// env->y = (b2 << 31) | (env->y >> 1);
tcg_gen_andi_tl(r_temp, cpu_cc_src, 0x1);
tcg_gen_shli_tl(r_temp, r_temp, 31);
- tcg_gen_shri_tl(cpu_tmp0, cpu_y, 1);
- tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x7fffffff);
- tcg_gen_or_tl(cpu_tmp0, cpu_tmp0, r_temp);
- tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
+ tcg_gen_shri_tl(t0, cpu_y, 1);
+ tcg_gen_andi_tl(t0, t0, 0x7fffffff);
+ tcg_gen_or_tl(t0, t0, r_temp);
+ tcg_gen_andi_tl(cpu_y, t0, 0xffffffff);
// b1 = N ^ V;
- gen_mov_reg_N(cpu_tmp0, cpu_psr);
+ gen_mov_reg_N(t0, cpu_psr);
gen_mov_reg_V(r_temp, cpu_psr);
- tcg_gen_xor_tl(cpu_tmp0, cpu_tmp0, r_temp);
+ tcg_gen_xor_tl(t0, t0, r_temp);
tcg_temp_free(r_temp);
// T0 = (b1 << 31) | (T0 >> 1);
// src1 = T0;
- tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, 31);
+ tcg_gen_shli_tl(t0, t0, 31);
tcg_gen_shri_tl(cpu_cc_src, cpu_cc_src, 1);
- tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
+ tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t0);
+ tcg_temp_free(t0);
tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
static inline void gen_op_multiply(TCGv dst, TCGv src1, TCGv src2, int sign_ext)
{
- TCGv_i32 r_src1, r_src2;
- TCGv_i64 r_temp, r_temp2;
-
- r_src1 = tcg_temp_new_i32();
- r_src2 = tcg_temp_new_i32();
-
- tcg_gen_trunc_tl_i32(r_src1, src1);
- tcg_gen_trunc_tl_i32(r_src2, src2);
-
- r_temp = tcg_temp_new_i64();
- r_temp2 = tcg_temp_new_i64();
-
+#if TARGET_LONG_BITS == 32
if (sign_ext) {
- tcg_gen_ext_i32_i64(r_temp, r_src2);
- tcg_gen_ext_i32_i64(r_temp2, r_src1);
+ tcg_gen_muls2_tl(dst, cpu_y, src1, src2);
} else {
- tcg_gen_extu_i32_i64(r_temp, r_src2);
- tcg_gen_extu_i32_i64(r_temp2, r_src1);
+ tcg_gen_mulu2_tl(dst, cpu_y, src1, src2);
}
+#else
+ TCGv t0 = tcg_temp_new_i64();
+ TCGv t1 = tcg_temp_new_i64();
- tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
-
- tcg_gen_shri_i64(r_temp, r_temp2, 32);
- tcg_gen_trunc_i64_tl(cpu_tmp0, r_temp);
- tcg_temp_free_i64(r_temp);
- tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
-
- tcg_gen_trunc_i64_tl(dst, r_temp2);
+ if (sign_ext) {
+ tcg_gen_ext32s_i64(t0, src1);
+ tcg_gen_ext32s_i64(t1, src2);
+ } else {
+ tcg_gen_ext32u_i64(t0, src1);
+ tcg_gen_ext32u_i64(t1, src2);
+ }
- tcg_temp_free_i64(r_temp2);
+ tcg_gen_mul_i64(dst, t0, t1);
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
- tcg_temp_free_i32(r_src1);
- tcg_temp_free_i32(r_src2);
+ tcg_gen_shri_i64(cpu_y, dst, 32);
+#endif
}
static inline void gen_op_umul(TCGv dst, TCGv src1, TCGv src2)
// Z | (N ^ V)
static inline void gen_op_eval_ble(TCGv dst, TCGv_i32 src)
{
- gen_mov_reg_N(cpu_tmp0, src);
+ TCGv t0 = tcg_temp_new();
+ gen_mov_reg_N(t0, src);
gen_mov_reg_V(dst, src);
- tcg_gen_xor_tl(dst, dst, cpu_tmp0);
- gen_mov_reg_Z(cpu_tmp0, src);
- tcg_gen_or_tl(dst, dst, cpu_tmp0);
+ tcg_gen_xor_tl(dst, dst, t0);
+ gen_mov_reg_Z(t0, src);
+ tcg_gen_or_tl(dst, dst, t0);
+ tcg_temp_free(t0);
}
// N ^ V
static inline void gen_op_eval_bl(TCGv dst, TCGv_i32 src)
{
- gen_mov_reg_V(cpu_tmp0, src);
+ TCGv t0 = tcg_temp_new();
+ gen_mov_reg_V(t0, src);
gen_mov_reg_N(dst, src);
- tcg_gen_xor_tl(dst, dst, cpu_tmp0);
+ tcg_gen_xor_tl(dst, dst, t0);
+ tcg_temp_free(t0);
}
// C | Z
static inline void gen_op_eval_bleu(TCGv dst, TCGv_i32 src)
{
- gen_mov_reg_Z(cpu_tmp0, src);
+ TCGv t0 = tcg_temp_new();
+ gen_mov_reg_Z(t0, src);
gen_mov_reg_C(dst, src);
- tcg_gen_or_tl(dst, dst, cpu_tmp0);
+ tcg_gen_or_tl(dst, dst, t0);
+ tcg_temp_free(t0);
}
// C
// !(Z | (N ^ V))
static inline void gen_op_eval_bg(TCGv dst, TCGv_i32 src)
{
- gen_mov_reg_N(cpu_tmp0, src);
- gen_mov_reg_V(dst, src);
- tcg_gen_xor_tl(dst, dst, cpu_tmp0);
- gen_mov_reg_Z(cpu_tmp0, src);
- tcg_gen_or_tl(dst, dst, cpu_tmp0);
+ gen_op_eval_ble(dst, src);
tcg_gen_xori_tl(dst, dst, 0x1);
}
// !(N ^ V)
static inline void gen_op_eval_bge(TCGv dst, TCGv_i32 src)
{
- gen_mov_reg_V(cpu_tmp0, src);
- gen_mov_reg_N(dst, src);
- tcg_gen_xor_tl(dst, dst, cpu_tmp0);
+ gen_op_eval_bl(dst, src);
tcg_gen_xori_tl(dst, dst, 0x1);
}
// !(C | Z)
static inline void gen_op_eval_bgu(TCGv dst, TCGv_i32 src)
{
- gen_mov_reg_Z(cpu_tmp0, src);
- gen_mov_reg_C(dst, src);
- tcg_gen_or_tl(dst, dst, cpu_tmp0);
+ gen_op_eval_bleu(dst, src);
tcg_gen_xori_tl(dst, dst, 0x1);
}
static inline void gen_op_eval_fbne(TCGv dst, TCGv src,
unsigned int fcc_offset)
{
+ TCGv t0 = tcg_temp_new();
gen_mov_reg_FCC0(dst, src, fcc_offset);
- gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
- tcg_gen_or_tl(dst, dst, cpu_tmp0);
+ gen_mov_reg_FCC1(t0, src, fcc_offset);
+ tcg_gen_or_tl(dst, dst, t0);
+ tcg_temp_free(t0);
}
// 1 or 2: FCC0 ^ FCC1
static inline void gen_op_eval_fblg(TCGv dst, TCGv src,
unsigned int fcc_offset)
{
+ TCGv t0 = tcg_temp_new();
gen_mov_reg_FCC0(dst, src, fcc_offset);
- gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
- tcg_gen_xor_tl(dst, dst, cpu_tmp0);
+ gen_mov_reg_FCC1(t0, src, fcc_offset);
+ tcg_gen_xor_tl(dst, dst, t0);
+ tcg_temp_free(t0);
}
// 1 or 3: FCC0
static inline void gen_op_eval_fbl(TCGv dst, TCGv src,
unsigned int fcc_offset)
{
+ TCGv t0 = tcg_temp_new();
gen_mov_reg_FCC0(dst, src, fcc_offset);
- gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
- tcg_gen_xori_tl(cpu_tmp0, cpu_tmp0, 0x1);
- tcg_gen_and_tl(dst, dst, cpu_tmp0);
+ gen_mov_reg_FCC1(t0, src, fcc_offset);
+ tcg_gen_andc_tl(dst, dst, t0);
+ tcg_temp_free(t0);
}
// 2 or 3: FCC1
static inline void gen_op_eval_fbg(TCGv dst, TCGv src,
unsigned int fcc_offset)
{
+ TCGv t0 = tcg_temp_new();
gen_mov_reg_FCC0(dst, src, fcc_offset);
- tcg_gen_xori_tl(dst, dst, 0x1);
- gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
- tcg_gen_and_tl(dst, dst, cpu_tmp0);
+ gen_mov_reg_FCC1(t0, src, fcc_offset);
+ tcg_gen_andc_tl(dst, t0, dst);
+ tcg_temp_free(t0);
}
// 3: FCC0 & FCC1
static inline void gen_op_eval_fbu(TCGv dst, TCGv src,
unsigned int fcc_offset)
{
+ TCGv t0 = tcg_temp_new();
gen_mov_reg_FCC0(dst, src, fcc_offset);
- gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
- tcg_gen_and_tl(dst, dst, cpu_tmp0);
+ gen_mov_reg_FCC1(t0, src, fcc_offset);
+ tcg_gen_and_tl(dst, dst, t0);
+ tcg_temp_free(t0);
}
// 0: !(FCC0 | FCC1)
static inline void gen_op_eval_fbe(TCGv dst, TCGv src,
unsigned int fcc_offset)
{
+ TCGv t0 = tcg_temp_new();
gen_mov_reg_FCC0(dst, src, fcc_offset);
- gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
- tcg_gen_or_tl(dst, dst, cpu_tmp0);
+ gen_mov_reg_FCC1(t0, src, fcc_offset);
+ tcg_gen_or_tl(dst, dst, t0);
tcg_gen_xori_tl(dst, dst, 0x1);
+ tcg_temp_free(t0);
}
// 0 or 3: !(FCC0 ^ FCC1)
static inline void gen_op_eval_fbue(TCGv dst, TCGv src,
unsigned int fcc_offset)
{
+ TCGv t0 = tcg_temp_new();
gen_mov_reg_FCC0(dst, src, fcc_offset);
- gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
- tcg_gen_xor_tl(dst, dst, cpu_tmp0);
+ gen_mov_reg_FCC1(t0, src, fcc_offset);
+ tcg_gen_xor_tl(dst, dst, t0);
tcg_gen_xori_tl(dst, dst, 0x1);
+ tcg_temp_free(t0);
}
// 0 or 2: !FCC0
static inline void gen_op_eval_fbuge(TCGv dst, TCGv src,
unsigned int fcc_offset)
{
+ TCGv t0 = tcg_temp_new();
gen_mov_reg_FCC0(dst, src, fcc_offset);
- gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
- tcg_gen_xori_tl(cpu_tmp0, cpu_tmp0, 0x1);
- tcg_gen_and_tl(dst, dst, cpu_tmp0);
+ gen_mov_reg_FCC1(t0, src, fcc_offset);
+ tcg_gen_andc_tl(dst, dst, t0);
tcg_gen_xori_tl(dst, dst, 0x1);
+ tcg_temp_free(t0);
}
// 0 or 1: !FCC1
static inline void gen_op_eval_fbule(TCGv dst, TCGv src,
unsigned int fcc_offset)
{
+ TCGv t0 = tcg_temp_new();
gen_mov_reg_FCC0(dst, src, fcc_offset);
+ gen_mov_reg_FCC1(t0, src, fcc_offset);
+ tcg_gen_andc_tl(dst, t0, dst);
tcg_gen_xori_tl(dst, dst, 0x1);
- gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
- tcg_gen_and_tl(dst, dst, cpu_tmp0);
- tcg_gen_xori_tl(dst, dst, 0x1);
+ tcg_temp_free(t0);
}
// !3: !(FCC0 & FCC1)
static inline void gen_op_eval_fbo(TCGv dst, TCGv src,
unsigned int fcc_offset)
{
+ TCGv t0 = tcg_temp_new();
gen_mov_reg_FCC0(dst, src, fcc_offset);
- gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
- tcg_gen_and_tl(dst, dst, cpu_tmp0);
+ gen_mov_reg_FCC1(t0, src, fcc_offset);
+ tcg_gen_and_tl(dst, dst, t0);
tcg_gen_xori_tl(dst, dst, 0x1);
+ tcg_temp_free(t0);
}
static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
}
opc = GET_FIELD(insn, 0, 1);
-
rd = GET_FIELD(insn, 2, 6);
switch (opc) {
case 2: /* FPU & Logical Operations */
{
unsigned int xop = GET_FIELD(insn, 7, 12);
+ TCGv cpu_dst = get_temp_tl(dc);
+ TCGv cpu_tmp0;
+
if (xop == 0x3a) { /* generate trap */
int cond = GET_FIELD(insn, 3, 6);
TCGv_i32 trap;
gen_store_gpr(dc, rd, cpu_dst);
break;
} else if (xop == 0x2a) { /* rdwim / V9 rdpr */
- if (!supervisor(dc))
+ if (!supervisor(dc)) {
goto priv_insn;
+ }
+ cpu_tmp0 = get_temp_tl(dc);
#ifdef TARGET_SPARC64
rs1 = GET_FIELD(insn, 13, 17);
switch (rs1) {
#define FMOVR(sz) \
do { \
DisasCompare cmp; \
- cond = GET_FIELD_SP(insn, 14, 17); \
+ cond = GET_FIELD_SP(insn, 10, 12); \
cpu_src1 = get_src1(dc, insn); \
gen_compare_reg(&cmp, cond, cpu_src1); \
gen_fmov##sz(dc, &cmp, rd, rs2); \
} else { /* register */
rs2 = GET_FIELD(insn, 27, 31);
cpu_src2 = gen_load_gpr(dc, rs2);
+ cpu_tmp0 = get_temp_tl(dc);
if (insn & (1 << 12)) {
tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
} else {
} else { /* register */
rs2 = GET_FIELD(insn, 27, 31);
cpu_src2 = gen_load_gpr(dc, rs2);
+ cpu_tmp0 = get_temp_tl(dc);
if (insn & (1 << 12)) {
tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
tcg_gen_shr_i64(cpu_dst, cpu_src1, cpu_tmp0);
} else { /* register */
rs2 = GET_FIELD(insn, 27, 31);
cpu_src2 = gen_load_gpr(dc, rs2);
+ cpu_tmp0 = get_temp_tl(dc);
if (insn & (1 << 12)) {
tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
tcg_gen_sar_i64(cpu_dst, cpu_src1, cpu_tmp0);
simm = GET_FIELDs(insn, 20, 31);
tcg_gen_shli_tl(cpu_dst, cpu_src1, simm & 0x1f);
} else { /* register */
+ cpu_tmp0 = get_temp_tl(dc);
tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
tcg_gen_shl_tl(cpu_dst, cpu_src1, cpu_tmp0);
}
simm = GET_FIELDs(insn, 20, 31);
tcg_gen_shri_tl(cpu_dst, cpu_src1, simm & 0x1f);
} else { /* register */
+ cpu_tmp0 = get_temp_tl(dc);
tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
tcg_gen_shr_tl(cpu_dst, cpu_src1, cpu_tmp0);
}
simm = GET_FIELDs(insn, 20, 31);
tcg_gen_sari_tl(cpu_dst, cpu_src1, simm & 0x1f);
} else { /* register */
+ cpu_tmp0 = get_temp_tl(dc);
tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
tcg_gen_sar_tl(cpu_dst, cpu_src1, cpu_tmp0);
}
#endif
case 0x30:
{
+ cpu_tmp0 = get_temp_tl(dc);
switch(rd) {
case 0: /* wry */
tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
in the SPARCv8
manual, nop on the
microSPARC II */
+ if ((rd == 0x13) && (dc->def->features &
+ CPU_FEATURE_POWERDOWN)) {
+ /* LEON3 power-down */
+ gen_helper_power_down(cpu_env);
+ }
break;
#else
case 0x2: /* V9 wrccr */
- tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
- gen_helper_wrccr(cpu_env, cpu_dst);
+ tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
+ gen_helper_wrccr(cpu_env, cpu_tmp0);
tcg_gen_movi_i32(cpu_cc_op, CC_OP_FLAGS);
dc->cc_op = CC_OP_FLAGS;
break;
case 0x3: /* V9 wrasi */
- tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
- tcg_gen_andi_tl(cpu_dst, cpu_dst, 0xff);
- tcg_gen_trunc_tl_i32(cpu_asi, cpu_dst);
+ tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
+ tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xff);
+ tcg_gen_trunc_tl_i32(cpu_asi, cpu_tmp0);
break;
case 0x6: /* V9 wrfprs */
- tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
- tcg_gen_trunc_tl_i32(cpu_fprs, cpu_dst);
+ tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
+ tcg_gen_trunc_tl_i32(cpu_fprs, cpu_tmp0);
save_state(dc);
gen_op_next_insn();
tcg_gen_exit_tb(0);
case 0x14: /* Softint set */
if (!supervisor(dc))
goto illegal_insn;
- tcg_gen_xor_tl(cpu_tmp64, cpu_src1, cpu_src2);
- gen_helper_set_softint(cpu_env, cpu_tmp64);
+ tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
+ gen_helper_set_softint(cpu_env, cpu_tmp0);
break;
case 0x15: /* Softint clear */
if (!supervisor(dc))
goto illegal_insn;
- tcg_gen_xor_tl(cpu_tmp64, cpu_src1, cpu_src2);
- gen_helper_clear_softint(cpu_env, cpu_tmp64);
+ tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
+ gen_helper_clear_softint(cpu_env, cpu_tmp0);
break;
case 0x16: /* Softint write */
if (!supervisor(dc))
goto illegal_insn;
- tcg_gen_xor_tl(cpu_tmp64, cpu_src1, cpu_src2);
- gen_helper_write_softint(cpu_env, cpu_tmp64);
+ tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
+ gen_helper_write_softint(cpu_env, cpu_tmp0);
break;
case 0x17: /* Tick compare */
#if !defined(CONFIG_USER_ONLY)
{
TCGv_ptr r_tickptr;
- tcg_gen_xor_tl(cpu_dst, cpu_src1,
+ tcg_gen_xor_tl(cpu_tmp0, cpu_src1,
cpu_src2);
r_tickptr = tcg_temp_new_ptr();
tcg_gen_ld_ptr(r_tickptr, cpu_env,
offsetof(CPUSPARCState, stick));
gen_helper_tick_set_count(r_tickptr,
- cpu_dst);
+ cpu_tmp0);
tcg_temp_free_ptr(r_tickptr);
}
break;
goto illegal_insn;
}
#else
- tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
- gen_helper_wrpsr(cpu_env, cpu_dst);
+ cpu_tmp0 = get_temp_tl(dc);
+ tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
+ gen_helper_wrpsr(cpu_env, cpu_tmp0);
tcg_gen_movi_i32(cpu_cc_op, CC_OP_FLAGS);
dc->cc_op = CC_OP_FLAGS;
save_state(dc);
{
if (!supervisor(dc))
goto priv_insn;
+ cpu_tmp0 = get_temp_tl(dc);
tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
#ifdef TARGET_SPARC64
switch (rd) {
CHECK_IU_FEATURE(dc, HYPV);
if (!hypervisor(dc))
goto priv_insn;
+ cpu_tmp0 = get_temp_tl(dc);
tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
switch (rd) {
case 0: // hpstate
save_state(dc);
cpu_src1 = get_src1(dc, insn);
+ cpu_tmp0 = get_temp_tl(dc);
if (IS_IMM) { /* immediate */
simm = GET_FIELDs(insn, 19, 31);
- tcg_gen_addi_tl(cpu_dst, cpu_src1, simm);
+ tcg_gen_addi_tl(cpu_tmp0, cpu_src1, simm);
} else { /* register */
rs2 = GET_FIELD(insn, 27, 31);
if (rs2) {
cpu_src2 = gen_load_gpr(dc, rs2);
- tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
+ tcg_gen_add_tl(cpu_tmp0, cpu_src1, cpu_src2);
} else {
- tcg_gen_mov_tl(cpu_dst, cpu_src1);
+ tcg_gen_mov_tl(cpu_tmp0, cpu_src1);
}
}
gen_helper_restore(cpu_env);
gen_mov_pc_npc(dc);
r_const = tcg_const_i32(3);
- gen_helper_check_align(cpu_env, cpu_dst, r_const);
+ gen_helper_check_align(cpu_env, cpu_tmp0, r_const);
tcg_temp_free_i32(r_const);
- tcg_gen_mov_tl(cpu_npc, cpu_dst);
+ tcg_gen_mov_tl(cpu_npc, cpu_tmp0);
dc->npc = DYNAMIC_PC;
goto jmp_insn;
#endif
} else {
cpu_src1 = get_src1(dc, insn);
+ cpu_tmp0 = get_temp_tl(dc);
if (IS_IMM) { /* immediate */
simm = GET_FIELDs(insn, 19, 31);
- tcg_gen_addi_tl(cpu_dst, cpu_src1, simm);
+ tcg_gen_addi_tl(cpu_tmp0, cpu_src1, simm);
} else { /* register */
rs2 = GET_FIELD(insn, 27, 31);
if (rs2) {
cpu_src2 = gen_load_gpr(dc, rs2);
- tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
+ tcg_gen_add_tl(cpu_tmp0, cpu_src1, cpu_src2);
} else {
- tcg_gen_mov_tl(cpu_dst, cpu_src1);
+ tcg_gen_mov_tl(cpu_tmp0, cpu_src1);
}
}
switch (xop) {
gen_store_gpr(dc, rd, t);
gen_mov_pc_npc(dc);
r_const = tcg_const_i32(3);
- gen_helper_check_align(cpu_env, cpu_dst, r_const);
+ gen_helper_check_align(cpu_env, cpu_tmp0, r_const);
tcg_temp_free_i32(r_const);
- gen_address_mask(dc, cpu_dst);
- tcg_gen_mov_tl(cpu_npc, cpu_dst);
+ gen_address_mask(dc, cpu_tmp0);
+ tcg_gen_mov_tl(cpu_npc, cpu_tmp0);
dc->npc = DYNAMIC_PC;
}
goto jmp_insn;
goto priv_insn;
gen_mov_pc_npc(dc);
r_const = tcg_const_i32(3);
- gen_helper_check_align(cpu_env, cpu_dst, r_const);
+ gen_helper_check_align(cpu_env, cpu_tmp0, r_const);
tcg_temp_free_i32(r_const);
- tcg_gen_mov_tl(cpu_npc, cpu_dst);
+ tcg_gen_mov_tl(cpu_npc, cpu_tmp0);
dc->npc = DYNAMIC_PC;
gen_helper_rett(cpu_env);
}
case 0x3c: /* save */
save_state(dc);
gen_helper_save(cpu_env);
- gen_store_gpr(dc, rd, cpu_dst);
+ gen_store_gpr(dc, rd, cpu_tmp0);
break;
case 0x3d: /* restore */
save_state(dc);
gen_helper_restore(cpu_env);
- gen_store_gpr(dc, rd, cpu_dst);
+ gen_store_gpr(dc, rd, cpu_tmp0);
break;
#if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
case 0x3e: /* V9 done/retry */
goto illegal_insn;
else {
TCGv_i32 r_const;
+ TCGv_i64 t64;
save_state(dc);
r_const = tcg_const_i32(7);
gen_helper_check_align(cpu_env, cpu_addr, r_const);
tcg_temp_free_i32(r_const);
gen_address_mask(dc, cpu_addr);
- tcg_gen_qemu_ld64(cpu_tmp64, cpu_addr, dc->mem_idx);
- tcg_gen_trunc_i64_tl(cpu_tmp0, cpu_tmp64);
- tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xffffffffULL);
- gen_store_gpr(dc, rd + 1, cpu_tmp0);
- tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
- tcg_gen_trunc_i64_tl(cpu_val, cpu_tmp64);
- tcg_gen_andi_tl(cpu_val, cpu_val, 0xffffffffULL);
+ t64 = tcg_temp_new_i64();
+ tcg_gen_qemu_ld64(t64, cpu_addr, dc->mem_idx);
+ tcg_gen_trunc_i64_tl(cpu_val, t64);
+ tcg_gen_ext32u_tl(cpu_val, cpu_val);
+ gen_store_gpr(dc, rd + 1, cpu_val);
+ tcg_gen_shri_i64(t64, t64, 32);
+ tcg_gen_trunc_i64_tl(cpu_val, t64);
+ tcg_temp_free_i64(t64);
+ tcg_gen_ext32u_tl(cpu_val, cpu_val);
}
break;
case 0x9: /* ldsb, load signed byte */
tcg_temp_free(r_const);
}
break;
- case 0x0f: /* swap, swap register with memory. Also
- atomically */
- CHECK_IU_FEATURE(dc, SWAP);
- cpu_src1 = gen_load_gpr(dc, rd);
- gen_address_mask(dc, cpu_addr);
- tcg_gen_qemu_ld32u(cpu_tmp0, cpu_addr, dc->mem_idx);
- tcg_gen_qemu_st32(cpu_src1, cpu_addr, dc->mem_idx);
- tcg_gen_mov_tl(cpu_val, cpu_tmp0);
+ case 0x0f:
+ /* swap, swap register with memory. Also atomically */
+ {
+ TCGv t0 = get_temp_tl(dc);
+ CHECK_IU_FEATURE(dc, SWAP);
+ cpu_src1 = gen_load_gpr(dc, rd);
+ gen_address_mask(dc, cpu_addr);
+ tcg_gen_qemu_ld32u(t0, cpu_addr, dc->mem_idx);
+ tcg_gen_qemu_st32(cpu_src1, cpu_addr, dc->mem_idx);
+ tcg_gen_mov_tl(cpu_val, t0);
+ }
break;
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
case 0x10: /* lda, V9 lduwa, load word alternate */
skip_move: ;
#endif
} else if (xop >= 0x20 && xop < 0x24) {
+ TCGv t0;
+
if (gen_trap_ifnofpu(dc)) {
goto jmp_insn;
}
switch (xop) {
case 0x20: /* ldf, load fpreg */
gen_address_mask(dc, cpu_addr);
- tcg_gen_qemu_ld32u(cpu_tmp0, cpu_addr, dc->mem_idx);
+ t0 = get_temp_tl(dc);
+ tcg_gen_qemu_ld32u(t0, cpu_addr, dc->mem_idx);
cpu_dst_32 = gen_dest_fpr_F(dc);
- tcg_gen_trunc_tl_i32(cpu_dst_32, cpu_tmp0);
+ tcg_gen_trunc_tl_i32(cpu_dst_32, t0);
gen_store_fpr_F(dc, rd, cpu_dst_32);
break;
case 0x21: /* ldfsr, V9 ldxfsr */
#ifdef TARGET_SPARC64
gen_address_mask(dc, cpu_addr);
if (rd == 1) {
- tcg_gen_qemu_ld64(cpu_tmp64, cpu_addr, dc->mem_idx);
- gen_helper_ldxfsr(cpu_env, cpu_tmp64);
+ TCGv_i64 t64 = tcg_temp_new_i64();
+ tcg_gen_qemu_ld64(t64, cpu_addr, dc->mem_idx);
+ gen_helper_ldxfsr(cpu_env, t64);
+ tcg_temp_free_i64(t64);
break;
}
#endif
- {
- TCGv_i32 t32 = get_temp_i32(dc);
- tcg_gen_qemu_ld32u(cpu_tmp0, cpu_addr, dc->mem_idx);
- tcg_gen_trunc_tl_i32(t32, cpu_tmp0);
- gen_helper_ldfsr(cpu_env, t32);
- }
+ cpu_dst_32 = get_temp_i32(dc);
+ t0 = get_temp_tl(dc);
+ tcg_gen_qemu_ld32u(t0, cpu_addr, dc->mem_idx);
+ tcg_gen_trunc_tl_i32(cpu_dst_32, t0);
+ gen_helper_ldfsr(cpu_env, cpu_dst_32);
break;
case 0x22: /* ldqf, load quad fpreg */
{
goto illegal_insn;
else {
TCGv_i32 r_const;
+ TCGv_i64 t64;
TCGv lo;
save_state(dc);
gen_helper_check_align(cpu_env, cpu_addr, r_const);
tcg_temp_free_i32(r_const);
lo = gen_load_gpr(dc, rd + 1);
- tcg_gen_concat_tl_i64(cpu_tmp64, lo, cpu_val);
- tcg_gen_qemu_st64(cpu_tmp64, cpu_addr, dc->mem_idx);
+
+ t64 = tcg_temp_new_i64();
+ tcg_gen_concat_tl_i64(t64, lo, cpu_val);
+ tcg_gen_qemu_st64(t64, cpu_addr, dc->mem_idx);
+ tcg_temp_free_i64(t64);
}
break;
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
save_state(dc);
switch (xop) {
case 0x24: /* stf, store fpreg */
- gen_address_mask(dc, cpu_addr);
- cpu_src1_32 = gen_load_fpr_F(dc, rd);
- tcg_gen_ext_i32_tl(cpu_tmp0, cpu_src1_32);
- tcg_gen_qemu_st32(cpu_tmp0, cpu_addr, dc->mem_idx);
+ {
+ TCGv t = get_temp_tl(dc);
+ gen_address_mask(dc, cpu_addr);
+ cpu_src1_32 = gen_load_fpr_F(dc, rd);
+ tcg_gen_ext_i32_tl(t, cpu_src1_32);
+ tcg_gen_qemu_st32(t, cpu_addr, dc->mem_idx);
+ }
break;
case 0x25: /* stfsr, V9 stxfsr */
{
}
}
-static inline void gen_intermediate_code_internal(TranslationBlock * tb,
- int spc, CPUSPARCState *env)
+static inline void gen_intermediate_code_internal(SPARCCPU *cpu,
+ TranslationBlock *tb,
+ bool spc)
{
+ CPUSPARCState *env = &cpu->env;
target_ulong pc_start, last_pc;
uint16_t *gen_opc_end;
DisasContext dc1, *dc = &dc1;
dc->fpu_enabled = tb_fpu_enabled(tb->flags);
dc->address_mask_32bit = tb_am_enabled(tb->flags);
dc->singlestep = (env->singlestep_enabled || singlestep);
- gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
+ gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
num_insns = 0;
max_insns = tb->cflags & CF_COUNT_MASK;
if (max_insns == 0)
max_insns = CF_COUNT_MASK;
- gen_icount_start();
+ gen_tb_start();
do {
if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
}
if (spc) {
qemu_log("Search PC...\n");
- j = gen_opc_ptr - gen_opc_buf;
+ j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
if (lj < j) {
lj++;
while (lj < j)
- gen_opc_instr_start[lj++] = 0;
- gen_opc_pc[lj] = dc->pc;
+ tcg_ctx.gen_opc_instr_start[lj++] = 0;
+ tcg_ctx.gen_opc_pc[lj] = dc->pc;
gen_opc_npc[lj] = dc->npc;
- gen_opc_instr_start[lj] = 1;
- gen_opc_icount[lj] = num_insns;
+ tcg_ctx.gen_opc_instr_start[lj] = 1;
+ tcg_ctx.gen_opc_icount[lj] = num_insns;
}
}
if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
last_pc = dc->pc;
insn = cpu_ldl_code(env, dc->pc);
- cpu_tmp0 = tcg_temp_new();
- cpu_tmp64 = tcg_temp_new_i64();
- cpu_dst = tcg_temp_new();
-
disas_sparc_insn(dc, insn);
num_insns++;
- tcg_temp_free(cpu_dst);
- tcg_temp_free_i64(cpu_tmp64);
- tcg_temp_free(cpu_tmp0);
-
if (dc->is_br)
break;
/* if the next PC is different, we abort now */
if (dc->singlestep) {
break;
}
- } while ((gen_opc_ptr < gen_opc_end) &&
+ } while ((tcg_ctx.gen_opc_ptr < gen_opc_end) &&
(dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32) &&
num_insns < max_insns);
tcg_gen_exit_tb(0);
}
}
- gen_icount_end(tb, num_insns);
- *gen_opc_ptr = INDEX_op_end;
+ gen_tb_end(tb, num_insns);
+ *tcg_ctx.gen_opc_ptr = INDEX_op_end;
if (spc) {
- j = gen_opc_ptr - gen_opc_buf;
+ j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
lj++;
while (lj <= j)
- gen_opc_instr_start[lj++] = 0;
+ tcg_ctx.gen_opc_instr_start[lj++] = 0;
#if 0
log_page_dump();
#endif
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
qemu_log("--------------\n");
qemu_log("IN: %s\n", lookup_symbol(pc_start));
- log_target_disas(pc_start, last_pc + 4 - pc_start, 0);
+ log_target_disas(env, pc_start, last_pc + 4 - pc_start, 0);
qemu_log("\n");
}
#endif
void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
{
- gen_intermediate_code_internal(tb, 0, env);
+ gen_intermediate_code_internal(sparc_env_get_cpu(env), tb, false);
}
void gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
{
- gen_intermediate_code_internal(tb, 1, env);
+ gen_intermediate_code_internal(sparc_env_get_cpu(env), tb, true);
}
void gen_intermediate_code_init(CPUSPARCState *env)
void restore_state_to_opc(CPUSPARCState *env, TranslationBlock *tb, int pc_pos)
{
target_ulong npc;
- env->pc = gen_opc_pc[pc_pos];
+ env->pc = tcg_ctx.gen_opc_pc[pc_pos];
npc = gen_opc_npc[pc_pos];
if (npc == 1) {
/* dynamic NPC: already stored */