diff options
author | Aurelien Jarno <aurelien@aurel32.net> | 2010-04-09 20:52:48 +0200 |
---|---|---|
committer | Aurelien Jarno <aurelien@aurel32.net> | 2010-04-19 07:03:02 +0200 |
commit | 23401b58a4a47e964b838339f718b2993bd9345a (patch) | |
tree | ee94697854c0789aefaaa1ef7014cfa27e7ae592 /tcg/arm | |
parent | 8f7f749f216af458ea96573c4057f13023e3268d (diff) |
tcg/arm: use the blx instruction when possible
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Diffstat (limited to 'tcg/arm')
-rw-r--r-- | tcg/arm/tcg-target.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c index b768bdf2a..2eaab041f 100644 --- a/tcg/arm/tcg-target.c +++ b/tcg/arm/tcg-target.c @@ -357,6 +357,11 @@ static inline void tcg_out_bl(TCGContext *s, int cond, int32_t offset) (((offset - 8) >> 2) & 0x00ffffff)); } +static inline void tcg_out_blx(TCGContext *s, int cond, int rn) +{ + tcg_out32(s, (cond << 28) | 0x012fff30 | rn); +} + static inline void tcg_out_dat_reg(TCGContext *s, int cond, int opc, int rd, int rn, int rm, int shift) { @@ -778,10 +783,13 @@ static inline void tcg_out_call(TCGContext *s, int cond, uint32_t addr) static inline void tcg_out_callr(TCGContext *s, int cond, int arg) { - /* TODO: on ARMv5 and ARMv6 replace with tcg_out_blx(s, cond, arg); */ - tcg_out_dat_reg(s, cond, ARITH_MOV, TCG_REG_R14, 0, - TCG_REG_PC, SHIFT_IMM_LSL(0)); - tcg_out_bx(s, cond, arg); + if (use_armv5_instructions) { + tcg_out_blx(s, cond, arg); + } else { + tcg_out_dat_reg(s, cond, ARITH_MOV, TCG_REG_R14, 0, + TCG_REG_PC, SHIFT_IMM_LSL(0)); + tcg_out_bx(s, cond, arg); + } } static inline void tcg_out_goto_label(TCGContext *s, int cond, int label_index) |