* <http://www.gnu.org/licenses/lgpl-2.1.html>
*/
+#include "qemu/osdep.h"
#include "cpu.h"
#include "qemu/log.h"
+#include "exec/log.h"
#include "disas/disas.h"
+#include "exec/exec-all.h"
#include "tcg-op.h"
#include "exec/cpu_ldst.h"
#include "linux-user/syscall_defs.h"
#define FMT64X "%016" PRIx64
-static TCGv_ptr cpu_env;
+static TCGv_env cpu_env;
static TCGv cpu_pc;
static TCGv cpu_regs[TILEGX_R_COUNT];
unsigned srcbdest = get_SrcBDest_Y2(bundle);
const char *mnemonic;
TCGMemOp memop;
+ bool prefetch_nofault = false;
switch (OEY2(opc, mode)) {
case OEY2(LD1S_OPCODE_Y2, MODE_OPCODE_YA2):
memop = MO_SB;
- mnemonic = "ld1s";
+ mnemonic = "ld1s"; /* prefetch_l1_fault */
goto do_load;
case OEY2(LD1U_OPCODE_Y2, MODE_OPCODE_YA2):
memop = MO_UB;
- mnemonic = "ld1u";
+ mnemonic = "ld1u"; /* prefetch, prefetch_l1 */
+ prefetch_nofault = (srcbdest == TILEGX_R_ZERO);
goto do_load;
case OEY2(LD2S_OPCODE_Y2, MODE_OPCODE_YA2):
memop = MO_TESW;
- mnemonic = "ld2s";
+ mnemonic = "ld2s"; /* prefetch_l2_fault */
goto do_load;
case OEY2(LD2U_OPCODE_Y2, MODE_OPCODE_YA2):
memop = MO_TEUW;
- mnemonic = "ld2u";
+ mnemonic = "ld2u"; /* prefetch_l2 */
+ prefetch_nofault = (srcbdest == TILEGX_R_ZERO);
goto do_load;
case OEY2(LD4S_OPCODE_Y2, MODE_OPCODE_YB2):
memop = MO_TESL;
- mnemonic = "ld4s";
+ mnemonic = "ld4s"; /* prefetch_l3_fault */
goto do_load;
case OEY2(LD4U_OPCODE_Y2, MODE_OPCODE_YB2):
memop = MO_TEUL;
- mnemonic = "ld4u";
+ mnemonic = "ld4u"; /* prefetch_l3 */
+ prefetch_nofault = (srcbdest == TILEGX_R_ZERO);
goto do_load;
case OEY2(LD_OPCODE_Y2, MODE_OPCODE_YB2):
memop = MO_TEQ;
mnemonic = "ld";
do_load:
- tcg_gen_qemu_ld_tl(dest_gr(dc, srcbdest), load_gr(dc, srca),
- dc->mmuidx, memop);
+ if (!prefetch_nofault) {
+ tcg_gen_qemu_ld_tl(dest_gr(dc, srcbdest), load_gr(dc, srca),
+ dc->mmuidx, memop);
+ }
qemu_log_mask(CPU_LOG_TB_IN_ASM, "%s %s, %s", mnemonic,
reg_names[srcbdest], reg_names[srca]);
return TILEGX_EXCP_NONE;
}
dc->num_wb = 0;
- if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
- tcg_gen_debug_insn_start(dc->pc);
- }
-
qemu_log_mask(CPU_LOG_TB_IN_ASM, " %" PRIx64 ": { ", dc->pc);
if (get_Mode(bundle)) {
notice_excp(dc, bundle, "y0", decode_y0(dc, bundle));
}
}
-static inline void gen_intermediate_code_internal(TileGXCPU *cpu,
- TranslationBlock *tb,
- bool search_pc)
+void gen_intermediate_code(CPUTLGState *env, struct TranslationBlock *tb)
{
+ TileGXCPU *cpu = tilegx_env_get_cpu(env);
DisasContext ctx;
DisasContext *dc = &ctx;
CPUState *cs = CPU(cpu);
- CPUTLGState *env = &cpu->env;
uint64_t pc_start = tb->pc;
uint64_t next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
- int j, lj = -1;
int num_insns = 0;
int max_insns = tb->cflags & CF_COUNT_MASK;
if (cs->singlestep_enabled || singlestep) {
max_insns = 1;
}
+ if (max_insns > TCG_MAX_INSNS) {
+ max_insns = TCG_MAX_INSNS;
+ }
gen_tb_start(tb);
while (1) {
- if (search_pc) {
- j = tcg_op_buf_count();
- if (lj < j) {
- lj++;
- while (lj < j) {
- tcg_ctx.gen_opc_instr_start[lj++] = 0;
- }
- }
- tcg_ctx.gen_opc_pc[lj] = dc->pc;
- tcg_ctx.gen_opc_instr_start[lj] = 1;
- tcg_ctx.gen_opc_icount[lj] = num_insns;
- }
+ tcg_gen_insn_start(dc->pc);
+ num_insns++;
+
translate_one_bundle(dc, cpu_ldq_data(env, dc->pc));
if (dc->exit_tb) {
break;
}
dc->pc += TILEGX_BUNDLE_SIZE_IN_BYTES;
- if (++num_insns >= max_insns
+ if (num_insns >= max_insns
|| dc->pc >= next_page_start
|| tcg_op_buf_full()) {
/* Ending the TB due to TB size or page boundary. Set PC. */
}
gen_tb_end(tb, num_insns);
- if (search_pc) {
- j = tcg_op_buf_count();
- lj++;
- while (lj <= j) {
- tcg_ctx.gen_opc_instr_start[lj++] = 0;
- }
- } else {
- tb->size = dc->pc - pc_start;
- tb->icount = num_insns;
- }
+ tb->size = dc->pc - pc_start;
+ tb->icount = num_insns;
qemu_log_mask(CPU_LOG_TB_IN_ASM, "\n");
}
-void gen_intermediate_code(CPUTLGState *env, struct TranslationBlock *tb)
-{
- gen_intermediate_code_internal(tilegx_env_get_cpu(env), tb, false);
-}
-
-void gen_intermediate_code_pc(CPUTLGState *env, struct TranslationBlock *tb)
-{
- gen_intermediate_code_internal(tilegx_env_get_cpu(env), tb, true);
-}
-
-void restore_state_to_opc(CPUTLGState *env, TranslationBlock *tb, int pc_pos)
+void restore_state_to_opc(CPUTLGState *env, TranslationBlock *tb,
+ target_ulong *data)
{
- env->pc = tcg_ctx.gen_opc_pc[pc_pos];
+ env->pc = data[0];
}
void tilegx_tcg_init(void)
int i;
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
- cpu_pc = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUTLGState, pc), "pc");
+ cpu_pc = tcg_global_mem_new_i64(cpu_env, offsetof(CPUTLGState, pc), "pc");
for (i = 0; i < TILEGX_R_COUNT; i++) {
- cpu_regs[i] = tcg_global_mem_new_i64(TCG_AREG0,
+ cpu_regs[i] = tcg_global_mem_new_i64(cpu_env,
offsetof(CPUTLGState, regs[i]),
reg_names[i]);
}