Skip to content

Commit

Permalink
tcg-aarch64: Use symbolic names for branches
Browse files Browse the repository at this point in the history
Reviewed-by: Claudio Fontana <claudio.fontana@huawei.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
  • Loading branch information
rth7680 authored and Richard Henderson committed Apr 16, 2014
1 parent c6e310d commit 81d8a5e
Showing 1 changed file with 43 additions and 31 deletions.
74 changes: 43 additions & 31 deletions tcg/aarch64/tcg-target.c
Expand Up @@ -270,6 +270,18 @@ enum aarch64_ldst_op_type { /* type of operation */
use the section number of the architecture reference manual in which the
instruction group is described. */
typedef enum {
/* Conditional branch (immediate). */
I3202_B_C = 0x54000000,

/* Unconditional branch (immediate). */
I3206_B = 0x14000000,
I3206_BL = 0x94000000,

/* Unconditional branch (register). */
I3207_BR = 0xd61f0000,
I3207_BLR = 0xd63f0000,
I3207_RET = 0xd65f0000,

/* Add/subtract immediate instructions. */
I3401_ADDI = 0x11000000,
I3401_ADDSI = 0x31000000,
Expand Down Expand Up @@ -421,6 +433,22 @@ 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_3202(TCGContext *s, AArch64Insn insn,
TCGCond c, int imm19)
{
tcg_out32(s, insn | tcg_cond_to_aarch64[c] | (imm19 & 0x7ffff) << 5);
}

static void tcg_out_insn_3206(TCGContext *s, AArch64Insn insn, int imm26)
{
tcg_out32(s, insn | (imm26 & 0x03ffffff));
}

static void tcg_out_insn_3207(TCGContext *s, AArch64Insn insn, TCGReg rn)
{
tcg_out32(s, insn | rn << 5);
}

static void tcg_out_insn_3401(TCGContext *s, AArch64Insn insn, TCGType ext,
TCGReg rd, TCGReg rn, uint64_t aimm)
{
Expand Down Expand Up @@ -817,28 +845,24 @@ static inline void tcg_out_goto(TCGContext *s, intptr_t target)
tcg_abort();
}

tcg_out32(s, 0x14000000 | (offset & 0x03ffffff));
tcg_out_insn(s, 3206, B, offset);
}

static inline void tcg_out_goto_noaddr(TCGContext *s)
{
/* We pay attention here to not modify the branch target by
reading from the buffer. This ensure that caches and memory are
kept coherent during retranslation.
Mask away possible garbage in the high bits for the first translation,
while keeping the offset bits for retranslation. */
uint32_t insn;
insn = (tcg_in32(s) & 0x03ffffff) | 0x14000000;
tcg_out32(s, insn);
/* We pay attention here to not modify the branch target by reading from
the buffer. This ensure that caches and memory are kept coherent during
retranslation. Mask away possible garbage in the high bits for the
first translation, while keeping the offset bits for retranslation. */
uint32_t old = tcg_in32(s);
tcg_out_insn(s, 3206, B, old);
}

static inline void tcg_out_goto_cond_noaddr(TCGContext *s, TCGCond c)
{
/* see comments in tcg_out_goto_noaddr */
uint32_t insn;
insn = tcg_in32(s) & (0x07ffff << 5);
insn |= 0x54000000 | tcg_cond_to_aarch64[c];
tcg_out32(s, insn);
/* See comments in tcg_out_goto_noaddr. */
uint32_t old = tcg_in32(s) >> 5;
tcg_out_insn(s, 3202, B_C, c, old);
}

static inline void tcg_out_goto_cond(TCGContext *s, TCGCond c, intptr_t target)
Expand All @@ -850,18 +874,12 @@ static inline void tcg_out_goto_cond(TCGContext *s, TCGCond c, intptr_t target)
tcg_abort();
}

offset &= 0x7ffff;
tcg_out32(s, 0x54000000 | tcg_cond_to_aarch64[c] | offset << 5);
tcg_out_insn(s, 3202, B_C, c, offset);
}

static inline void tcg_out_callr(TCGContext *s, TCGReg reg)
{
tcg_out32(s, 0xd63f0000 | reg << 5);
}

static inline void tcg_out_gotor(TCGContext *s, TCGReg reg)
{
tcg_out32(s, 0xd61f0000 | reg << 5);
tcg_out_insn(s, 3207, BLR, reg);
}

static inline void tcg_out_call(TCGContext *s, intptr_t target)
Expand All @@ -872,16 +890,10 @@ static inline void tcg_out_call(TCGContext *s, intptr_t target)
tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP, target);
tcg_out_callr(s, TCG_REG_TMP);
} else {
tcg_out32(s, 0x94000000 | (offset & 0x03ffffff));
tcg_out_insn(s, 3206, BL, offset);
}
}

static inline void tcg_out_ret(TCGContext *s)
{
/* emit RET { LR } */
tcg_out32(s, 0xd65f03c0);
}

void aarch64_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr)
{
intptr_t target = addr;
Expand Down Expand Up @@ -1899,7 +1911,7 @@ static void tcg_target_qemu_prologue(TCGContext *s)
#endif

tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
tcg_out_gotor(s, tcg_target_call_iarg_regs[1]);
tcg_out_insn(s, 3207, BR, tcg_target_call_iarg_regs[1]);

tb_ret_addr = s->code_ptr;

Expand All @@ -1917,5 +1929,5 @@ static void tcg_target_qemu_prologue(TCGContext *s)
/* pop (FP, LR), restore SP to previous frame, return */
tcg_out_pop_pair(s, TCG_REG_SP,
TCG_REG_FP, TCG_REG_LR, frame_size_callee_saved);
tcg_out_ret(s);
tcg_out_insn(s, 3207, RET, TCG_REG_LR);
}

0 comments on commit 81d8a5e

Please sign in to comment.