mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-23 13:05:28 +00:00
tcg/aarch64: Enable indirect jump path using LDR (literal)
This patch enables the indirect jump path using an LDR (literal) instruction. It will be interesting to test and see which performs better among the two paths. Backports commit 2acee8b2b5e6bba2935bb6ce5be92d0f0f9799cb from qemu
This commit is contained in:
parent
5e9e39cafd
commit
57f8eec080
|
@ -273,6 +273,8 @@ typedef enum {
|
|||
I3207_BLR = 0xd63f0000,
|
||||
I3207_RET = 0xd65f0000,
|
||||
|
||||
/* Load literal for loading the address at pc-relative offset */
|
||||
I3305_LDR = 0x58000000,
|
||||
/* Load/store register. Described here as 3.3.12, but the helper
|
||||
that emits them can transform to 3.3.10 or 3.3.13. */
|
||||
I3312_STRB = 0x38000000 | LDST_ST << 22 | MO_8 << 30,
|
||||
|
@ -393,6 +395,11 @@ static inline uint32_t tcg_in32(TCGContext *s)
|
|||
#define tcg_out_insn(S, FMT, OP, ...) \
|
||||
glue(tcg_out_insn_,FMT)(S, glue(glue(glue(I,FMT),_),OP), ## __VA_ARGS__)
|
||||
|
||||
static void tcg_out_insn_3305(TCGContext *s, AArch64Insn insn, int imm19, TCGReg rt)
|
||||
{
|
||||
tcg_out32(s, insn | (imm19 & 0x7ffff) << 5 | rt);
|
||||
}
|
||||
|
||||
static void tcg_out_insn_3201(TCGContext *s, AArch64Insn insn, TCGType ext,
|
||||
TCGReg rt, int imm19)
|
||||
{
|
||||
|
@ -868,6 +875,8 @@ static inline void tcg_out_call(TCGContext *s, tcg_insn_unit *target)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef USE_DIRECT_JUMP
|
||||
|
||||
void aarch64_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr)
|
||||
{
|
||||
tcg_insn_unit i1, i2;
|
||||
|
@ -893,6 +902,8 @@ void aarch64_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr)
|
|||
flush_icache_range(jmp_addr, jmp_addr + 8);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static inline void tcg_out_goto_label(TCGContext *s, TCGLabel *l)
|
||||
{
|
||||
if (!l->has_value) {
|
||||
|
@ -1415,21 +1426,24 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
|
|||
break;
|
||||
|
||||
case INDEX_op_goto_tb:
|
||||
#ifndef USE_DIRECT_JUMP
|
||||
#error "USE_DIRECT_JUMP required for aarch64"
|
||||
#endif
|
||||
/* consistency for USE_DIRECT_JUMP */
|
||||
tcg_debug_assert(s->tb_jmp_insn_offset != NULL);
|
||||
/* Ensure that ADRP+ADD are 8-byte aligned so that an atomic
|
||||
write can be used to patch the target address. */
|
||||
if ((uintptr_t)s->code_ptr & 7) {
|
||||
tcg_out32(s, NOP);
|
||||
if (s->tb_jmp_insn_offset != NULL) {
|
||||
/* USE_DIRECT_JUMP */
|
||||
/* Ensure that ADRP+ADD are 8-byte aligned so that an atomic
|
||||
write can be used to patch the target address. */
|
||||
if ((uintptr_t)s->code_ptr & 7) {
|
||||
tcg_out32(s, NOP);
|
||||
}
|
||||
s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s);
|
||||
/* actual branch destination will be patched by
|
||||
aarch64_tb_set_jmp_target later. */
|
||||
tcg_out_insn(s, 3406, ADRP, TCG_REG_TMP, 0);
|
||||
tcg_out_insn(s, 3401, ADDI, TCG_TYPE_I64, TCG_REG_TMP, TCG_REG_TMP, 0);
|
||||
} else {
|
||||
/* !USE_DIRECT_JUMP */
|
||||
tcg_debug_assert(s->tb_jmp_target_addr != NULL);
|
||||
intptr_t offset = tcg_pcrel_diff(s, (s->tb_jmp_target_addr + a0)) >> 2;
|
||||
tcg_out_insn(s, 3305, LDR, offset, TCG_REG_TMP);
|
||||
}
|
||||
s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s);
|
||||
/* actual branch destination will be patched by
|
||||
aarch64_tb_set_jmp_target later. */
|
||||
tcg_out_insn(s, 3406, ADRP, TCG_REG_TMP, 0);
|
||||
tcg_out_insn(s, 3401, ADDI, TCG_TYPE_I64, TCG_REG_TMP, TCG_REG_TMP, 0);
|
||||
tcg_out_insn(s, 3207, BR, TCG_REG_TMP);
|
||||
s->tb_jmp_reset_offset[a0] = tcg_current_code_size(s);
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue