qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

target/arm: Convert T16, long branches

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20190904193059.26202-68-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

authored by

Richard Henderson and committed by
Peter Maydell
67b54c55 8d4a4dc8

+43 -49
+7
target/arm/t16.decode
··· 272 272 %imm11_0x2 0:s11 !function=times_2 273 273 274 274 B 11100 ........... &i imm=%imm11_0x2 275 + 276 + # thumb_insn_is_16bit() ensures we won't be decoding these as 277 + # T16 instructions for a Thumb2 CPU, so these patterns must be 278 + # a Thumb1 split BL/BLX. 279 + BLX_suffix 11101 imm:11 &i 280 + BL_BLX_prefix 11110 imm:s11 &i 281 + BL_suffix 11111 imm:11 &i
+36 -49
target/arm/translate.c
··· 10147 10147 return true; 10148 10148 } 10149 10149 10150 + static bool trans_BL_BLX_prefix(DisasContext *s, arg_BL_BLX_prefix *a) 10151 + { 10152 + assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2)); 10153 + tcg_gen_movi_i32(cpu_R[14], read_pc(s) + (a->imm << 12)); 10154 + return true; 10155 + } 10156 + 10157 + static bool trans_BL_suffix(DisasContext *s, arg_BL_suffix *a) 10158 + { 10159 + TCGv_i32 tmp = tcg_temp_new_i32(); 10160 + 10161 + assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2)); 10162 + tcg_gen_addi_i32(tmp, cpu_R[14], (a->imm << 1) | 1); 10163 + tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1); 10164 + gen_bx(s, tmp); 10165 + return true; 10166 + } 10167 + 10168 + static bool trans_BLX_suffix(DisasContext *s, arg_BLX_suffix *a) 10169 + { 10170 + TCGv_i32 tmp; 10171 + 10172 + assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2)); 10173 + if (!ENABLE_ARCH_5) { 10174 + return false; 10175 + } 10176 + tmp = tcg_temp_new_i32(); 10177 + tcg_gen_addi_i32(tmp, cpu_R[14], a->imm << 1); 10178 + tcg_gen_andi_i32(tmp, tmp, 0xfffffffc); 10179 + tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1); 10180 + gen_bx(s, tmp); 10181 + return true; 10182 + } 10183 + 10150 10184 static bool op_tbranch(DisasContext *s, arg_tbranch *a, bool half) 10151 10185 { 10152 10186 TCGv_i32 addr, tmp; ··· 10736 10770 10737 10771 static void disas_thumb_insn(DisasContext *s, uint32_t insn) 10738 10772 { 10739 - int32_t offset; 10740 - TCGv_i32 tmp; 10741 - TCGv_i32 tmp2; 10742 - 10743 10773 if (disas_t16(s, insn)) { 10744 10774 return; 10745 10775 } ··· 10758 10788 case 11: /* misc, in decodetree */ 10759 10789 case 12: /* load/store multiple, in decodetree */ 10760 10790 case 13: /* conditional branch or swi, in decodetree */ 10761 - goto illegal_op; 10762 - 10763 10791 case 14: 10764 - if (insn & (1 << 11)) { 10765 - /* thumb_insn_is_16bit() ensures we can't get here for 10766 - * a Thumb2 CPU, so this must be a thumb1 split BL/BLX: 10767 - * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF) 10768 - */ 10769 - assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2)); 10770 - ARCH(5); 10771 - offset = ((insn & 0x7ff) << 1); 10772 - tmp = load_reg(s, 14); 10773 - tcg_gen_addi_i32(tmp, tmp, offset); 10774 - tcg_gen_andi_i32(tmp, tmp, 0xfffffffc); 10775 - 10776 - tmp2 = tcg_temp_new_i32(); 10777 - tcg_gen_movi_i32(tmp2, s->base.pc_next | 1); 10778 - store_reg(s, 14, tmp2); 10779 - gen_bx(s, tmp); 10780 - break; 10781 - } 10782 - /* unconditional branch, in decodetree */ 10792 + case 15: 10793 + /* branches, in decodetree */ 10783 10794 goto illegal_op; 10784 - 10785 - case 15: 10786 - /* thumb_insn_is_16bit() ensures we can't get here for 10787 - * a Thumb2 CPU, so this must be a thumb1 split BL/BLX. 10788 - */ 10789 - assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2)); 10790 - 10791 - if (insn & (1 << 11)) { 10792 - /* 0b1111_1xxx_xxxx_xxxx : BL suffix */ 10793 - offset = ((insn & 0x7ff) << 1) | 1; 10794 - tmp = load_reg(s, 14); 10795 - tcg_gen_addi_i32(tmp, tmp, offset); 10796 - 10797 - tmp2 = tcg_temp_new_i32(); 10798 - tcg_gen_movi_i32(tmp2, s->base.pc_next | 1); 10799 - store_reg(s, 14, tmp2); 10800 - gen_bx(s, tmp); 10801 - } else { 10802 - /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */ 10803 - uint32_t uoffset = ((int32_t)insn << 21) >> 9; 10804 - 10805 - tcg_gen_movi_i32(cpu_R[14], read_pc(s) + uoffset); 10806 - } 10807 - break; 10808 10795 } 10809 10796 return; 10810 10797 illegal_op: