tcg-i386: Swap order of TLB hit and miss paths.
Make fallthru be TLB hit and branch be TLB miss. Doing this both improves branch prediction and will allow further cleanup. Signed-off-by: Richard Henderson <rth@twiddle.net> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
parent
be5a4eb7f0
commit
1a6dc1e406
@ -771,26 +771,21 @@ static void tcg_out_qemu_ld_direct(TCGContext *s, int datalo, int datahi,
|
|||||||
static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
|
static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
|
||||||
int opc)
|
int opc)
|
||||||
{
|
{
|
||||||
int addr_reg, data_reg, data_reg2, r0, r1, mem_index, s_bits;
|
int addr_reg, addr_reg2 = 0;
|
||||||
|
int data_reg, data_reg2 = 0;
|
||||||
|
int r0, r1, mem_index, s_bits;
|
||||||
#if defined(CONFIG_SOFTMMU)
|
#if defined(CONFIG_SOFTMMU)
|
||||||
uint8_t *label1_ptr, *label2_ptr;
|
uint8_t *label_ptr[3];
|
||||||
#endif
|
|
||||||
#if TARGET_LONG_BITS == 64
|
|
||||||
#if defined(CONFIG_SOFTMMU)
|
|
||||||
uint8_t *label3_ptr;
|
|
||||||
#endif
|
|
||||||
int addr_reg2;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
data_reg = *args++;
|
data_reg = *args++;
|
||||||
if (opc == 3)
|
if (opc == 3) {
|
||||||
data_reg2 = *args++;
|
data_reg2 = *args++;
|
||||||
else
|
}
|
||||||
data_reg2 = 0;
|
|
||||||
addr_reg = *args++;
|
addr_reg = *args++;
|
||||||
#if TARGET_LONG_BITS == 64
|
if (TARGET_LONG_BITS == 64) {
|
||||||
addr_reg2 = *args++;
|
addr_reg2 = *args++;
|
||||||
#endif
|
}
|
||||||
mem_index = *args;
|
mem_index = *args;
|
||||||
s_bits = opc & 3;
|
s_bits = opc & 3;
|
||||||
|
|
||||||
@ -815,28 +810,42 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
|
|||||||
|
|
||||||
tcg_out_mov(s, r0, addr_reg);
|
tcg_out_mov(s, r0, addr_reg);
|
||||||
|
|
||||||
#if TARGET_LONG_BITS == 32
|
/* jne label1 */
|
||||||
/* je label1 */
|
|
||||||
tcg_out8(s, OPC_JCC_short + JCC_JE);
|
|
||||||
label1_ptr = s->code_ptr;
|
|
||||||
s->code_ptr++;
|
|
||||||
#else
|
|
||||||
/* jne label3 */
|
|
||||||
tcg_out8(s, OPC_JCC_short + JCC_JNE);
|
tcg_out8(s, OPC_JCC_short + JCC_JNE);
|
||||||
label3_ptr = s->code_ptr;
|
label_ptr[0] = s->code_ptr;
|
||||||
s->code_ptr++;
|
s->code_ptr++;
|
||||||
|
|
||||||
/* cmp 4(r1), addr_reg2 */
|
if (TARGET_LONG_BITS == 64) {
|
||||||
tcg_out_modrm_offset(s, OPC_CMP_GvEv, addr_reg2, r1, 4);
|
/* cmp 4(r1), addr_reg2 */
|
||||||
|
tcg_out_modrm_offset(s, OPC_CMP_GvEv, addr_reg2, r1, 4);
|
||||||
|
|
||||||
/* je label1 */
|
/* jne label1 */
|
||||||
tcg_out8(s, OPC_JCC_short + JCC_JE);
|
tcg_out8(s, OPC_JCC_short + JCC_JNE);
|
||||||
label1_ptr = s->code_ptr;
|
label_ptr[1] = s->code_ptr;
|
||||||
|
s->code_ptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TLB Hit. */
|
||||||
|
|
||||||
|
/* add x(r1), r0 */
|
||||||
|
tcg_out_modrm_offset(s, OPC_ADD_GvEv, r0, r1,
|
||||||
|
offsetof(CPUTLBEntry, addend) -
|
||||||
|
offsetof(CPUTLBEntry, addr_read));
|
||||||
|
|
||||||
|
tcg_out_qemu_ld_direct(s, data_reg, data_reg2, r0, 0, opc);
|
||||||
|
|
||||||
|
/* jmp label2 */
|
||||||
|
tcg_out8(s, OPC_JMP_short);
|
||||||
|
label_ptr[2] = s->code_ptr;
|
||||||
s->code_ptr++;
|
s->code_ptr++;
|
||||||
|
|
||||||
/* label3: */
|
/* TLB Miss. */
|
||||||
*label3_ptr = s->code_ptr - label3_ptr - 1;
|
|
||||||
#endif
|
/* label1: */
|
||||||
|
*label_ptr[0] = s->code_ptr - label_ptr[0] - 1;
|
||||||
|
if (TARGET_LONG_BITS == 64) {
|
||||||
|
*label_ptr[1] = s->code_ptr - label_ptr[1] - 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* XXX: move that code at the end of the TB */
|
/* XXX: move that code at the end of the TB */
|
||||||
#if TARGET_LONG_BITS == 32
|
#if TARGET_LONG_BITS == 32
|
||||||
@ -876,23 +885,8 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* jmp label2 */
|
|
||||||
tcg_out8(s, OPC_JMP_short);
|
|
||||||
label2_ptr = s->code_ptr;
|
|
||||||
s->code_ptr++;
|
|
||||||
|
|
||||||
/* label1: */
|
|
||||||
*label1_ptr = s->code_ptr - label1_ptr - 1;
|
|
||||||
|
|
||||||
/* add x(r1), r0 */
|
|
||||||
tcg_out_modrm_offset(s, OPC_ADD_GvEv, r0, r1,
|
|
||||||
offsetof(CPUTLBEntry, addend) -
|
|
||||||
offsetof(CPUTLBEntry, addr_read));
|
|
||||||
|
|
||||||
tcg_out_qemu_ld_direct(s, data_reg, data_reg2, r0, 0, opc);
|
|
||||||
|
|
||||||
/* label2: */
|
/* label2: */
|
||||||
*label2_ptr = s->code_ptr - label2_ptr - 1;
|
*label_ptr[2] = s->code_ptr - label_ptr[2] - 1;
|
||||||
#else
|
#else
|
||||||
tcg_out_qemu_ld_direct(s, data_reg, data_reg2, addr_reg, GUEST_BASE, opc);
|
tcg_out_qemu_ld_direct(s, data_reg, data_reg2, addr_reg, GUEST_BASE, opc);
|
||||||
#endif
|
#endif
|
||||||
@ -955,27 +949,22 @@ static void tcg_out_qemu_st_direct(TCGContext *s, int datalo, int datahi,
|
|||||||
static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
|
static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
|
||||||
int opc)
|
int opc)
|
||||||
{
|
{
|
||||||
int addr_reg, data_reg, data_reg2, r0, r1, mem_index, s_bits;
|
int addr_reg, addr_reg2 = 0;
|
||||||
|
int data_reg, data_reg2 = 0;
|
||||||
|
int r0, r1, mem_index, s_bits;
|
||||||
#if defined(CONFIG_SOFTMMU)
|
#if defined(CONFIG_SOFTMMU)
|
||||||
int stack_adjust;
|
int stack_adjust;
|
||||||
uint8_t *label1_ptr, *label2_ptr;
|
uint8_t *label_ptr[3];
|
||||||
#endif
|
|
||||||
#if TARGET_LONG_BITS == 64
|
|
||||||
#if defined(CONFIG_SOFTMMU)
|
|
||||||
uint8_t *label3_ptr;
|
|
||||||
#endif
|
|
||||||
int addr_reg2;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
data_reg = *args++;
|
data_reg = *args++;
|
||||||
if (opc == 3)
|
if (opc == 3) {
|
||||||
data_reg2 = *args++;
|
data_reg2 = *args++;
|
||||||
else
|
}
|
||||||
data_reg2 = 0;
|
|
||||||
addr_reg = *args++;
|
addr_reg = *args++;
|
||||||
#if TARGET_LONG_BITS == 64
|
if (TARGET_LONG_BITS == 64) {
|
||||||
addr_reg2 = *args++;
|
addr_reg2 = *args++;
|
||||||
#endif
|
}
|
||||||
mem_index = *args;
|
mem_index = *args;
|
||||||
|
|
||||||
s_bits = opc;
|
s_bits = opc;
|
||||||
@ -1001,28 +990,42 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
|
|||||||
|
|
||||||
tcg_out_mov(s, r0, addr_reg);
|
tcg_out_mov(s, r0, addr_reg);
|
||||||
|
|
||||||
#if TARGET_LONG_BITS == 32
|
/* jne label1 */
|
||||||
/* je label1 */
|
|
||||||
tcg_out8(s, OPC_JCC_short + JCC_JE);
|
|
||||||
label1_ptr = s->code_ptr;
|
|
||||||
s->code_ptr++;
|
|
||||||
#else
|
|
||||||
/* jne label3 */
|
|
||||||
tcg_out8(s, OPC_JCC_short + JCC_JNE);
|
tcg_out8(s, OPC_JCC_short + JCC_JNE);
|
||||||
label3_ptr = s->code_ptr;
|
label_ptr[0] = s->code_ptr;
|
||||||
s->code_ptr++;
|
s->code_ptr++;
|
||||||
|
|
||||||
/* cmp 4(r1), addr_reg2 */
|
if (TARGET_LONG_BITS == 64) {
|
||||||
tcg_out_modrm_offset(s, OPC_CMP_GvEv, addr_reg2, r1, 4);
|
/* cmp 4(r1), addr_reg2 */
|
||||||
|
tcg_out_modrm_offset(s, OPC_CMP_GvEv, addr_reg2, r1, 4);
|
||||||
|
|
||||||
/* je label1 */
|
/* jne label1 */
|
||||||
tcg_out8(s, OPC_JCC_short + JCC_JE);
|
tcg_out8(s, OPC_JCC_short + JCC_JNE);
|
||||||
label1_ptr = s->code_ptr;
|
label_ptr[1] = s->code_ptr;
|
||||||
|
s->code_ptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TLB Hit. */
|
||||||
|
|
||||||
|
/* add x(r1), r0 */
|
||||||
|
tcg_out_modrm_offset(s, OPC_ADD_GvEv, r0, r1,
|
||||||
|
offsetof(CPUTLBEntry, addend) -
|
||||||
|
offsetof(CPUTLBEntry, addr_write));
|
||||||
|
|
||||||
|
tcg_out_qemu_st_direct(s, data_reg, data_reg2, r0, 0, opc);
|
||||||
|
|
||||||
|
/* jmp label2 */
|
||||||
|
tcg_out8(s, OPC_JMP_short);
|
||||||
|
label_ptr[2] = s->code_ptr;
|
||||||
s->code_ptr++;
|
s->code_ptr++;
|
||||||
|
|
||||||
/* label3: */
|
/* TLB Miss. */
|
||||||
*label3_ptr = s->code_ptr - label3_ptr - 1;
|
|
||||||
#endif
|
/* label1: */
|
||||||
|
*label_ptr[0] = s->code_ptr - label_ptr[0] - 1;
|
||||||
|
if (TARGET_LONG_BITS == 64) {
|
||||||
|
*label_ptr[1] = s->code_ptr - label_ptr[1] - 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* XXX: move that code at the end of the TB */
|
/* XXX: move that code at the end of the TB */
|
||||||
#if TARGET_LONG_BITS == 32
|
#if TARGET_LONG_BITS == 32
|
||||||
@ -1080,23 +1083,8 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
|
|||||||
tcg_out_addi(s, TCG_REG_ESP, stack_adjust);
|
tcg_out_addi(s, TCG_REG_ESP, stack_adjust);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* jmp label2 */
|
|
||||||
tcg_out8(s, OPC_JMP_short);
|
|
||||||
label2_ptr = s->code_ptr;
|
|
||||||
s->code_ptr++;
|
|
||||||
|
|
||||||
/* label1: */
|
|
||||||
*label1_ptr = s->code_ptr - label1_ptr - 1;
|
|
||||||
|
|
||||||
/* add x(r1), r0 */
|
|
||||||
tcg_out_modrm_offset(s, OPC_ADD_GvEv, r0, r1,
|
|
||||||
offsetof(CPUTLBEntry, addend) -
|
|
||||||
offsetof(CPUTLBEntry, addr_write));
|
|
||||||
|
|
||||||
tcg_out_qemu_st_direct(s, data_reg, data_reg2, r0, 0, opc);
|
|
||||||
|
|
||||||
/* label2: */
|
/* label2: */
|
||||||
*label2_ptr = s->code_ptr - label2_ptr - 1;
|
*label_ptr[2] = s->code_ptr - label_ptr[2] - 1;
|
||||||
#else
|
#else
|
||||||
tcg_out_qemu_st_direct(s, data_reg, data_reg2, addr_reg, GUEST_BASE, opc);
|
tcg_out_qemu_st_direct(s, data_reg, data_reg2, addr_reg, GUEST_BASE, opc);
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user