diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2019-09-04 12:30:38 -0700 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2019-09-05 13:23:03 +0100 |
commit | 07afd747f9fdd79fabf3a51416c7d795f873d297 (patch) | |
tree | f0379c541a3ec72f9178d496e4505a971d424031 /target/arm | |
parent | d1d229179c6b011cc3fa124d4b6b649866470530 (diff) |
target/arm: Convert T16 load/store (immediate offset)
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20190904193059.26202-49-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target/arm')
-rw-r--r-- | target/arm/t16.decode | 33 | ||||
-rw-r--r-- | target/arm/translate.c | 94 |
2 files changed, 38 insertions, 89 deletions
diff --git a/target/arm/t16.decode b/target/arm/t16.decode index 83fe4363c7..1cf79789ac 100644 --- a/target/arm/t16.decode +++ b/target/arm/t16.decode @@ -24,6 +24,7 @@ &s_rri_rot !extern s rn rd imm rot &s_rrrr !extern s rd rn rm ra &ldst_rr !extern p w u rn rt rm shimm shtype +&ldst_ri !extern p w u rn rt imm # Set S if the instruction is outside of an IT block. %s !function=t16_setflags @@ -69,3 +70,35 @@ LDR_rr 0101 100 ... ... ... @ldst_rr LDRH_rr 0101 101 ... ... ... @ldst_rr LDRB_rr 0101 110 ... ... ... @ldst_rr LDRSH_rr 0101 111 ... ... ... @ldst_rr + +# Load/store word/byte (immediate offset) + +%imm5_6x4 6:5 !function=times_4 + +@ldst_ri_1 ..... imm:5 rn:3 rt:3 \ + &ldst_ri p=1 w=0 u=1 +@ldst_ri_4 ..... ..... rn:3 rt:3 \ + &ldst_ri p=1 w=0 u=1 imm=%imm5_6x4 + +STR_ri 01100 ..... ... ... @ldst_ri_4 +LDR_ri 01101 ..... ... ... @ldst_ri_4 +STRB_ri 01110 ..... ... ... @ldst_ri_1 +LDRB_ri 01111 ..... ... ... @ldst_ri_1 + +# Load/store halfword (immediate offset) + +%imm5_6x2 6:5 !function=times_2 +@ldst_ri_2 ..... ..... rn:3 rt:3 \ + &ldst_ri p=1 w=0 u=1 imm=%imm5_6x2 + +STRH_ri 10000 ..... ... ... @ldst_ri_2 +LDRH_ri 10001 ..... ... ... @ldst_ri_2 + +# Load/store (SP-relative) + +%imm8_0x4 0:8 !function=times_4 +@ldst_spec_i ..... rt:3 ........ \ + &ldst_ri p=1 w=0 u=1 imm=%imm8_0x4 + +STR_ri 10010 ... ........ @ldst_spec_i rn=13 +LDR_ri 10011 ... ........ @ldst_spec_i rn=13 diff --git a/target/arm/translate.c b/target/arm/translate.c index 789abe9b87..4ae73d1c92 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -10863,97 +10863,13 @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn) */ goto illegal_op; - case 5: - /* load/store register offset, in decodetree */ + case 5: /* load/store register offset, in decodetree */ + case 6: /* load/store word immediate offset, in decodetree */ + case 7: /* load/store byte immediate offset, in decodetree */ + case 8: /* load/store halfword immediate offset, in decodetree */ + case 9: /* load/store from stack, in decodetree */ goto illegal_op; - case 6: - /* load/store word immediate offset */ - rd = insn & 7; - rn = (insn >> 3) & 7; - addr = load_reg(s, rn); - val = (insn >> 4) & 0x7c; - tcg_gen_addi_i32(addr, addr, val); - - if (insn & (1 << 11)) { - /* load */ - tmp = tcg_temp_new_i32(); - gen_aa32_ld32u(s, tmp, addr, get_mem_index(s)); - store_reg(s, rd, tmp); - } else { - /* store */ - tmp = load_reg(s, rd); - gen_aa32_st32(s, tmp, addr, get_mem_index(s)); - tcg_temp_free_i32(tmp); - } - tcg_temp_free_i32(addr); - break; - - case 7: - /* load/store byte immediate offset */ - rd = insn & 7; - rn = (insn >> 3) & 7; - addr = load_reg(s, rn); - val = (insn >> 6) & 0x1f; - tcg_gen_addi_i32(addr, addr, val); - - if (insn & (1 << 11)) { - /* load */ - tmp = tcg_temp_new_i32(); - gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit); - store_reg(s, rd, tmp); - } else { - /* store */ - tmp = load_reg(s, rd); - gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit); - tcg_temp_free_i32(tmp); - } - tcg_temp_free_i32(addr); - break; - - case 8: - /* load/store halfword immediate offset */ - rd = insn & 7; - rn = (insn >> 3) & 7; - addr = load_reg(s, rn); - val = (insn >> 5) & 0x3e; - tcg_gen_addi_i32(addr, addr, val); - - if (insn & (1 << 11)) { - /* load */ - tmp = tcg_temp_new_i32(); - gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit); - store_reg(s, rd, tmp); - } else { - /* store */ - tmp = load_reg(s, rd); - gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit); - tcg_temp_free_i32(tmp); - } - tcg_temp_free_i32(addr); - break; - - case 9: - /* load/store from stack */ - rd = (insn >> 8) & 7; - addr = load_reg(s, 13); - val = (insn & 0xff) * 4; - tcg_gen_addi_i32(addr, addr, val); - - if (insn & (1 << 11)) { - /* load */ - tmp = tcg_temp_new_i32(); - gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit); - store_reg(s, rd, tmp); - } else { - /* store */ - tmp = load_reg(s, rd); - gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit); - tcg_temp_free_i32(tmp); - } - tcg_temp_free_i32(addr); - break; - case 10: /* * 0b1010_xxxx_xxxx_xxxx |