On 9/21/21 1:19 PM, WANG Xuerui wrote:
+ /* Compare masked address with the TLB entry. */
+ label_ptr[0] = s->code_ptr;
+ tcg_out_opc_bne(s, TCG_REG_TMP0, TCG_REG_TMP1, 0);
+
+ /* TLB Hit - translate address using addend. */
+ tcg_out_opc_add_d(s, TCG_REG_TMP0, TCG_REG_TMP2, addrl);
You removed a little too much here. You still need
if (TARGET_LONG_BITS == 32) {
tcg_out_ext32u(s, TCG_REG_TMP0, addrl);
addrl = TCG_REG_TMP0;
}
tcg_out_opc_add_d(s, TCG_REG_TMP0, TCG_REG_TMP2, addrl);
+static void add_qemu_ldst_label(TCGContext *s, int is_ld,
TCGMemOpIdx oi,
+ TCGReg datalo, TCGReg addrlo,
+ void *raddr, tcg_insn_unit **label_ptr)
+{
+ TCGLabelQemuLdst *label = new_ldst_label(s);
+
+ label->is_ld = is_ld;
+ label->oi = oi;
+ label->type = 0;
Type should be set based on "is_64" argument to tcg_out_qemu_ld (or
indeed, is_64 could be replaced by "type", which would probably make
more sense).
This will be used to fix...
+ if (opc & MO_SIGN) {
+ /* Sign-extend directly into destination. */
+ switch (size) {
+ case MO_8:
+ tcg_out_ext8s(s, l->datalo_reg, TCG_REG_A0);
+ break;
+ case MO_16:
+ tcg_out_ext16s(s, l->datalo_reg, TCG_REG_A0);
+ break;
+ case MO_32:
+ tcg_out_ext32s(s, l->datalo_reg, TCG_REG_A0);
+ break;
+ default:
+ g_assert_not_reached();
+ break;
+ }
+ } else {
+ tcg_out_mov(s, size == MO_64, l->datalo_reg, TCG_REG_A0);
+ }
... this, where TCG_TYPE_I32 loads should always be sign-extended from
32-bits. Something like
switch (opc & MO_SSIZE) {
case MO_SB:
ext8s;
break;
case MO_SH:
ext16s;
break;
case MO_SL:
ext32s;
break;
case MO_UL:
if (type == TCG_TYPE_I32) {
ext32s;
break;
}
/* fall through */
default:
tcg_out_mov(s, TCG_TYPE_REG, datalo, A0);
break;
}
+ if (USE_GUEST_BASE) {
+ tcg_out_opc_add_d(s, base, TCG_GUEST_BASE_REG, addr_regl);
+ } else {
+ tcg_out_opc_add_d(s, base, addr_regl, TCG_REG_ZERO);
+ }
Still adding zero in tcg_out_qemu_st.