diff options
author | Richard Henderson | 2021-08-08 20:29:18 +0200 |
---|---|---|
committer | Richard Henderson | 2021-09-14 21:00:21 +0200 |
commit | 31d160adc9d2a13db582096bb844038732c1fbea (patch) | |
tree | 9908e5c1c14de624b66f56662a3d7f40a33e2294 /tcg | |
parent | tcg/arm: Support armv4t in tcg_out_goto and tcg_out_call (diff) | |
download | qemu-31d160adc9d2a13db582096bb844038732c1fbea.tar.gz qemu-31d160adc9d2a13db582096bb844038732c1fbea.tar.xz qemu-31d160adc9d2a13db582096bb844038732c1fbea.zip |
tcg/arm: Split out tcg_out_ldstm
Expand these hard-coded instructions symbolically.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'tcg')
-rw-r--r-- | tcg/arm/tcg-target.c.inc | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/tcg/arm/tcg-target.c.inc b/tcg/arm/tcg-target.c.inc index 852100bb80..c9e3fcfeac 100644 --- a/tcg/arm/tcg-target.c.inc +++ b/tcg/arm/tcg-target.c.inc @@ -141,6 +141,9 @@ typedef enum { INSN_CLZ = 0x016f0f10, INSN_RBIT = 0x06ff0f30, + INSN_LDMIA = 0x08b00000, + INSN_STMDB = 0x09200000, + INSN_LDR_IMM = 0x04100000, INSN_LDR_REG = 0x06100000, INSN_STR_IMM = 0x04000000, @@ -593,6 +596,12 @@ static inline void tcg_out_dat_imm(TCGContext *s, (rn << 16) | (rd << 12) | im); } +static void tcg_out_ldstm(TCGContext *s, int cond, int opc, + TCGReg rn, uint16_t mask) +{ + tcg_out32(s, (cond << 28) | opc | (rn << 16) | mask); +} + /* Note that this routine is used for both LDR and LDRH formats, so we do not wish to include an immediate shift at this point. */ static void tcg_out_memop_r(TCGContext *s, int cond, ARMInsn opc, TCGReg rt, @@ -3081,7 +3090,10 @@ static void tcg_target_qemu_prologue(TCGContext *s) { /* Calling convention requires us to save r4-r11 and lr. */ /* stmdb sp!, { r4 - r11, lr } */ - tcg_out32(s, (COND_AL << 28) | 0x092d4ff0); + tcg_out_ldstm(s, COND_AL, INSN_STMDB, TCG_REG_CALL_STACK, + (1 << TCG_REG_R4) | (1 << TCG_REG_R5) | (1 << TCG_REG_R6) | + (1 << TCG_REG_R7) | (1 << TCG_REG_R8) | (1 << TCG_REG_R9) | + (1 << TCG_REG_R10) | (1 << TCG_REG_R11) | (1 << TCG_REG_R14)); /* Reserve callee argument and tcg temp space. */ tcg_out_dat_rI(s, COND_AL, ARITH_SUB, TCG_REG_CALL_STACK, @@ -3109,7 +3121,10 @@ static void tcg_out_epilogue(TCGContext *s) TCG_REG_CALL_STACK, STACK_ADDEND, 1); /* ldmia sp!, { r4 - r11, pc } */ - tcg_out32(s, (COND_AL << 28) | 0x08bd8ff0); + tcg_out_ldstm(s, COND_AL, INSN_LDMIA, TCG_REG_CALL_STACK, + (1 << TCG_REG_R4) | (1 << TCG_REG_R5) | (1 << TCG_REG_R6) | + (1 << TCG_REG_R7) | (1 << TCG_REG_R8) | (1 << TCG_REG_R9) | + (1 << TCG_REG_R10) | (1 << TCG_REG_R11) | (1 << TCG_REG_PC)); } typedef struct { |