Commit 2acee8b2 authored by Pranith Kumar's avatar Pranith Kumar Committed by Richard Henderson
Browse files

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.

CC: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: default avatarRichard Henderson <rth@twiddle.net>
Signed-off-by: default avatarPranith Kumar <bobby.prani@gmail.com>
Message-Id: <20170630143614.31059-3-bobby.prani@gmail.com>
Signed-off-by: default avatarRichard Henderson <rth@twiddle.net>
parent b68686bd
Loading
Loading
Loading
Loading
+28 −14
Original line number Diff line number Diff line
@@ -269,6 +269,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,
@@ -389,6 +391,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)
{
@@ -864,6 +871,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;
@@ -889,6 +898,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) {
@@ -1400,11 +1411,8 @@ 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);
        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) {
@@ -1415,6 +1423,12 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
               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);
        }
        tcg_out_insn(s, 3207, BR, TCG_REG_TMP);
        s->tb_jmp_reset_offset[a0] = tcg_current_code_size(s);
        break;