won't fit in a TCGv or TCGv_i64, so we pass TCGv_ptr variables to pass the
address to helper functions. Here's an example for an HVX vector-add-word
istruction.
- static void generate_V6_vaddw(
- CPUHexagonState *env,
- DisasContext *ctx,
- Insn *insn,
- Packet *pkt)
+ static void generate_V6_vaddw(DisasContext *ctx)
{
+ Insn *insn __attribute__((unused)) = ctx->insn;
const int VdN = insn->regno[0];
const intptr_t VdV_off =
ctx_future_vreg_off(ctx, VdN, 1, true);
TCGv_ptr VvV = tcg_temp_new_ptr();
tcg_gen_addi_ptr(VuV, cpu_env, VuV_off);
tcg_gen_addi_ptr(VvV, cpu_env, VvV_off);
- TCGv slot = tcg_constant_tl(insn->slot);
- gen_helper_V6_vaddw(cpu_env, VdV, VuV, VvV, slot);
- gen_log_vreg_write(ctx, VdV_off, VdN, EXT_DFL, insn->slot, false);
+ gen_helper_V6_vaddw(cpu_env, VdV, VuV, VvV);
}
Notice that we also generate a variable named <operand>_off for each operand of
Finally, we notice that the override doesn't use the TCGv_ptr variables, so
we don't generate them when an override is present. Here is what we generate
when the override is present.
- static void generate_V6_vaddw(
- CPUHexagonState *env,
- DisasContext *ctx,
- Insn *insn,
- Packet *pkt)
+ static void generate_V6_vaddw(DisasContext *ctx)
{
+ Insn *insn __attribute__((unused)) = ctx->insn;
const int VdN = insn->regno[0];
const intptr_t VdV_off =
ctx_future_vreg_off(ctx, VdN, 1, true);
const intptr_t VvV_off =
vreg_src_off(ctx, VvN);
fGEN_TCG_V6_vaddw({ fHIDE(int i;) fVFOREACH(32, i) { VdV.w[i] = VuV.w[i] + VvV.w[i] ; } });
- gen_log_vreg_write(ctx, VdV_off, VdN, EXT_DFL, insn->slot, false);
}
We also generate an analyze_<tag> function for each instruction. Currently,
VRegs Vector registers
future_VRegs Registers to be stored during packet commit
tmp_VRegs Temporary registers *not* stored during commit
- VRegs_updated Mask of predicated vector writes
QRegs Q (vector predicate) registers
future_QRegs Registers to be stored during packet commit
- QRegs_updated Mask of predicated vector writes
*** Debugging ***