Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Mips Tracewrap Support (WIP) #26

Draft
wants to merge 3 commits into
base: tracewrap-6.2.0
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/fpu/softfloat-types.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ this code that are retained.
#ifndef SOFTFLOAT_TYPES_H
#define SOFTFLOAT_TYPES_H

#include <stdint.h>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same - I believe it's unnecessary and should work without

#include <stdbool.h>

/*
* Software IEC/IEEE floating-point types.
*/
Expand Down
1 change: 1 addition & 0 deletions include/fpu/softfloat.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ typedef enum {

#include "fpu/softfloat-types.h"
#include "fpu/softfloat-helpers.h"
#include <stdbool.h>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary?


/*----------------------------------------------------------------------------
| Routine to raise any or all of the software IEC/IEEE floating-point
Expand Down
1 change: 1 addition & 0 deletions include/qemu/bswap.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef BSWAP_H
#define BSWAP_H

#include "osdep.h"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary change? It's preferable to keep unrelated changes to the minimum, so that updating the QEMU base would be easier.

#ifdef CONFIG_MACHINE_BSWAP_H
# include <sys/endian.h>
# include <machine/bswap.h>
Expand Down
3 changes: 2 additions & 1 deletion linux-user/mips/trace_info.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "frame_arch.h"
#include <stdint.h>

const uint64_t frame_arch = frame_arch_mips;
const uint64_t frame_mach = frame_mach_mipsisa32 ;
const uint64_t frame_mach = frame_mach_mipsisa32;
7 changes: 7 additions & 0 deletions linux-user/mips64/trace_info.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#pragma once

#include "frame_arch.h"
#include <stdint.h>

const uint64_t frame_arch = frame_arch_mips;
const uint64_t frame_mach = frame_mach_mipsisa64;
2 changes: 1 addition & 1 deletion qobject/block-qdict.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,8 @@ void qdict_array_split(QDict *src, QList **dst)
bool is_subqdict;
QDict *subqdict = NULL;
char indexstr[32], prefix[32];
size_t snprintf_ret;

size_t snprintf_ret;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary change

snprintf_ret = snprintf(indexstr, 32, "%u", i);
assert(snprintf_ret < 32);

Expand Down
4 changes: 2 additions & 2 deletions stubs/replay-tools.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ bool replay_events_enabled(void)
return false;
}

int64_t replay_save_clock(unsigned int kind, int64_t clock, int64_t raw_icount)
int64_t replay_save_clock(ReplayClockKind kind, int64_t clock, int64_t raw_icount)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see you imported the change from QEMU mainstream. Please cherry-pick the whole commit of theirs, it will make rebase easier.

{
abort();
return 0;
}

int64_t replay_read_clock(unsigned int kind, int64_t raw_icount)
int64_t replay_read_clock(ReplayClockKind kind, int64_t raw_icount)
{
abort();
return 0;
Expand Down
33 changes: 25 additions & 8 deletions target/mips/helper.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
DEF_HELPER_3(raise_exception_err, noreturn, env, i32, int)
DEF_HELPER_3(raise_exception_err, noreturn, env, i32, i32)
DEF_HELPER_2(raise_exception, noreturn, env, i32)
DEF_HELPER_1(raise_exception_debug, noreturn, env)

Expand All @@ -17,13 +17,30 @@ DEF_HELPER_3(lld, tl, env, tl, int)
#endif

#ifdef HAS_TRACEWRAP
DEF_HELPER_1(trace_newframe, void, tl)
DEF_HELPER_3(trace_endframe, void, env, tl, i32)
DEF_HELPER_2(trace_load_reg, void, i32, i32)
DEF_HELPER_2(trace_store_reg, void, i32, i32)
DEF_HELPER_3(trace_ld, void, env, i32, i32)
DEF_HELPER_3(trace_st, void, env, i32, i32)
#endif //HAS_TRACEWRAP
// trace being/end
DEF_HELPER_1(trace_newframe, void, i64)
DEF_HELPER_2(trace_endframe, void, env, i64)
DEF_HELPER_1(trace_mode, void, ptr)

// load/store registers
DEF_HELPER_2(trace_load_reg32, void, i32, i32)
DEF_HELPER_2(trace_store_reg32, void, i32, i32)

// load store memory operands
DEF_HELPER_3(trace_load_mem, void, i32, i32, i32)
DEF_HELPER_3(trace_store_mem, void, i32, i32, i32)
DEF_HELPER_3(trace_load_mem_i64, void, i32, i64, i32)
DEF_HELPER_3(trace_store_mem_i64, void, i32, i64, i32)
#ifdef TARGET_MIPS64
// load/store registers
DEF_HELPER_2(trace_load_reg64, void, i32, i64)
DEF_HELPER_2(trace_store_reg64, void, i32, i64)

// load store memory operands
DEF_HELPER_3(trace_load_mem64, void, i64, i64, i32)
DEF_HELPER_3(trace_store_mem64, void, i64, i64, i32)
#endif // TARGET_MIPS64
#endif // HAS_TRACEWRAP

DEF_HELPER_FLAGS_1(bitswap, TCG_CALL_NO_RWG_SE, tl, tl)
#ifdef TARGET_MIPS64
Expand Down
2 changes: 1 addition & 1 deletion target/mips/tcg/exception.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ target_ulong exception_resume_pc(CPUMIPSState *env)
}

void helper_raise_exception_err(CPUMIPSState *env, uint32_t exception,
int error_code)
uint32_t error_code)
{
do_raise_exception_err(env, exception, error_code, 0);
}
Expand Down
125 changes: 120 additions & 5 deletions target/mips/tcg/translate.c
Original file line number Diff line number Diff line change
Expand Up @@ -1224,6 +1224,100 @@ static const char regnames_LO[][4] = {
"LO0", "LO1", "LO2", "LO3",
};

/*
** Include useful headers and defines
*/
#ifdef HAS_TRACEWRAP
#include <frame_arch.h>
#endif // HAS_TRACEWRAP

static inline void gen_trace_newframe(uint64_t pc) {
#ifdef HAS_TRACEWRAP

// will contain machine type information
TCGv_i64 _pc = tcg_const_i64(pc);
gen_helper_trace_newframe(_pc);
tcg_temp_free_i64(_pc);

TCGv_ptr mt;
#ifdef TARGET_MIPS64
mt = tcg_const_ptr(FRAME_MODE_MIPS64);
#else // else this is TARGET_MIPS
mt = tcg_const_ptr(FRAME_MODE_MIPS);
#endif // TARGET_MIPS64

// set trace mode to mips64 or mips
gen_helper_trace_mode(mt);
tcg_temp_free_ptr(mt);

#endif // HAS_TRACEWRAP
}

static inline void gen_trace_endframe(uint64_t pc) {
#ifdef HAS_TRACEWRAP
TCGv_i64 _pc = tcg_const_i64(pc);
gen_helper_trace_endframe(cpu_env, _pc);
tcg_temp_free_i64(_pc);

#endif // HAS_TRACEWRAP
}

static void gen_trace_load_reg(int reg, TCGv var) {
#ifdef HAS_TRACEWRAP

TCGv_i32 r = tcg_const_i32(reg);
#ifdef TARGET_MIPS64
gen_helper_trace_load_reg64(r, var);
#else
gen_helper_trace_load_reg32(r, var);
#endif
tcg_temp_free_i32(r);

#endif // HAS_TRACEWRAP
}

static void gen_trace_store_reg(int reg, TCGv var) {
#ifdef HAS_TRACEWRAP

TCGv_i32 r = tcg_const_i32(reg);
#ifdef TARGET_MIPS64
gen_helper_trace_store_reg64(r, var);
#else
gen_helper_trace_store_reg32(r, var);
#endif
tcg_temp_free_i32(r);

#endif // HAS_TRACEWRAP
}

static void gen_trace_load_mem(TCGv addr, TCGv val, MemOp op) {
#ifdef HAS_TRACEWRAP

TCGv_i32 o = tcg_const_i32(op);
#ifdef TARGET_MIPS64
gen_helper_trace_load_mem64(addr, val, o);
#else
gen_helper_trace_load_mem(addr, val, o);
#endif
tcg_temp_free_i32(o);

#endif // HAS_TRACEWRAP
}

static void gen_trace_store_mem(TCGv addr, TCGv val, MemOp op) {
#ifdef HAS_TRACEWRAP

TCGv_i32 o = tcg_const_i32(op);
#ifdef TARGET_MIPS64
gen_helper_trace_store_mem64(addr, val, o);
#else
gen_helper_trace_store_mem(addr, val, o);
#endif
tcg_temp_free_i32(o);

#endif // HAS_TRACEWRAP
}

/* General purpose registers moves. */
void gen_load_gpr(TCGv t, int reg)
{
Expand All @@ -1232,13 +1326,17 @@ void gen_load_gpr(TCGv t, int reg)
} else {
tcg_gen_mov_tl(t, cpu_gpr[reg]);
}

gen_trace_load_reg(reg, t);
}

void gen_store_gpr(TCGv t, int reg)
{
if (reg != 0) {
tcg_gen_mov_tl(cpu_gpr[reg], t);
}

gen_trace_store_reg(reg, t);
}

#if defined(TARGET_MIPS64)
Expand All @@ -1249,13 +1347,17 @@ void gen_load_gpr_hi(TCGv_i64 t, int reg)
} else {
tcg_gen_mov_i64(t, cpu_gpr_hi[reg]);
}

gen_trace_load_reg(reg, t);
}

void gen_store_gpr_hi(TCGv_i64 t, int reg)
{
if (reg != 0) {
tcg_gen_mov_i64(cpu_gpr_hi[reg], t);
}

gen_trace_store_reg(reg, t);
}
#endif /* TARGET_MIPS64 */

Expand All @@ -1264,6 +1366,7 @@ static inline void gen_load_srsgpr(int from, int to)
{
TCGv t0 = tcg_temp_new();

// if from == r0 then just move 0
if (from == 0) {
tcg_gen_movi_tl(t0, 0);
} else {
Expand Down Expand Up @@ -16033,19 +16136,24 @@ static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
int insn_bytes;
int is_slot;

// get pc_next and start generating new traceframe
uint64_t pc_next = ctx->base.pc_next;
gen_trace_newframe(pc_next);

// translate depending on architecture
is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
if (ctx->insn_flags & ISA_NANOMIPS32) {
ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
ctx->opcode = translator_lduw(env, &ctx->base, pc_next);
insn_bytes = decode_isa_nanomips(env, ctx);
} else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
ctx->opcode = translator_ldl(env, &ctx->base, ctx->base.pc_next);
ctx->opcode = translator_ldl(env, &ctx->base, pc_next);
insn_bytes = 4;
decode_opc(env, ctx);
} else if (ctx->insn_flags & ASE_MICROMIPS) {
ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
ctx->opcode = translator_lduw(env, &ctx->base, pc_next);
insn_bytes = decode_isa_micromips(env, ctx);
} else if (ctx->insn_flags & ASE_MIPS16) {
ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
ctx->opcode = translator_lduw(env, &ctx->base, pc_next);
insn_bytes = decode_ase_mips16e(env, ctx);
} else {
gen_reserved_instruction(ctx);
Expand Down Expand Up @@ -16074,7 +16182,11 @@ static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
if (is_slot) {
gen_branch(ctx, insn_bytes);
}

// update pc for next instruction
// and get pc_next
ctx->base.pc_next += insn_bytes;
pc_next = ctx->base.pc_next;

if (ctx->base.is_jmp != DISAS_NEXT) {
return;
Expand All @@ -16085,10 +16197,13 @@ static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
* See mips_tr_init_disas_context about single-stepping a branch
* together with its delay slot.
*/
if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE
if (pc_next - ctx->page_start >= TARGET_PAGE_SIZE
&& !ctx->base.singlestep_enabled) {
ctx->base.is_jmp = DISAS_TOO_MANY;
}

// end the frame
gen_trace_endframe(pc_next);
}

static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
Expand Down
Loading