tcg/arm: Clarify tcg_out_bx for arm4 host

In theory this would re-enable usage of QEMU on an armv4 host.
Whether this is worthwhile is debatable -- we've been unconditionally
issuing the armv5t BX instruction in the prologue since 2011 without
complaint. Possibly we should simply require an armv6 host.

Backports commit 702a947484eb3e615183dafc93de590ab0679f60 from qemu
This commit is contained in:
Richard Henderson 2018-03-03 14:17:12 -05:00 committed by Lioncash
parent d496bb6150
commit 3b02642372
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7

View file

@ -338,11 +338,6 @@ static const uint8_t tcg_cond_to_arm_cond[] = {
[TCG_COND_GTU] = COND_HI,
};
static inline void tcg_out_bx(TCGContext *s, int cond, int rn)
{
tcg_out32(s, (cond << 28) | 0x012fff10 | rn);
}
static inline void tcg_out_b(TCGContext *s, int cond, int32_t offset)
{
tcg_out32(s, (cond << 28) | 0x0a000000 |
@ -411,6 +406,18 @@ static inline void tcg_out_mov_reg(TCGContext *s, int cond, int rd, int rm)
}
}
static inline void tcg_out_bx(TCGContext *s, int cond, TCGReg rn)
{
/* Unless the C portion of QEMU is compiled as thumb, we don't
actually need true BX semantics; merely a branch to an address
held in a register. */
if (use_armv5t_instructions) {
tcg_out32(s, (cond << 28) | 0x012fff10 | rn);
} else {
tcg_out_mov_reg(s, cond, TCG_REG_PC, rn);
}
}
static inline void tcg_out_dat_imm(TCGContext *s,
int cond, int opc, int rd, int rn, int im)
{
@ -986,7 +993,7 @@ static inline void tcg_out_st8(TCGContext *s, int cond,
* with the code buffer limited to 16MB we wouldn't need the long case.
* But we also use it for the tail-call to the qemu_ld/st helpers, which does.
*/
static inline void tcg_out_goto(TCGContext *s, int cond, tcg_insn_unit *addr)
static void tcg_out_goto(TCGContext *s, int cond, tcg_insn_unit *addr)
{
intptr_t addri = (intptr_t)addr;
ptrdiff_t disp = tcg_pcrel_diff(s, addr);
@ -996,15 +1003,9 @@ static inline void tcg_out_goto(TCGContext *s, int cond, tcg_insn_unit *addr)
return;
}
assert(use_armv5t_instructions || (addri & 1) == 0);
tcg_out_movi32(s, cond, TCG_REG_TMP, addri);
if (use_armv5t_instructions) {
tcg_out_bx(s, cond, TCG_REG_TMP);
} else {
if (addri & 1) {
tcg_abort();
}
tcg_out_mov_reg(s, cond, TCG_REG_PC, TCG_REG_TMP);
}
tcg_out_bx(s, cond, TCG_REG_TMP);
}
/* The call case is mostly used for helpers - so it's not unreasonable