This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Thumb32 assembler (68/69)
- From: Zack Weinberg <zack at codesourcery dot com>
- To: binutils <binutils at sourceware dot org>
- Date: Tue, 26 Apr 2005 03:04:00 -0700
- Subject: Thumb32 assembler (68/69)
Finally the patch you've all been waiting for: the actual
implementation of the new Thumb32 instructions.
zw
gas/testsuite:
* gas/arm/thumb32.s, gas/arm/thumb32.d: New dump test.
* gas/arm/arm.exp: Run it.
* gas/arm/archz6k.s: Use even registers where required.
* gas/arm/archz6k.d: Update to match.
* gas/arm/thumb.d, gas/arm/t16-bad.l: Adjust expectation patterns.
gas:
* config/tc-arm.c (thumb32_mode): New global.
(struct arm_it): Add size_req field.
(BAD_THUMB32): New canned diagnostic.
(s_thumb32, s_thumb32_func): New functions.
(s_thumb_func): Call s_thumb for its effects.
(md_pseudo_table): Add .thumb32 and .thumb32_func.
(parse_shifter_operand): Set inst.reloc.exp to constant 0 before early
exit.
(OP_oRRnpc): New operand parse code.
(parse_operand): Handle it.
(encode_arm_immediate): Formatting.
(do_ldrd): Operand 1 is now an optional register, and operand 2 is now
an address.
(do_strex): Similarly.
(do_ldrex, do_ldrexd, do_strexd): New ARM instruction encoders.
(encode_thumb32_immediate, encode_thumb32_shifted_operand):
(encode_thumb32_addr_mode): New helper functions.
(T16_32_TAB, t16_32_codes, thumb_op16, THUMB_OP16, thumb_op32)
(THUMB_OP32, THUMB_SETS_FLAGS): New data table.
(do_t_add_sub, do_t_arit3, do_t_branch, do_t_blx, do_t_cpy)
(do_t_ldmstm, do_t_ldst, do_t_ldstd, do_t_ldstt, do_t_mlas, do_t_mul)
(do_t_mov_cmp, do_t_nop, do_t_push_pop, do_t_shift): Add support for
Thumb32 encoding.
(do_t_arit3c, do_t_bfc, do_t_bfi, do_t_bfx, do_t_bxj, do_t_clz)
(do_t_cpsi, do_t_hint, do_t_ldrex, do_t_ldrexd, do_t_mov16)
(do_t_mvn_tst, do_t_mrs, do_t_msr, do_t_mull, do_t_nop)
(do_t_neg, do_t_pkhbt, do_t_pkhtb, do_t_pld, do_t_qadd, do_t_rbit)
(do_t_rev, do_t_rsb, do_t_smi, do_t_smla, do_t_smlal, do_t_smul)
(do_t_ssat, do_t_strex, do_t_strexd, do_t_sxtah, do_t_sxth, do_t_usat)
(do_t_usat16): New Thumb32 instruction encoders.
(do_t_arit, do_t_lds): Delete.
(do_t_it): Correct bit-fiddling.
(md_assemble): Handle size suffixes. Remove unreachable code block.
(TxCE, tCE, TxCM, tCM): New insn-table macros.
(TCE, TCM): Adjust to match.
(insns): Add entries for all Thumb32 instructions.
(md_apply_fix3): Handle new relocations BFD_RELOC_ARM_T32_OFFSET_U8,
BFD_RELOC_ARM_T32_OFFSET_IMM, BFD_RELOC_ARM_T32_IMMEDIATE,
BFD_RELOC_THUMB_PCREL_BRANCH20, BFD_RELOC_THUMB_PCREL_BRANCH25.
Correct handling of BFD_RELOC_THUMB_PCREL_BRANCH7.
bfd:
* reloc.c: Add Thumb assembler-internal relocations
BFD_RELOC_ARM_T32_OFFSET_U8, BFD_RELOC_ARM_T32_OFFSET_IMM,
BFD_RELOC_ARM_T32_IMMEDIATE.
* bfd-in2.h, libbfd.h: Regenerate.
(elf32_arm_final_link_relocate): Correct handling of
R_ARM_THM_JUMP24 and R_ARM_THM_JUMP19.
opcodes:
* arm-dis.c (thumb_opcodes): Recognize NOP hints. Revert "rsbs
rX,rY,#0" to "negs rX,rY". Add spaces between operands to ldmia and
stmia.
(thumb32_opcodes): Recognize NOP hints. Correct entries for ldrex,
strex, smuad, smusd, smmul, cmn.w, cmp.w, smlad, smlsd, smmla, smmls,
smlald, smlsld, sbfx, ubfx, sub.w, adc.w, ldrd, strd. Filter out
undefined conditional branch variants.
(print_insn_thumb32): Consistently print immediates in both decimal and
hexadecimal. Consistently do not prefix positive integers with '+'.
Correct handling of %M, %J, %b, %B, %s. Add %W.
===================================================================
Index: gas/testsuite/gas/arm/arch6zk.d
--- gas/testsuite/gas/arm/arch6zk.d (revision 78)
+++ gas/testsuite/gas/arm/arch6zk.d (revision 79)
@@ -6,21 +6,21 @@
Disassembly of section .text:
0+000 <[^>]*> f57ff01f ? clrex
-0+004 <[^>]*> e1dc3f9f ? ldrexb r3, \[ip\]
-0+008 <[^>]*> 11d3cf9f ? ldrexbne ip, \[r3\]
-0+00c <[^>]*> e1bc3f9f ? ldrexd r3, \[ip\]
-0+010 <[^>]*> 11b3cf9f ? ldrexdne ip, \[r3\]
-0+014 <[^>]*> e1fc3f9f ? ldrexh r3, \[ip\]
-0+018 <[^>]*> 11f3cf9f ? ldrexhne ip, \[r3\]
+0+004 <[^>]*> e1dc4f9f ? ldrexb r4, \[ip\]
+0+008 <[^>]*> 11d4cf9f ? ldrexbne ip, \[r4\]
+0+00c <[^>]*> e1bc4f9f ? ldrexd r4, \[ip\]
+0+010 <[^>]*> 11b4cf9f ? ldrexdne ip, \[r4\]
+0+014 <[^>]*> e1fc4f9f ? ldrexh r4, \[ip\]
+0+018 <[^>]*> 11f4cf9f ? ldrexhne ip, \[r4\]
0+01c <[^>]*> e320f080 ? nop \{128\}
0+020 <[^>]*> 1320f07f ? nopne \{127\}
0+024 <[^>]*> e320f004 ? sev
-0+028 <[^>]*> e1c73f9c ? strexb r3, ip, \[r7\]
-0+02c <[^>]*> 11c8cf93 ? strexbne ip, r3, \[r8\]
-0+030 <[^>]*> e1a73f9c ? strexd r3, ip, \[r7\]
-0+034 <[^>]*> 11a8cf93 ? strexdne ip, r3, \[r8\]
-0+038 <[^>]*> e1e73f9c ? strexh r3, ip, \[r7\]
-0+03c <[^>]*> 11e8cf93 ? strexhne ip, r3, \[r8\]
+0+028 <[^>]*> e1c74f9c ? strexb r4, ip, \[r7\]
+0+02c <[^>]*> 11c8cf94 ? strexbne ip, r4, \[r8\]
+0+030 <[^>]*> e1a74f9c ? strexd r4, ip, \[r7\]
+0+034 <[^>]*> 11a8cf94 ? strexdne ip, r4, \[r8\]
+0+038 <[^>]*> e1e74f9c ? strexh r4, ip, \[r7\]
+0+03c <[^>]*> 11e8cf94 ? strexhne ip, r4, \[r8\]
0+040 <[^>]*> e320f002 ? wfe
0+044 <[^>]*> e320f003 ? wfi
0+048 <[^>]*> e320f001 ? yield
===================================================================
Index: gas/testsuite/gas/arm/arch6zk.s
--- gas/testsuite/gas/arm/arch6zk.s (revision 78)
+++ gas/testsuite/gas/arm/arch6zk.s (revision 79)
@@ -4,21 +4,21 @@
label:
# ARMV6K instructions
clrex
- ldrexb r3, [r12]
- ldrexbne r12, [r3]
- ldrexd r3, [r12]
- ldrexdne r12, [r3]
- ldrexh r3, [r12]
- ldrexhne r12, [r3]
- nop {128}
- nopne {127}
+ ldrexb r4, [r12]
+ ldrexbne r12, [r4]
+ ldrexd r4, [r12]
+ ldrexdne r12, [r4]
+ ldrexh r4, [r12]
+ ldrexhne r12, [r4]
+ nop {128}
+ nopne {127}
sev
- strexb r3, r12, [r7]
- strexbne r12, r3, [r8]
- strexd r3, r12, [r7]
- strexdne r12, r3, [r8]
- strexh r3, r12, [r7]
- strexhne r12, r3, [r8]
+ strexb r4, r12, [r7]
+ strexbne r12, r4, [r8]
+ strexd r4, r12, [r7]
+ strexdne r12, r4, [r8]
+ strexh r4, r12, [r7]
+ strexhne r12, r4, [r8]
wfe
wfi
yield
===================================================================
Index: gas/testsuite/gas/arm/arm.exp
--- gas/testsuite/gas/arm/arm.exp (revision 78)
+++ gas/testsuite/gas/arm/arm.exp (revision 79)
@@ -54,6 +54,7 @@
run_dump_test "arch6zk"
run_dump_test "tcompat"
run_dump_test "iwmmxt"
+ run_dump_test "thumb32"
run_errors_test "vfp-bad" "-mfpu=vfp" "VFP errors"
run_errors_test "req" "-mcpu=arm7m" ".req errors"
===================================================================
Index: gas/testsuite/gas/arm/thumb.d
--- gas/testsuite/gas/arm/thumb.d (revision 78)
+++ gas/testsuite/gas/arm/thumb.d (revision 79)
@@ -30,7 +30,7 @@
0+02c <[^>]+> 41a0 sbcs r0, r4
0+02e <[^>]+> 41e1 rors r1, r4
0+030 <[^>]+> 422a tst r2, r5
-0+032 <[^>]+> 4249 rsbs r1, r1, #0
+0+032 <[^>]+> 4249 negs r1, r1
0+034 <[^>]+> 429a cmp r2, r3
0+036 <[^>]+> 42e1 cmn r1, r4
0+038 <[^>]+> 4318 orrs r0, r3
@@ -83,8 +83,8 @@
0+096 <[^>]+> b5f9 push {r0, r3, r4, r5, r6, r7, lr}
0+098 <[^>]+> bc98 pop {r3, r4, r7}
0+09a <[^>]+> bdff pop {r0, r1, r2, r3, r4, r5, r6, r7, pc}
-0+09c <[^>]+> c3f3 stmia r3!,{r0, r1, r4, r5, r6, r7}
-0+09e <[^>]+> c8fe ldmia r0!,{r1, r2, r3, r4, r5, r6, r7}
+0+09c <[^>]+> c3f3 stmia r3!, {r0, r1, r4, r5, r6, r7}
+0+09e <[^>]+> c8fe ldmia r0!, {r1, r2, r3, r4, r5, r6, r7}
0+0a0 <[^>]+> d0e2 beq.n 0+068 <[^>]+>
0+0a2 <[^>]+> d1e1 bne.n 0+068 <[^>]+>
0+0a4 <[^>]+> d2e0 bcs.n 0+068 <[^>]+>
===================================================================
Index: gas/testsuite/gas/arm/thumb32.d
--- gas/testsuite/gas/arm/thumb32.d (revision 0)
+++ gas/testsuite/gas/arm/thumb32.d (revision 79)
@@ -0,0 +1,995 @@
+# name: 32-bit Thumb instructions
+# as: -march=armv6kt2
+# objdump: -dr --prefix-addresses --show-raw-insn
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+0+000 <[^>]+> f041 0000 orr\.w r0, r1, #0 ; 0x0
+0+004 <[^>]+> f041 00a5 orr\.w r0, r1, #165 ; 0xa5
+0+008 <[^>]+> f041 10a5 orr\.w r0, r1, #10813605 ; 0xa500a5
+0+00c <[^>]+> f041 20a5 orr\.w r0, r1, #2768282880 ; 0xa500a500
+0+010 <[^>]+> f041 30a5 orr\.w r0, r1, #2779096485 ; 0xa5a5a5a5
+0+014 <[^>]+> f041 4000 orr\.w r0, r1, #2147483648 ; 0x80000000
+0+018 <[^>]+> f041 4080 orr\.w r0, r1, #1073741824 ; 0x40000000
+0+01c <[^>]+> f041 4020 orr\.w r0, r1, #2684354560 ; 0xa0000000
+0+020 <[^>]+> f041 40a0 orr\.w r0, r1, #1342177280 ; 0x50000000
+0+024 <[^>]+> f041 5020 orr\.w r0, r1, #671088640 ; 0x28000000
+0+028 <[^>]+> f041 4014 orr\.w r0, r1, #2483027968 ; 0x94000000
+0+02c <[^>]+> f041 4094 orr\.w r0, r1, #1241513984 ; 0x4a000000
+0+030 <[^>]+> f041 4025 orr\.w r0, r1, #2768240640 ; 0xa5000000
+0+034 <[^>]+> f041 40a5 orr\.w r0, r1, #1384120320 ; 0x52800000
+0+038 <[^>]+> f041 5025 orr\.w r0, r1, #692060160 ; 0x29400000
+0+03c <[^>]+> f041 50a5 orr\.w r0, r1, #346030080 ; 0x14a00000
+0+040 <[^>]+> f041 6025 orr\.w r0, r1, #173015040 ; 0xa500000
+0+044 <[^>]+> f041 60a5 orr\.w r0, r1, #86507520 ; 0x5280000
+0+048 <[^>]+> f041 7025 orr\.w r0, r1, #43253760 ; 0x2940000
+0+04c <[^>]+> f041 70a5 orr\.w r0, r1, #21626880 ; 0x14a0000
+0+050 <[^>]+> f441 0025 orr\.w r0, r1, #10813440 ; 0xa50000
+0+054 <[^>]+> f441 00a5 orr\.w r0, r1, #5406720 ; 0x528000
+0+058 <[^>]+> f441 1025 orr\.w r0, r1, #2703360 ; 0x294000
+0+05c <[^>]+> f441 10a5 orr\.w r0, r1, #1351680 ; 0x14a000
+0+060 <[^>]+> f441 2025 orr\.w r0, r1, #675840 ; 0xa5000
+0+064 <[^>]+> f441 20a5 orr\.w r0, r1, #337920 ; 0x52800
+0+068 <[^>]+> f441 3025 orr\.w r0, r1, #168960 ; 0x29400
+0+06c <[^>]+> f441 30a5 orr\.w r0, r1, #84480 ; 0x14a00
+0+070 <[^>]+> f441 4025 orr\.w r0, r1, #42240 ; 0xa500
+0+074 <[^>]+> f441 40a5 orr\.w r0, r1, #21120 ; 0x5280
+0+078 <[^>]+> f441 5025 orr\.w r0, r1, #10560 ; 0x2940
+0+07c <[^>]+> f441 50a5 orr\.w r0, r1, #5280 ; 0x14a0
+0+080 <[^>]+> f441 6025 orr\.w r0, r1, #2640 ; 0xa50
+0+084 <[^>]+> f441 60a5 orr\.w r0, r1, #1320 ; 0x528
+0+088 <[^>]+> f441 7025 orr\.w r0, r1, #660 ; 0x294
+0+08c <[^>]+> f441 70a5 orr\.w r0, r1, #330 ; 0x14a
+0+090 <[^>]+> f110 0000 adds\.w r0, r0, #0 ; 0x0
+0+094 <[^>]+> f110 0500 adds\.w r5, r0, #0 ; 0x0
+0+098 <[^>]+> f115 0000 adds\.w r0, r5, #0 ; 0x0
+0+09c <[^>]+> f110 0005 adds\.w r0, r0, #5 ; 0x5
+0+0a0 <[^>]+> f110 0081 adds\.w r0, r0, #129 ; 0x81
+0+0a4 <[^>]+> f110 0081 adds\.w r0, r0, #129 ; 0x81
+0+0a8 <[^>]+> f110 057e adds\.w r5, r0, #126 ; 0x7e
+0+0ac <[^>]+> 1800 adds r0, r0, r0
+0+0ae <[^>]+> 1805 adds r5, r0, r0
+0+0b0 <[^>]+> 1828 adds r0, r5, r0
+0+0b2 <[^>]+> 1940 adds r0, r0, r5
+0+0b4 <[^>]+> 18d1 adds r1, r2, r3
+0+0b6 <[^>]+> 4480 add r8, r0
+0+0b8 <[^>]+> 4440 add r0, r8
+0+0ba <[^>]+> 4440 add r0, r8
+0+0bc <[^>]+> 4440 add r0, r8
+0+0be <[^>]+> eb00 0800 add\.w r8, r0, r0
+0+0c2 <[^>]+> 4401 add r1, r0
+0+0c4 <[^>]+> 4408 add r0, r1
+0+0c6 <[^>]+> f10f 0000 add\.w r0, pc, #0 ; 0x0
+0+0ca <[^>]+> f10f 0500 add\.w r5, pc, #0 ; 0x0
+0+0ce <[^>]+> f50f 7001 add\.w r0, pc, #516 ; 0x204
+0+0d2 <[^>]+> f10d 0000 add\.w r0, sp, #0 ; 0x0
+0+0d6 <[^>]+> f10d 0500 add\.w r5, sp, #0 ; 0x0
+0+0da <[^>]+> f50d 7001 add\.w r0, sp, #516 ; 0x204
+0+0de <[^>]+> f100 0d00 add\.w sp, r0, #0 ; 0x0
+0+0e2 <[^>]+> f10d 0d00 add\.w sp, sp, #0 ; 0x0
+0+0e6 <[^>]+> f500 7d82 add\.w sp, r0, #260 ; 0x104
+0+0ea <[^>]+> f100 0000 add\.w r0, r0, #0 ; 0x0
+0+0ee <[^>]+> f110 0000 adds\.w r0, r0, #0 ; 0x0
+0+0f2 <[^>]+> f100 0900 add\.w r9, r0, #0 ; 0x0
+0+0f6 <[^>]+> f109 0000 add\.w r0, r9, #0 ; 0x0
+0+0fa <[^>]+> f100 0081 add\.w r0, r0, #129 ; 0x81
+0+0fe <[^>]+> eb00 0000 add\.w r0, r0, r0
+0+102 <[^>]+> eb10 0000 adds\.w r0, r0, r0
+0+106 <[^>]+> eb00 0900 add\.w r9, r0, r0
+0+10a <[^>]+> eb09 0000 add\.w r0, r9, r0
+0+10e <[^>]+> eb00 0009 add\.w r0, r0, r9
+0+112 <[^>]+> eb09 080a add\.w r8, r9, sl
+0+116 <[^>]+> eb09 484a add\.w r8, r9, sl, lsl #17
+0+11a <[^>]+> eb08 081a add\.w r8, r8, sl, lsr #32
+0+11e <[^>]+> eb08 485a add\.w r8, r8, sl, lsr #17
+0+122 <[^>]+> eb09 082a add\.w r8, r9, sl, asr #32
+0+126 <[^>]+> eb09 486a add\.w r8, r9, sl, asr #17
+0+12a <[^>]+> eb09 083a add\.w r8, r9, sl, rrx
+0+12e <[^>]+> eb09 487a add\.w r8, r9, sl, ror #17
+0+132 <[^>]+> f1b0 0000 subs\.w r0, r0, #0 ; 0x0
+0+136 <[^>]+> f1b0 0500 subs\.w r5, r0, #0 ; 0x0
+0+13a <[^>]+> f1b5 0000 subs\.w r0, r5, #0 ; 0x0
+0+13e <[^>]+> f1b0 0005 subs\.w r0, r0, #5 ; 0x5
+0+142 <[^>]+> f1b0 0081 subs\.w r0, r0, #129 ; 0x81
+0+146 <[^>]+> f1b0 0508 subs\.w r5, r0, #8 ; 0x8
+0+14a <[^>]+> 1a00 sub r0, r0, r0
+0+14c <[^>]+> 1a05 sub r5, r0, r0
+0+14e <[^>]+> 1a28 sub r0, r5, r0
+0+150 <[^>]+> 1b40 sub r0, r0, r5
+0+152 <[^>]+> f5a0 7d82 sub\.w sp, r0, #260 ; 0x104
+0+156 <[^>]+> f5ad 7d82 sub\.w sp, sp, #260 ; 0x104
+0+15a <[^>]+> ebb8 0800 subs\.w r8, r8, r0
+0+15e <[^>]+> ebb0 0008 subs\.w r0, r0, r8
+0+162 <[^>]+> f5b0 7082 subs\.w r0, r0, #260 ; 0x104
+0+166 <[^>]+> 4140 adcs r0, r0
+0+168 <[^>]+> 4145 adcs r5, r0
+0+16a <[^>]+> 4168 adcs r0, r5
+0+16c <[^>]+> 4168 adcs r0, r5
+0+16e <[^>]+> 4168 adcs r0, r5
+0+170 <[^>]+> eb45 0000 adc\.w r0, r5, r0
+0+174 <[^>]+> eb41 0002 adc\.w r0, r1, r2
+0+178 <[^>]+> eb40 0900 adc\.w r9, r0, r0
+0+17c <[^>]+> eb49 0000 adc\.w r0, r9, r0
+0+180 <[^>]+> eb40 0009 adc\.w r0, r0, r9
+0+184 <[^>]+> eb50 0000 adcs\.w r0, r0, r0
+0+188 <[^>]+> eb41 4062 adc\.w r0, r1, r2, asr #17
+0+18c <[^>]+> f141 0081 adc\.w r0, r1, #129 ; 0x81
+0+190 <[^>]+> 4000 ands r0, r0
+0+192 <[^>]+> 4005 ands r5, r0
+0+194 <[^>]+> 4028 ands r0, r5
+0+196 <[^>]+> 4028 ands r0, r5
+0+198 <[^>]+> 4028 ands r0, r5
+0+19a <[^>]+> ea05 0000 and\.w r0, r5, r0
+0+19e <[^>]+> ea01 0002 and\.w r0, r1, r2
+0+1a2 <[^>]+> ea00 0900 and\.w r9, r0, r0
+0+1a6 <[^>]+> ea09 0000 and\.w r0, r9, r0
+0+1aa <[^>]+> ea00 0009 and\.w r0, r0, r9
+0+1ae <[^>]+> ea10 0000 ands\.w r0, r0, r0
+0+1b2 <[^>]+> ea01 4062 and\.w r0, r1, r2, asr #17
+0+1b6 <[^>]+> f001 0081 and\.w r0, r1, #129 ; 0x81
+0+1ba <[^>]+> 4380 bics r0, r0
+0+1bc <[^>]+> 4385 bics r5, r0
+0+1be <[^>]+> 43a8 bics r0, r5
+0+1c0 <[^>]+> 43a8 bics r0, r5
+0+1c2 <[^>]+> ea35 0000 bics\.w r0, r5, r0
+0+1c6 <[^>]+> ea25 0000 bic\.w r0, r5, r0
+0+1ca <[^>]+> ea21 0002 bic\.w r0, r1, r2
+0+1ce <[^>]+> ea20 0900 bic\.w r9, r0, r0
+0+1d2 <[^>]+> ea29 0000 bic\.w r0, r9, r0
+0+1d6 <[^>]+> ea20 0009 bic\.w r0, r0, r9
+0+1da <[^>]+> ea30 0000 bics\.w r0, r0, r0
+0+1de <[^>]+> ea21 4062 bic\.w r0, r1, r2, asr #17
+0+1e2 <[^>]+> f021 0081 bic\.w r0, r1, #129 ; 0x81
+0+1e6 <[^>]+> 4040 eors r0, r0
+0+1e8 <[^>]+> 4045 eors r5, r0
+0+1ea <[^>]+> 4068 eors r0, r5
+0+1ec <[^>]+> 4068 eors r0, r5
+0+1ee <[^>]+> 4068 eors r0, r5
+0+1f0 <[^>]+> ea85 0000 eor\.w r0, r5, r0
+0+1f4 <[^>]+> ea81 0002 eor\.w r0, r1, r2
+0+1f8 <[^>]+> ea80 0900 eor\.w r9, r0, r0
+0+1fc <[^>]+> ea89 0000 eor\.w r0, r9, r0
+0+200 <[^>]+> ea80 0009 eor\.w r0, r0, r9
+0+204 <[^>]+> ea90 0000 eors\.w r0, r0, r0
+0+208 <[^>]+> ea81 4062 eor\.w r0, r1, r2, asr #17
+0+20c <[^>]+> f081 0081 eor\.w r0, r1, #129 ; 0x81
+0+210 <[^>]+> 4300 orrs r0, r0
+0+212 <[^>]+> 4305 orrs r5, r0
+0+214 <[^>]+> 4328 orrs r0, r5
+0+216 <[^>]+> 4328 orrs r0, r5
+0+218 <[^>]+> 4328 orrs r0, r5
+0+21a <[^>]+> ea45 0000 orr\.w r0, r5, r0
+0+21e <[^>]+> ea41 0002 orr\.w r0, r1, r2
+0+222 <[^>]+> ea40 0900 orr\.w r9, r0, r0
+0+226 <[^>]+> ea49 0000 orr\.w r0, r9, r0
+0+22a <[^>]+> ea40 0009 orr\.w r0, r0, r9
+0+22e <[^>]+> ea50 0000 orrs\.w r0, r0, r0
+0+232 <[^>]+> ea41 4062 orr\.w r0, r1, r2, asr #17
+0+236 <[^>]+> f041 0081 orr\.w r0, r1, #129 ; 0x81
+0+23a <[^>]+> ebd0 0000 rsbs r0, r0, r0
+0+23e <[^>]+> ebd5 0500 rsbs r5, r5, r0
+0+242 <[^>]+> ebd0 0005 rsbs r0, r0, r5
+0+246 <[^>]+> ebd0 0005 rsbs r0, r0, r5
+0+24a <[^>]+> ebd5 0000 rsbs r0, r5, r0
+0+24e <[^>]+> ebc5 0000 rsb r0, r5, r0
+0+252 <[^>]+> ebc1 0002 rsb r0, r1, r2
+0+256 <[^>]+> ebc0 0900 rsb r9, r0, r0
+0+25a <[^>]+> ebc9 0000 rsb r0, r9, r0
+0+25e <[^>]+> ebc0 0009 rsb r0, r0, r9
+0+262 <[^>]+> ebd0 0000 rsbs r0, r0, r0
+0+266 <[^>]+> ebc1 4062 rsb r0, r1, r2, asr #17
+0+26a <[^>]+> f1c1 0081 rsb r0, r1, #129 ; 0x81
+0+26e <[^>]+> 4180 sbcs r0, r0
+0+270 <[^>]+> 4185 sbcs r5, r0
+0+272 <[^>]+> 41a8 sbcs r0, r5
+0+274 <[^>]+> 41a8 sbcs r0, r5
+0+276 <[^>]+> eb75 0000 sbcs\.w r0, r5, r0
+0+27a <[^>]+> eb65 0000 sbc\.w r0, r5, r0
+0+27e <[^>]+> eb61 0002 sbc\.w r0, r1, r2
+0+282 <[^>]+> eb60 0900 sbc\.w r9, r0, r0
+0+286 <[^>]+> eb69 0000 sbc\.w r0, r9, r0
+0+28a <[^>]+> eb60 0009 sbc\.w r0, r0, r9
+0+28e <[^>]+> eb70 0000 sbcs\.w r0, r0, r0
+0+292 <[^>]+> eb61 4062 sbc\.w r0, r1, r2, asr #17
+0+296 <[^>]+> f161 0081 sbc\.w r0, r1, #129 ; 0x81
+0+29a <[^>]+> f36f 0000 bfc r0, #0, #1
+0+29e <[^>]+> f36f 0900 bfc r9, #0, #1
+0+2a2 <[^>]+> f36f 0900 bfc r9, #0, #1
+0+2a6 <[^>]+> f36f 5055 bfc r0, #21, #1
+0+2aa <[^>]+> f36f 0011 bfc r0, #0, #18
+0+2ae <[^>]+> f360 0000 bfi r0, r0, #0, #1
+0+2b2 <[^>]+> f360 0900 bfi r9, r0, #0, #1
+0+2b6 <[^>]+> f369 0000 bfi r0, r9, #0, #1
+0+2ba <[^>]+> f360 5055 bfi r0, r0, #21, #1
+0+2be <[^>]+> f360 0011 bfi r0, r0, #0, #18
+0+2c2 <[^>]+> f340 0000 sbfx r0, r0, #0, #1
+0+2c6 <[^>]+> f3c0 0900 ubfx r9, r0, #0, #1
+0+2ca <[^>]+> f349 0000 sbfx r0, r9, #0, #1
+0+2ce <[^>]+> f3c0 5040 ubfx r0, r0, #21, #1
+0+2d2 <[^>]+> f340 0011 sbfx r0, r0, #0, #18
+0+2d6 <[^>]+> d0fe beq\.n 0+2d6 <[^>]+>
+0+2d8 <[^>]+> d029 beq\.n 0+32e <[^>]+>
+0+2da <[^>]+> d1fc bne\.n 0+2d6 <[^>]+>
+0+2dc <[^>]+> d127 bne\.n 0+32e <[^>]+>
+0+2de <[^>]+> d2fa bcs\.n 0+2d6 <[^>]+>
+0+2e0 <[^>]+> d225 bcs\.n 0+32e <[^>]+>
+0+2e2 <[^>]+> d2f8 bcs\.n 0+2d6 <[^>]+>
+0+2e4 <[^>]+> d223 bcs\.n 0+32e <[^>]+>
+0+2e6 <[^>]+> d3f6 bcc\.n 0+2d6 <[^>]+>
+0+2e8 <[^>]+> d321 bcc\.n 0+32e <[^>]+>
+0+2ea <[^>]+> d3f4 bcc\.n 0+2d6 <[^>]+>
+0+2ec <[^>]+> d31f bcc\.n 0+32e <[^>]+>
+0+2ee <[^>]+> d3f2 bcc\.n 0+2d6 <[^>]+>
+0+2f0 <[^>]+> d31d bcc\.n 0+32e <[^>]+>
+0+2f2 <[^>]+> d4f0 bmi\.n 0+2d6 <[^>]+>
+0+2f4 <[^>]+> d41b bmi\.n 0+32e <[^>]+>
+0+2f6 <[^>]+> d5ee bpl\.n 0+2d6 <[^>]+>
+0+2f8 <[^>]+> d519 bpl\.n 0+32e <[^>]+>
+0+2fa <[^>]+> d6ec bvs\.n 0+2d6 <[^>]+>
+0+2fc <[^>]+> d617 bvs\.n 0+32e <[^>]+>
+0+2fe <[^>]+> d7ea bvc\.n 0+2d6 <[^>]+>
+0+300 <[^>]+> d715 bvc\.n 0+32e <[^>]+>
+0+302 <[^>]+> d8e8 bhi\.n 0+2d6 <[^>]+>
+0+304 <[^>]+> d813 bhi\.n 0+32e <[^>]+>
+0+306 <[^>]+> d9e6 bls\.n 0+2d6 <[^>]+>
+0+308 <[^>]+> d911 bls\.n 0+32e <[^>]+>
+0+30a <[^>]+> d7e4 bvc\.n 0+2d6 <[^>]+>
+0+30c <[^>]+> d70f bvc\.n 0+32e <[^>]+>
+0+30e <[^>]+> d8e2 bhi\.n 0+2d6 <[^>]+>
+0+310 <[^>]+> d80d bhi\.n 0+32e <[^>]+>
+0+312 <[^>]+> d9e0 bls\.n 0+2d6 <[^>]+>
+0+314 <[^>]+> d90b bls\.n 0+32e <[^>]+>
+0+316 <[^>]+> dade bge\.n 0+2d6 <[^>]+>
+0+318 <[^>]+> da09 bge\.n 0+32e <[^>]+>
+0+31a <[^>]+> dbdc blt\.n 0+2d6 <[^>]+>
+0+31c <[^>]+> db07 blt\.n 0+32e <[^>]+>
+0+31e <[^>]+> dcda bgt\.n 0+2d6 <[^>]+>
+0+320 <[^>]+> dc05 bgt\.n 0+32e <[^>]+>
+0+322 <[^>]+> ddd8 ble\.n 0+2d6 <[^>]+>
+0+324 <[^>]+> dd03 ble\.n 0+32e <[^>]+>
+0+326 <[^>]+> ded6 bal\.n 0+2d6 <[^>]+>
+0+328 <[^>]+> de01 bal\.n 0+32e <[^>]+>
+0+32a <[^>]+> e7d4 b\.n 0+2d6 <[^>]+>
+0+32c <[^>]+> e7ff b\.n 0+32e <[^>]+>
+0+32e <[^>]+> f43f affe beq\.w 0+32e <[^>]+>
+0+332 <[^>]+> f000 8058 beq\.w 0+3e6 <[^>]+>
+0+336 <[^>]+> f47f affa bne\.w 0+32e <[^>]+>
+0+33a <[^>]+> f040 8054 bne\.w 0+3e6 <[^>]+>
+0+33e <[^>]+> f4bf aff6 bcs\.w 0+32e <[^>]+>
+0+342 <[^>]+> f080 8050 bcs\.w 0+3e6 <[^>]+>
+0+346 <[^>]+> f4bf aff2 bcs\.w 0+32e <[^>]+>
+0+34a <[^>]+> f080 804c bcs\.w 0+3e6 <[^>]+>
+0+34e <[^>]+> f4ff afee bcc\.w 0+32e <[^>]+>
+0+352 <[^>]+> f0c0 8048 bcc\.w 0+3e6 <[^>]+>
+0+356 <[^>]+> f4ff afea bcc\.w 0+32e <[^>]+>
+0+35a <[^>]+> f0c0 8044 bcc\.w 0+3e6 <[^>]+>
+0+35e <[^>]+> f4ff afe6 bcc\.w 0+32e <[^>]+>
+0+362 <[^>]+> f0c0 8040 bcc\.w 0+3e6 <[^>]+>
+0+366 <[^>]+> f53f afe2 bmi\.w 0+32e <[^>]+>
+0+36a <[^>]+> f100 803c bmi\.w 0+3e6 <[^>]+>
+0+36e <[^>]+> f57f afde bpl\.w 0+32e <[^>]+>
+0+372 <[^>]+> f140 8038 bpl\.w 0+3e6 <[^>]+>
+0+376 <[^>]+> f5bf afda bvs\.w 0+32e <[^>]+>
+0+37a <[^>]+> f180 8034 bvs\.w 0+3e6 <[^>]+>
+0+37e <[^>]+> f5ff afd6 bvc\.w 0+32e <[^>]+>
+0+382 <[^>]+> f1c0 8030 bvc\.w 0+3e6 <[^>]+>
+0+386 <[^>]+> f63f afd2 bhi\.w 0+32e <[^>]+>
+0+38a <[^>]+> f200 802c bhi\.w 0+3e6 <[^>]+>
+0+38e <[^>]+> f67f afce bls\.w 0+32e <[^>]+>
+0+392 <[^>]+> f240 8028 bls\.w 0+3e6 <[^>]+>
+0+396 <[^>]+> f5ff afca bvc\.w 0+32e <[^>]+>
+0+39a <[^>]+> f1c0 8024 bvc\.w 0+3e6 <[^>]+>
+0+39e <[^>]+> f63f afc6 bhi\.w 0+32e <[^>]+>
+0+3a2 <[^>]+> f200 8020 bhi\.w 0+3e6 <[^>]+>
+0+3a6 <[^>]+> f67f afc2 bls\.w 0+32e <[^>]+>
+0+3aa <[^>]+> f240 801c bls\.w 0+3e6 <[^>]+>
+0+3ae <[^>]+> f6bf afbe bge\.w 0+32e <[^>]+>
+0+3b2 <[^>]+> f280 8018 bge\.w 0+3e6 <[^>]+>
+0+3b6 <[^>]+> f6ff afba blt\.w 0+32e <[^>]+>
+0+3ba <[^>]+> f2c0 8014 blt\.w 0+3e6 <[^>]+>
+0+3be <[^>]+> f73f afb6 bgt\.w 0+32e <[^>]+>
+0+3c2 <[^>]+> f300 8010 bgt\.w 0+3e6 <[^>]+>
+0+3c6 <[^>]+> f77f afb2 ble\.w 0+32e <[^>]+>
+0+3ca <[^>]+> f340 800c ble\.w 0+3e6 <[^>]+>
+0+3ce <[^>]+> f7ff bfae b\.w 0+32e <[^>]+>
+0+3d2 <[^>]+> f000 b808 b\.w 0+3e6 <[^>]+>
+0+3d6 <[^>]+> f000 f995 bl 0+32e <[^>]+>
+ 3d6: R_ARM_THM_CALL \.text
+0+3da <[^>]+> f000 f9f1 bl 0+3e6 <[^>]+>
+ 3da: R_ARM_THM_CALL \.text
+0+3de <[^>]+> f000 e995 blx 0+32e <[^>]+>
+ 3de: R_ARM_THM_XPC22 \.text
+0+3e2 <[^>]+> f000 e9f1 blx 0+3e6 <[^>]+>
+ 3e2: R_ARM_THM_XPC22 \.text
+0+3e6 <[^>]+> 4700 bx r0
+0+3e8 <[^>]+> 4748 bx r9
+0+3ea <[^>]+> 4780 blx r0
+0+3ec <[^>]+> 47c8 blx r9
+0+3ee <[^>]+> f3c0 8f00 bxj r0
+0+3f2 <[^>]+> f3c9 8f00 bxj r9
+0+3f6 <[^>]+> fab0 f080 clz r0, r0
+0+3fa <[^>]+> fab0 f980 clz r9, r0
+0+3fe <[^>]+> fab9 f089 clz r0, r9
+0+402 <[^>]+> b661 cpsie f
+0+404 <[^>]+> b672 cpsid i
+0+406 <[^>]+> b664 cpsie a
+0+408 <[^>]+> f3af 8620 cpsid\.w f
+0+40c <[^>]+> f3af 8440 cpsie\.w i
+0+410 <[^>]+> f3af 8680 cpsid\.w a
+0+414 <[^>]+> f3af 8540 cpsie i, #0
+0+418 <[^>]+> f3af 8751 cpsid i, #17
+0+41c <[^>]+> f3af 8100 cps #0
+0+420 <[^>]+> f3af 8111 cps #17
+0+424 <[^>]+> 4600 mov r0, r0
+0+426 <[^>]+> 4681 mov r9, r0
+0+428 <[^>]+> 4648 mov r0, r9
+0+42a <[^>]+> ea4f 0000 mov\.w r0, r0
+0+42e <[^>]+> ea4f 0900 mov\.w r9, r0
+0+432 <[^>]+> ea4f 0009 mov\.w r0, r9
+0+436 <[^>]+> b910 czbne r0, 0+43e <[^>]+>
+0+438 <[^>]+> b105 czbeq r5, 0+43c <[^>]+>
+0+43a <[^>]+> bf00 nop
+0+43c <[^>]+> bf10 yield
+0+43e <[^>]+> bf20 wfe
+0+440 <[^>]+> bf30 wfi
+0+442 <[^>]+> bf40 sev
+0+444 <[^>]+> f3af 8000 nop\.w
+0+448 <[^>]+> f3af 8001 yield\.w
+0+44c <[^>]+> f3af 8002 wfe\.w
+0+450 <[^>]+> f3af 8003 wfi\.w
+0+454 <[^>]+> f3af 9004 sev\.w
+0+458 <[^>]+> bf90 nop \{9\}
+0+45a <[^>]+> f3af 8081 nop\.w \{129\}
+0+45e <[^>]+> bf08 it eq
+0+460 <[^>]+> bf00 nop
+0+462 <[^>]+> bf18 it ne
+0+464 <[^>]+> bf00 nop
+0+466 <[^>]+> bf28 it cs
+0+468 <[^>]+> bf00 nop
+0+46a <[^>]+> bf28 it cs
+0+46c <[^>]+> bf00 nop
+0+46e <[^>]+> bf38 it cc
+0+470 <[^>]+> bf00 nop
+0+472 <[^>]+> bf38 it cc
+0+474 <[^>]+> bf00 nop
+0+476 <[^>]+> bf38 it cc
+0+478 <[^>]+> bf00 nop
+0+47a <[^>]+> bf48 it mi
+0+47c <[^>]+> bf00 nop
+0+47e <[^>]+> bf58 it pl
+0+480 <[^>]+> bf00 nop
+0+482 <[^>]+> bf68 it vs
+0+484 <[^>]+> bf00 nop
+0+486 <[^>]+> bf78 it vc
+0+488 <[^>]+> bf00 nop
+0+48a <[^>]+> bf88 it hi
+0+48c <[^>]+> bf00 nop
+0+48e <[^>]+> bfa8 it ge
+0+490 <[^>]+> bf00 nop
+0+492 <[^>]+> bfb8 it lt
+0+494 <[^>]+> bf00 nop
+0+496 <[^>]+> bfc8 it gt
+0+498 <[^>]+> bf00 nop
+0+49a <[^>]+> bfd8 it le
+0+49c <[^>]+> bf00 nop
+0+49e <[^>]+> bfe8 it al
+0+4a0 <[^>]+> bf00 nop
+0+4a2 <[^>]+> bf04 itt eq
+0+4a4 <[^>]+> bf00 nop
+0+4a6 <[^>]+> bf00 nop
+0+4a8 <[^>]+> bf0c ite eq
+0+4aa <[^>]+> bf00 nop
+0+4ac <[^>]+> bf00 nop
+0+4ae <[^>]+> bf02 ittt eq
+0+4b0 <[^>]+> bf00 nop
+0+4b2 <[^>]+> bf00 nop
+0+4b4 <[^>]+> bf00 nop
+0+4b6 <[^>]+> bf0a itet eq
+0+4b8 <[^>]+> bf00 nop
+0+4ba <[^>]+> bf00 nop
+0+4bc <[^>]+> bf00 nop
+0+4be <[^>]+> bf06 itte eq
+0+4c0 <[^>]+> bf00 nop
+0+4c2 <[^>]+> bf00 nop
+0+4c4 <[^>]+> bf00 nop
+0+4c6 <[^>]+> bf0e itee eq
+0+4c8 <[^>]+> bf00 nop
+0+4ca <[^>]+> bf00 nop
+0+4cc <[^>]+> bf00 nop
+0+4ce <[^>]+> bf01 itttt eq
+0+4d0 <[^>]+> bf00 nop
+0+4d2 <[^>]+> bf00 nop
+0+4d4 <[^>]+> bf00 nop
+0+4d6 <[^>]+> bf00 nop
+0+4d8 <[^>]+> bf09 itett eq
+0+4da <[^>]+> bf00 nop
+0+4dc <[^>]+> bf00 nop
+0+4de <[^>]+> bf00 nop
+0+4e0 <[^>]+> bf00 nop
+0+4e2 <[^>]+> bf05 ittet eq
+0+4e4 <[^>]+> bf00 nop
+0+4e6 <[^>]+> bf00 nop
+0+4e8 <[^>]+> bf00 nop
+0+4ea <[^>]+> bf00 nop
+0+4ec <[^>]+> bf03 ittte eq
+0+4ee <[^>]+> bf00 nop
+0+4f0 <[^>]+> bf00 nop
+0+4f2 <[^>]+> bf00 nop
+0+4f4 <[^>]+> bf00 nop
+0+4f6 <[^>]+> bf07 ittee eq
+0+4f8 <[^>]+> bf00 nop
+0+4fa <[^>]+> bf00 nop
+0+4fc <[^>]+> bf00 nop
+0+4fe <[^>]+> bf00 nop
+0+500 <[^>]+> bf0b itete eq
+0+502 <[^>]+> bf00 nop
+0+504 <[^>]+> bf00 nop
+0+506 <[^>]+> bf00 nop
+0+508 <[^>]+> bf00 nop
+0+50a <[^>]+> bf0d iteet eq
+0+50c <[^>]+> bf00 nop
+0+50e <[^>]+> bf00 nop
+0+510 <[^>]+> bf00 nop
+0+512 <[^>]+> bf00 nop
+0+514 <[^>]+> bf0f iteee eq
+0+516 <[^>]+> bf00 nop
+0+518 <[^>]+> bf00 nop
+0+51a <[^>]+> bf00 nop
+0+51c <[^>]+> bf00 nop
+0+51e <[^>]+> bf1c itt ne
+0+520 <[^>]+> bf00 nop
+0+522 <[^>]+> bf00 nop
+0+524 <[^>]+> bf14 ite ne
+0+526 <[^>]+> bf00 nop
+0+528 <[^>]+> bf00 nop
+0+52a <[^>]+> bf1e ittt ne
+0+52c <[^>]+> bf00 nop
+0+52e <[^>]+> bf00 nop
+0+530 <[^>]+> bf00 nop
+0+532 <[^>]+> bf16 itet ne
+0+534 <[^>]+> bf00 nop
+0+536 <[^>]+> bf00 nop
+0+538 <[^>]+> bf00 nop
+0+53a <[^>]+> bf1a itte ne
+0+53c <[^>]+> bf00 nop
+0+53e <[^>]+> bf00 nop
+0+540 <[^>]+> bf00 nop
+0+542 <[^>]+> bf12 itee ne
+0+544 <[^>]+> bf00 nop
+0+546 <[^>]+> bf00 nop
+0+548 <[^>]+> bf00 nop
+0+54a <[^>]+> bf1f itttt ne
+0+54c <[^>]+> bf00 nop
+0+54e <[^>]+> bf00 nop
+0+550 <[^>]+> bf00 nop
+0+552 <[^>]+> bf00 nop
+0+554 <[^>]+> bf17 itett ne
+0+556 <[^>]+> bf00 nop
+0+558 <[^>]+> bf00 nop
+0+55a <[^>]+> bf00 nop
+0+55c <[^>]+> bf00 nop
+0+55e <[^>]+> bf1b ittet ne
+0+560 <[^>]+> bf00 nop
+0+562 <[^>]+> bf00 nop
+0+564 <[^>]+> bf00 nop
+0+566 <[^>]+> bf00 nop
+0+568 <[^>]+> bf1d ittte ne
+0+56a <[^>]+> bf00 nop
+0+56c <[^>]+> bf00 nop
+0+56e <[^>]+> bf00 nop
+0+570 <[^>]+> bf00 nop
+0+572 <[^>]+> bf19 ittee ne
+0+574 <[^>]+> bf00 nop
+0+576 <[^>]+> bf00 nop
+0+578 <[^>]+> bf00 nop
+0+57a <[^>]+> bf00 nop
+0+57c <[^>]+> bf15 itete ne
+0+57e <[^>]+> bf00 nop
+0+580 <[^>]+> bf00 nop
+0+582 <[^>]+> bf00 nop
+0+584 <[^>]+> bf00 nop
+0+586 <[^>]+> bf13 iteet ne
+0+588 <[^>]+> bf00 nop
+0+58a <[^>]+> bf00 nop
+0+58c <[^>]+> bf00 nop
+0+58e <[^>]+> bf00 nop
+0+590 <[^>]+> bf11 iteee ne
+0+592 <[^>]+> bf00 nop
+0+594 <[^>]+> bf00 nop
+0+596 <[^>]+> bf00 nop
+0+598 <[^>]+> bf00 nop
+0+59a <[^>]+> f895 1000 ldrb\.w r1, \[r5\]
+0+59e <[^>]+> f895 1330 ldrb\.w r1, \[r5, #816\]
+0+5a2 <[^>]+> f815 1c30 ldrb\.w r1, \[r5, #-48\]
+0+5a6 <[^>]+> f815 1b30 ldrb\.w r1, \[r5, #48\]!
+0+5aa <[^>]+> f815 1930 ldrb\.w r1, \[r5, #-48\]!
+0+5ae <[^>]+> f815 1f30 ldrb\.w r1, \[r5\], #48
+0+5b2 <[^>]+> f815 1d30 ldrb\.w r1, \[r5\], #-48
+0+5b6 <[^>]+> 5d29 ldrb r1, \[r5, r4\]
+0+5b8 <[^>]+> f819 100c ldrb\.w r1, \[r9, ip\]
+0+5bc <[^>]+> f89f 10b0 ldrb\.w r1, \[pc, #176\]
+0+5c0 <[^>]+> f81f 1c26 ldrb\.w r1, \[pc, #-3110\]
+0+5c4 <[^>]+> f995 1000 ldrsb\.w r1, \[r5\]
+0+5c8 <[^>]+> f995 1330 ldrsb\.w r1, \[r5, #816\]
+0+5cc <[^>]+> f915 1c30 ldrsb\.w r1, \[r5, #-48\]
+0+5d0 <[^>]+> f915 1b30 ldrsb\.w r1, \[r5, #48\]!
+0+5d4 <[^>]+> f915 1930 ldrsb\.w r1, \[r5, #-48\]!
+0+5d8 <[^>]+> f915 1f30 ldrsb\.w r1, \[r5\], #48
+0+5dc <[^>]+> f915 1d30 ldrsb\.w r1, \[r5\], #-48
+0+5e0 <[^>]+> 5729 ldrsb r1, \[r5, r4\]
+0+5e2 <[^>]+> f919 100c ldrsb\.w r1, \[r9, ip\]
+0+5e6 <[^>]+> f99f 1086 ldrsb\.w r1, \[pc, #134\]
+0+5ea <[^>]+> f91f 1c50 ldrsb\.w r1, \[pc, #-3152\]
+0+5ee <[^>]+> f8b5 1000 ldrh\.w r1, \[r5\]
+0+5f2 <[^>]+> f8b5 1330 ldrh\.w r1, \[r5, #816\]
+0+5f6 <[^>]+> f835 1c30 ldrh\.w r1, \[r5, #-48\]
+0+5fa <[^>]+> f835 1b30 ldrh\.w r1, \[r5, #48\]!
+0+5fe <[^>]+> f835 1930 ldrh\.w r1, \[r5, #-48\]!
+0+602 <[^>]+> f835 1f30 ldrh\.w r1, \[r5\], #48
+0+606 <[^>]+> f835 1d30 ldrh\.w r1, \[r5\], #-48
+0+60a <[^>]+> 5b29 ldrh r1, \[r5, r4\]
+0+60c <[^>]+> f839 100c ldrh\.w r1, \[r9, ip\]
+0+610 <[^>]+> f8bf 105c ldrh\.w r1, \[pc, #92\]
+0+614 <[^>]+> f83f 1c7a ldrh\.w r1, \[pc, #-3194\]
+0+618 <[^>]+> f9b5 1000 ldrsh\.w r1, \[r5\]
+0+61c <[^>]+> f9b5 1330 ldrsh\.w r1, \[r5, #816\]
+0+620 <[^>]+> f935 1c30 ldrsh\.w r1, \[r5, #-48\]
+0+624 <[^>]+> f935 1b30 ldrsh\.w r1, \[r5, #48\]!
+0+628 <[^>]+> f935 1930 ldrsh\.w r1, \[r5, #-48\]!
+0+62c <[^>]+> f935 1f30 ldrsh\.w r1, \[r5\], #48
+0+630 <[^>]+> f935 1d30 ldrsh\.w r1, \[r5\], #-48
+0+634 <[^>]+> 5f29 ldrsh r1, \[r5, r4\]
+0+636 <[^>]+> f939 100c ldrsh\.w r1, \[r9, ip\]
+0+63a <[^>]+> f9bf 1032 ldrsh\.w r1, \[pc, #50\]
+0+63e <[^>]+> f93f 1ca4 ldrsh\.w r1, \[pc, #-3236\]
+0+642 <[^>]+> f8d5 1000 ldr\.w r1, \[r5\]
+0+646 <[^>]+> f8d5 1330 ldr\.w r1, \[r5, #816\]
+0+64a <[^>]+> f855 1c30 ldr\.w r1, \[r5, #-48\]
+0+64e <[^>]+> f855 1b30 ldr\.w r1, \[r5, #48\]!
+0+652 <[^>]+> f855 1930 ldr\.w r1, \[r5, #-48\]!
+0+656 <[^>]+> f855 1f30 ldr\.w r1, \[r5\], #48
+0+65a <[^>]+> f855 1d30 ldr\.w r1, \[r5\], #-48
+0+65e <[^>]+> 5929 ldr r1, \[r5, r4\]
+0+660 <[^>]+> f859 100c ldr\.w r1, \[r9, ip\]
+0+664 <[^>]+> f8df 1008 ldr\.w r1, \[pc, #8\]
+0+668 <[^>]+> f85f 1cce ldr\.w r1, \[pc, #-3278\]
+0+66c <[^>]+> f885 1000 strb\.w r1, \[r5\]
+0+670 <[^>]+> f885 1330 strb\.w r1, \[r5, #816\]
+0+674 <[^>]+> f805 1c30 strb\.w r1, \[r5, #-48\]
+0+678 <[^>]+> f805 1b30 strb\.w r1, \[r5, #48\]!
+0+67c <[^>]+> f805 1930 strb\.w r1, \[r5, #-48\]!
+0+680 <[^>]+> f805 1f30 strb\.w r1, \[r5\], #48
+0+684 <[^>]+> f805 1d30 strb\.w r1, \[r5\], #-48
+0+688 <[^>]+> 5529 strb r1, \[r5, r4\]
+0+68a <[^>]+> f809 100c strb\.w r1, \[r9, ip\]
+0+68e <[^>]+> f88f 1088 strb\.w r1, \[pc, #136\]
+0+692 <[^>]+> f80f 1c26 strb\.w r1, \[pc, #-3110\]
+0+696 <[^>]+> f8a5 1000 strh\.w r1, \[r5\]
+0+69a <[^>]+> f8a5 1330 strh\.w r1, \[r5, #816\]
+0+69e <[^>]+> f825 1c30 strh\.w r1, \[r5, #-48\]
+0+6a2 <[^>]+> f825 1b30 strh\.w r1, \[r5, #48\]!
+0+6a6 <[^>]+> f825 1930 strh\.w r1, \[r5, #-48\]!
+0+6aa <[^>]+> f825 1f30 strh\.w r1, \[r5\], #48
+0+6ae <[^>]+> f825 1d30 strh\.w r1, \[r5\], #-48
+0+6b2 <[^>]+> 5329 strh r1, \[r5, r4\]
+0+6b4 <[^>]+> f829 100c strh\.w r1, \[r9, ip\]
+0+6b8 <[^>]+> f8af 105e strh\.w r1, \[pc, #94\]
+0+6bc <[^>]+> f82f 1c50 strh\.w r1, \[pc, #-3152\]
+0+6c0 <[^>]+> f8c5 1000 str\.w r1, \[r5\]
+0+6c4 <[^>]+> f8c5 1330 str\.w r1, \[r5, #816\]
+0+6c8 <[^>]+> f845 1c30 str\.w r1, \[r5, #-48\]
+0+6cc <[^>]+> f845 1b30 str\.w r1, \[r5, #48\]!
+0+6d0 <[^>]+> f845 1930 str\.w r1, \[r5, #-48\]!
+0+6d4 <[^>]+> f845 1f30 str\.w r1, \[r5\], #48
+0+6d8 <[^>]+> f845 1d30 str\.w r1, \[r5\], #-48
+0+6dc <[^>]+> 5129 str r1, \[r5, r4\]
+0+6de <[^>]+> f849 100c str\.w r1, \[r9, ip\]
+0+6e2 <[^>]+> f8cf 1034 str\.w r1, \[pc, #52\]
+0+6e6 <[^>]+> f84f 1c7a str\.w r1, \[pc, #-3194\]
+0+6ea <[^>]+> f895 f000 pld \[r5\]
+0+6ee <[^>]+> f895 f330 pld \[r5, #816\]
+0+6f2 <[^>]+> f815 fc30 pld \[r5, #-48\]
+0+6f6 <[^>]+> f815 fb30 pld \[r5, #48\]!
+0+6fa <[^>]+> f815 f930 pld \[r5, #-48\]!
+0+6fe <[^>]+> f815 ff30 pld \[r5\], #48
+0+702 <[^>]+> f815 fd30 pld \[r5\], #-48
+0+706 <[^>]+> f815 f000 pld \[r5, r0\]
+0+70a <[^>]+> f819 f000 pld \[r9, r0\]
+0+70e <[^>]+> f89f f008 pld \[pc, #8\]
+0+712 <[^>]+> f81f fca6 pld \[pc, #-3238\]
+0+716 <[^>]+> e9d5 2300 ldrd r2, r3, \[r5\]
+0+71a <[^>]+> e9d5 230c ldrd r2, r3, \[r5, #48\]
+0+71e <[^>]+> e955 230c ldrd r2, r3, \[r5, #-48\]
+0+722 <[^>]+> e9c5 2300 strd r2, r3, \[r5\]
+0+726 <[^>]+> e9c5 230c strd r2, r3, \[r5, #48\]
+0+72a <[^>]+> e945 230c strd r2, r3, \[r5, #-48\]
+0+72e <[^>]+> f835 1e00 ldrht r1, \[r5\]
+0+732 <[^>]+> f835 1e30 ldrht r1, \[r5, #48\]
+0+736 <[^>]+> f915 1e00 ldrsbt r1, \[r5\]
+0+73a <[^>]+> f915 1e30 ldrsbt r1, \[r5, #48\]
+0+73e <[^>]+> f835 1e00 ldrht r1, \[r5\]
+0+742 <[^>]+> f835 1e30 ldrht r1, \[r5, #48\]
+0+746 <[^>]+> f935 1e00 ldrsht r1, \[r5\]
+0+74a <[^>]+> f935 1e30 ldrsht r1, \[r5, #48\]
+0+74e <[^>]+> f855 1e00 ldrt r1, \[r5\]
+0+752 <[^>]+> f855 1e30 ldrt r1, \[r5, #48\]
+0+756 <[^>]+> e8d4 1f4f ldrexb r1, \[r4\]
+0+75a <[^>]+> e8d4 1f5f ldrexh r1, \[r4\]
+0+75e <[^>]+> e854 1f00 ldrex r1, \[r4\]
+0+762 <[^>]+> e8d4 127f ldrexd r1, r2, \[r4\]
+0+766 <[^>]+> e8c4 2f41 strexb r1, r2, \[r4\]
+0+76a <[^>]+> e8c4 2f51 strexh r1, r2, \[r4\]
+0+76e <[^>]+> e844 2100 strex r1, r2, \[r4\]
+0+772 <[^>]+> e8c4 2371 strexd r1, r2, r3, \[r4\]
+0+776 <[^>]+> e854 1f81 ldrex r1, \[r4, #516\]
+0+77a <[^>]+> e844 2181 strex r1, r2, \[r4, #516\]
+0+77e <[^>]+> c80e ldmia r0!, \{r1, r2, r3\}
+0+780 <[^>]+> ca07 ldmia r2!, \{r0, r1, r2\}
+0+782 <[^>]+> e892 0007 ldmia\.w r2, \{r0, r1, r2\}
+0+786 <[^>]+> e899 0007 ldmia\.w r9, \{r0, r1, r2\}
+0+78a <[^>]+> e890 0580 ldmia\.w r0, \{r7, r8, sl\}
+0+78e <[^>]+> e8b0 0580 ldmia\.w r0!, \{r7, r8, sl\}
+0+792 <[^>]+> c00e stmia r0!, \{r1, r2, r3\}
+0+794 <[^>]+> c20b stmia r2!, \{r0, r1, r3\}
+0+796 <[^>]+> e8a2 000b stmia\.w r2!, \{r0, r1, r3\}
+0+79a <[^>]+> e889 0007 stmia\.w r9, \{r0, r1, r2\}
+0+79e <[^>]+> e880 0580 stmia\.w r0, \{r7, r8, sl\}
+0+7a2 <[^>]+> e8a0 0580 stmia\.w r0!, \{r7, r8, sl\}
+0+7a6 <[^>]+> e900 0580 stmdb r0, \{r7, r8, sl\}
+0+7aa <[^>]+> e910 0580 ldmdb r0, \{r7, r8, sl\}
+0+7ae <[^>]+> fb00 0000 mla r0, r0, r0, r0
+0+7b2 <[^>]+> fb00 0010 mls r0, r0, r0, r0
+0+7b6 <[^>]+> fb00 0900 mla r9, r0, r0, r0
+0+7ba <[^>]+> fb09 0000 mla r0, r9, r0, r0
+0+7be <[^>]+> fb00 0009 mla r0, r0, r9, r0
+0+7c2 <[^>]+> fb00 9000 mla r0, r0, r0, r9
+0+7c6 <[^>]+> 4200 tst r0, r0
+0+7c8 <[^>]+> 4200 tst r0, r0
+0+7ca <[^>]+> 4205 tst r5, r0
+0+7cc <[^>]+> 4228 tst r0, r5
+0+7ce <[^>]+> ea10 4f65 tst\.w r0, r5, asr #17
+0+7d2 <[^>]+> ea10 0f00 tst\.w r0, r0
+0+7d6 <[^>]+> ea19 0f00 tst\.w r9, r0
+0+7da <[^>]+> ea10 0f09 tst\.w r0, r9
+0+7de <[^>]+> f010 0f81 tst\.w r0, #129 ; 0x81
+0+7e2 <[^>]+> f015 0f81 tst\.w r5, #129 ; 0x81
+0+7e6 <[^>]+> ea90 0f00 teq r0, r0
+0+7ea <[^>]+> ea90 0f00 teq r0, r0
+0+7ee <[^>]+> ea95 0f00 teq r5, r0
+0+7f2 <[^>]+> ea90 0f05 teq r0, r5
+0+7f6 <[^>]+> ea90 4f65 teq r0, r5, asr #17
+0+7fa <[^>]+> ea90 0f00 teq r0, r0
+0+7fe <[^>]+> ea99 0f00 teq r9, r0
+0+802 <[^>]+> ea90 0f09 teq r0, r9
+0+806 <[^>]+> f090 0f81 teq r0, #129 ; 0x81
+0+80a <[^>]+> f095 0f81 teq r5, #129 ; 0x81
+0+80e <[^>]+> 4280 cmp r0, r0
+0+810 <[^>]+> 4280 cmp r0, r0
+0+812 <[^>]+> 4285 cmp r5, r0
+0+814 <[^>]+> 42a8 cmp r0, r5
+0+816 <[^>]+> ebb0 4f65 cmp\.w r0, r5, asr #17
+0+81a <[^>]+> ebb0 0f00 cmp\.w r0, r0
+0+81e <[^>]+> 4581 cmp r9, r0
+0+820 <[^>]+> ebb0 0f09 cmp\.w r0, r9
+0+824 <[^>]+> f1b0 0f81 cmp\.w r0, #129 ; 0x81
+0+828 <[^>]+> f1b5 0f81 cmp\.w r5, #129 ; 0x81
+0+82c <[^>]+> 42c0 cmn r0, r0
+0+82e <[^>]+> 42c0 cmn r0, r0
+0+830 <[^>]+> 42c5 cmn r5, r0
+0+832 <[^>]+> 42e8 cmn r0, r5
+0+834 <[^>]+> eb10 4f65 cmn\.w r0, r5, asr #17
+0+838 <[^>]+> eb10 0f00 cmn\.w r0, r0
+0+83c <[^>]+> eb19 0f00 cmn\.w r9, r0
+0+840 <[^>]+> eb10 0f09 cmn\.w r0, r9
+0+844 <[^>]+> f110 0f81 cmn\.w r0, #129 ; 0x81
+0+848 <[^>]+> f115 0f81 cmn\.w r5, #129 ; 0x81
+0+84c <[^>]+> 1c00 adds r0, r0, #0
+0+84e <[^>]+> 4600 mov r0, r0
+0+850 <[^>]+> 1c05 adds r5, r0, #0
+0+852 <[^>]+> 4628 mov r0, r5
+0+854 <[^>]+> ea4f 4065 mov\.w r0, r5, asr #17
+0+858 <[^>]+> ea4f 0000 mov\.w r0, r0
+0+85c <[^>]+> ea5f 0900 movs\.w r9, r0
+0+860 <[^>]+> ea5f 0009 movs\.w r0, r9
+0+864 <[^>]+> f04f 0081 mov\.w r0, #129 ; 0x81
+0+868 <[^>]+> f04f 0581 mov\.w r5, #129 ; 0x81
+0+86c <[^>]+> 43c0 mvns r0, r0
+0+86e <[^>]+> ea6f 0000 mvn\.w r0, r0
+0+872 <[^>]+> 43c5 mvns r5, r0
+0+874 <[^>]+> ea6f 0005 mvn\.w r0, r5
+0+878 <[^>]+> ea6f 4065 mvn\.w r0, r5, asr #17
+0+87c <[^>]+> ea6f 0000 mvn\.w r0, r0
+0+880 <[^>]+> ea7f 0900 mvns\.w r9, r0
+0+884 <[^>]+> ea7f 0009 mvns\.w r0, r9
+0+888 <[^>]+> f06f 0081 mvn\.w r0, #129 ; 0x81
+0+88c <[^>]+> f06f 0581 mvn\.w r5, #129 ; 0x81
+0+890 <[^>]+> f240 0000 movw r0, #0 ; 0x0
+0+894 <[^>]+> f2c0 0000 movt r0, #0 ; 0x0
+0+898 <[^>]+> f240 0900 movw r9, #0 ; 0x0
+0+89c <[^>]+> f249 0000 movw r0, #36864 ; 0x9000
+0+8a0 <[^>]+> f640 0000 movw r0, #2048 ; 0x800
+0+8a4 <[^>]+> f240 5000 movw r0, #1280 ; 0x500
+0+8a8 <[^>]+> f240 0081 movw r0, #129 ; 0x81
+0+8ac <[^>]+> f64f 70ff movw r0, #65535 ; 0xffff
+0+8b0 <[^>]+> f3ef 8000 mrs r0, SPSR
+0+8b4 <[^>]+> f3ff 8000 mrs r0, CPSR
+0+8b8 <[^>]+> f3ef 8900 mrs r9, SPSR
+0+8bc <[^>]+> f3ff 8900 mrs r9, CPSR
+0+8c0 <[^>]+> f380 8100 msr SPSR_c, r0
+0+8c4 <[^>]+> f390 8100 msr CPSR_c, r0
+0+8c8 <[^>]+> f389 8100 msr SPSR_c, r9
+0+8cc <[^>]+> f380 8200 msr SPSR_x, r0
+0+8d0 <[^>]+> f380 8400 msr SPSR_s, r0
+0+8d4 <[^>]+> f380 8800 msr SPSR_f, r0
+0+8d8 <[^>]+> fb00 f000 mul\.w r0, r0, r0
+0+8dc <[^>]+> fb09 f000 mul\.w r0, r9, r0
+0+8e0 <[^>]+> fb00 f009 mul\.w r0, r0, r9
+0+8e4 <[^>]+> fb00 f000 mul\.w r0, r0, r0
+0+8e8 <[^>]+> fb00 f909 mul\.w r9, r0, r9
+0+8ec <[^>]+> 4345 muls r5, r0
+0+8ee <[^>]+> 4345 muls r5, r0
+0+8f0 <[^>]+> 4368 muls r0, r5
+0+8f2 <[^>]+> fb80 0100 smull r0, r1, r0, r0
+0+8f6 <[^>]+> fba0 0100 umull r0, r1, r0, r0
+0+8fa <[^>]+> fbc0 0100 smlal r0, r1, r0, r0
+0+8fe <[^>]+> fbe0 0100 umlal r0, r1, r0, r0
+0+902 <[^>]+> fb80 9000 smull r9, r0, r0, r0
+0+906 <[^>]+> fb80 0900 smull r0, r9, r0, r0
+0+90a <[^>]+> fb89 0100 smull r0, r1, r9, r0
+0+90e <[^>]+> fb80 0109 smull r0, r1, r0, r9
+0+912 <[^>]+> 4240 negs r0, r0
+0+914 <[^>]+> 4268 negs r0, r5
+0+916 <[^>]+> 4245 negs r5, r0
+0+918 <[^>]+> f1d0 0000 rsbs r0, r0, #0 ; 0x0
+0+91c <[^>]+> f1d0 0500 rsbs r5, r0, #0 ; 0x0
+0+920 <[^>]+> f1d5 0000 rsbs r0, r5, #0 ; 0x0
+0+924 <[^>]+> f1c9 0000 rsb r0, r9, #0 ; 0x0
+0+928 <[^>]+> f1c0 0900 rsb r9, r0, #0 ; 0x0
+0+92c <[^>]+> f1d9 0000 rsbs r0, r9, #0 ; 0x0
+0+930 <[^>]+> f1d0 0900 rsbs r9, r0, #0 ; 0x0
+0+934 <[^>]+> eac0 0000 pkhbt r0, r0, r0
+0+938 <[^>]+> eac0 0900 pkhbt r9, r0, r0
+0+93c <[^>]+> eac9 0000 pkhbt r0, r9, r0
+0+940 <[^>]+> eac0 0009 pkhbt r0, r0, r9
+0+944 <[^>]+> eac0 5000 pkhbt r0, r0, r0, lsl #20
+0+948 <[^>]+> eac0 00c0 pkhbt r0, r0, r0, lsl #3
+0+94c <[^>]+> eac2 0103 pkhbt r1, r2, r3
+0+950 <[^>]+> eac2 4163 pkhtb r1, r2, r3, asr #17
+0+954 <[^>]+> b401 push \{r0\}
+0+956 <[^>]+> bc01 pop \{r0\}
+0+958 <[^>]+> b502 push \{r1, lr\}
+0+95a <[^>]+> bd02 pop \{r1, pc\}
+0+95c <[^>]+> e8bd 1f00 ldmia\.w sp!, \{r8, r9, sl, fp, ip\}
+0+960 <[^>]+> e8ad 1f00 stmia\.w sp!, \{r8, r9, sl, fp, ip\}
+0+964 <[^>]+> fa92 f113 qadd16 r1, r2, r3
+0+968 <[^>]+> fa82 f113 qadd8 r1, r2, r3
+0+96c <[^>]+> faa2 f113 qaddsubx r1, r2, r3
+0+970 <[^>]+> fad2 f113 qsub16 r1, r2, r3
+0+974 <[^>]+> fac2 f113 qsub8 r1, r2, r3
+0+978 <[^>]+> fae2 f113 qsubaddx r1, r2, r3
+0+97c <[^>]+> fa92 f103 sadd16 r1, r2, r3
+0+980 <[^>]+> fa82 f103 sadd8 r1, r2, r3
+0+984 <[^>]+> faa2 f103 saddsubx r1, r2, r3
+0+988 <[^>]+> fad2 f103 ssub16 r1, r2, r3
+0+98c <[^>]+> fac2 f103 ssub8 r1, r2, r3
+0+990 <[^>]+> fae2 f103 ssubaddx r1, r2, r3
+0+994 <[^>]+> fa92 f123 shadd16 r1, r2, r3
+0+998 <[^>]+> fa82 f123 shadd8 r1, r2, r3
+0+99c <[^>]+> faa2 f123 shaddsubx r1, r2, r3
+0+9a0 <[^>]+> fad2 f123 shsub16 r1, r2, r3
+0+9a4 <[^>]+> fac2 f123 shsub8 r1, r2, r3
+0+9a8 <[^>]+> fae2 f123 shsubaddx r1, r2, r3
+0+9ac <[^>]+> fa92 f143 uadd16 r1, r2, r3
+0+9b0 <[^>]+> fa82 f143 uadd8 r1, r2, r3
+0+9b4 <[^>]+> faa2 f143 uaddsubx r1, r2, r3
+0+9b8 <[^>]+> fad2 f143 usub16 r1, r2, r3
+0+9bc <[^>]+> fac2 f143 usub8 r1, r2, r3
+0+9c0 <[^>]+> fae2 f143 usubaddx r1, r2, r3
+0+9c4 <[^>]+> fa92 f163 uhadd16 r1, r2, r3
+0+9c8 <[^>]+> fa82 f163 uhadd8 r1, r2, r3
+0+9cc <[^>]+> faa2 f163 uhaddsubx r1, r2, r3
+0+9d0 <[^>]+> fad2 f163 uhsub16 r1, r2, r3
+0+9d4 <[^>]+> fac2 f163 uhsub8 r1, r2, r3
+0+9d8 <[^>]+> fae2 f163 uhsubaddx r1, r2, r3
+0+9dc <[^>]+> fa92 f153 uqadd16 r1, r2, r3
+0+9e0 <[^>]+> fa82 f153 uqadd8 r1, r2, r3
+0+9e4 <[^>]+> faa2 f153 uqaddsubx r1, r2, r3
+0+9e8 <[^>]+> fad2 f153 uqsub16 r1, r2, r3
+0+9ec <[^>]+> fac2 f153 uqsub8 r1, r2, r3
+0+9f0 <[^>]+> fae2 f153 uqsubaddx r1, r2, r3
+0+9f4 <[^>]+> faa2 f183 sel r1, r2, r3
+0+9f8 <[^>]+> ba00 rev r0, r0
+0+9fa <[^>]+> fa90 f080 rev\.w r0, r0
+0+9fe <[^>]+> ba28 rev r0, r5
+0+a00 <[^>]+> ba05 rev r5, r0
+0+a02 <[^>]+> fa99 f089 rev\.w r0, r9
+0+a06 <[^>]+> fa90 f980 rev\.w r9, r0
+0+a0a <[^>]+> ba40 rev16 r0, r0
+0+a0c <[^>]+> fa90 f090 rev16\.w r0, r0
+0+a10 <[^>]+> ba68 rev16 r0, r5
+0+a12 <[^>]+> ba45 rev16 r5, r0
+0+a14 <[^>]+> fa99 f099 rev16\.w r0, r9
+0+a18 <[^>]+> fa90 f990 rev16\.w r9, r0
+0+a1c <[^>]+> bac0 revsh r0, r0
+0+a1e <[^>]+> fa90 f0b0 revsh\.w r0, r0
+0+a22 <[^>]+> bae8 revsh r0, r5
+0+a24 <[^>]+> bac5 revsh r5, r0
+0+a26 <[^>]+> fa99 f0b9 revsh\.w r0, r9
+0+a2a <[^>]+> fa90 f9b0 revsh\.w r9, r0
+0+a2e <[^>]+> fa90 f0a0 rbit r0, r0
+0+a32 <[^>]+> fa90 f0a0 rbit r0, r0
+0+a36 <[^>]+> fa95 f0a0 rbit r0, r5
+0+a3a <[^>]+> fa90 f5a0 rbit r5, r0
+0+a3e <[^>]+> fa99 f0a0 rbit r0, r9
+0+a42 <[^>]+> fa90 f9a0 rbit r9, r0
+0+a46 <[^>]+> 0440 lsls r0, r0, #17
+0+a48 <[^>]+> 0380 lsls r0, r0, #14
+0+a4a <[^>]+> 0445 lsls r5, r0, #17
+0+a4c <[^>]+> 03a8 lsls r0, r5, #14
+0+a4e <[^>]+> 4080 lsls r0, r0
+0+a50 <[^>]+> 40a8 lsls r0, r5
+0+a52 <[^>]+> 40a8 lsls r0, r5
+0+a54 <[^>]+> ea4f 4949 mov\.w r9, r9, lsl #17
+0+a58 <[^>]+> ea4f 3989 mov\.w r9, r9, lsl #14
+0+a5c <[^>]+> ea5f 4049 movs\.w r0, r9, lsl #17
+0+a60 <[^>]+> ea4f 3980 mov\.w r9, r0, lsl #14
+0+a64 <[^>]+> fa00 f000 lsl\.w r0, r0, r0
+0+a68 <[^>]+> fa09 f909 lsl\.w r9, r9, r9
+0+a6c <[^>]+> fa19 f900 lsls\.w r9, r9, r0
+0+a70 <[^>]+> fa00 f009 lsl\.w r0, r0, r9
+0+a74 <[^>]+> fa00 f005 lsl\.w r0, r0, r5
+0+a78 <[^>]+> fa11 f002 lsls\.w r0, r1, r2
+0+a7c <[^>]+> 0c40 lsrs r0, r0, #17
+0+a7e <[^>]+> 0b80 lsrs r0, r0, #14
+0+a80 <[^>]+> 0c45 lsrs r5, r0, #17
+0+a82 <[^>]+> 0ba8 lsrs r0, r5, #14
+0+a84 <[^>]+> 40c0 lsrs r0, r0
+0+a86 <[^>]+> 40e8 lsrs r0, r5
+0+a88 <[^>]+> 40e8 lsrs r0, r5
+0+a8a <[^>]+> ea4f 4959 mov\.w r9, r9, lsr #17
+0+a8e <[^>]+> ea4f 3999 mov\.w r9, r9, lsr #14
+0+a92 <[^>]+> ea5f 4059 movs\.w r0, r9, lsr #17
+0+a96 <[^>]+> ea4f 3990 mov\.w r9, r0, lsr #14
+0+a9a <[^>]+> fa20 f000 lsr\.w r0, r0, r0
+0+a9e <[^>]+> fa29 f909 lsr\.w r9, r9, r9
+0+aa2 <[^>]+> fa39 f900 lsrs\.w r9, r9, r0
+0+aa6 <[^>]+> fa20 f009 lsr\.w r0, r0, r9
+0+aaa <[^>]+> fa20 f005 lsr\.w r0, r0, r5
+0+aae <[^>]+> fa31 f002 lsrs\.w r0, r1, r2
+0+ab2 <[^>]+> 1440 asrs r0, r0, #17
+0+ab4 <[^>]+> 1380 asrs r0, r0, #14
+0+ab6 <[^>]+> 1445 asrs r5, r0, #17
+0+ab8 <[^>]+> 13a8 asrs r0, r5, #14
+0+aba <[^>]+> 4100 asrs r0, r0
+0+abc <[^>]+> 4128 asrs r0, r5
+0+abe <[^>]+> 4128 asrs r0, r5
+0+ac0 <[^>]+> ea4f 4969 mov\.w r9, r9, asr #17
+0+ac4 <[^>]+> ea4f 39a9 mov\.w r9, r9, asr #14
+0+ac8 <[^>]+> ea5f 4069 movs\.w r0, r9, asr #17
+0+acc <[^>]+> ea4f 39a0 mov\.w r9, r0, asr #14
+0+ad0 <[^>]+> fa40 f000 asr\.w r0, r0, r0
+0+ad4 <[^>]+> fa49 f909 asr\.w r9, r9, r9
+0+ad8 <[^>]+> fa59 f900 asrs\.w r9, r9, r0
+0+adc <[^>]+> fa40 f009 asr\.w r0, r0, r9
+0+ae0 <[^>]+> fa40 f005 asr\.w r0, r0, r5
+0+ae4 <[^>]+> fa51 f002 asrs\.w r0, r1, r2
+0+ae8 <[^>]+> ea5f 4070 movs\.w r0, r0, ror #17
+0+aec <[^>]+> ea5f 30b0 movs\.w r0, r0, ror #14
+0+af0 <[^>]+> ea5f 4570 movs\.w r5, r0, ror #17
+0+af4 <[^>]+> ea5f 30b5 movs\.w r0, r5, ror #14
+0+af8 <[^>]+> 41c0 rors r0, r0
+0+afa <[^>]+> 41e8 rors r0, r5
+0+afc <[^>]+> 41e8 rors r0, r5
+0+afe <[^>]+> ea4f 4979 mov\.w r9, r9, ror #17
+0+b02 <[^>]+> ea4f 39b9 mov\.w r9, r9, ror #14
+0+b06 <[^>]+> ea5f 4079 movs\.w r0, r9, ror #17
+0+b0a <[^>]+> ea4f 39b0 mov\.w r9, r0, ror #14
+0+b0e <[^>]+> fa60 f000 ror\.w r0, r0, r0
+0+b12 <[^>]+> fa69 f909 ror\.w r9, r9, r9
+0+b16 <[^>]+> fa79 f900 rors\.w r9, r9, r0
+0+b1a <[^>]+> fa60 f009 ror\.w r0, r0, r9
+0+b1e <[^>]+> fa60 f005 ror\.w r0, r0, r5
+0+b22 <[^>]+> fa71 f002 rors\.w r0, r1, r2
+0+b26 <[^>]+> f7f0 8000 smi #0 ; 0x0
+0+b2a <[^>]+> f7fd 8bca smi #43981 ; 0xabcd
+0+b2e <[^>]+> fb10 0000 smlabb r0, r0, r0, r0
+0+b32 <[^>]+> fb10 0900 smlabb r9, r0, r0, r0
+0+b36 <[^>]+> fb19 0000 smlabb r0, r9, r0, r0
+0+b3a <[^>]+> fb10 0009 smlabb r0, r0, r9, r0
+0+b3e <[^>]+> fb10 9000 smlabb r0, r0, r0, r9
+0+b42 <[^>]+> fb10 0020 smlatb r0, r0, r0, r0
+0+b46 <[^>]+> fb10 0010 smlabt r0, r0, r0, r0
+0+b4a <[^>]+> fb10 0030 smlatt r0, r0, r0, r0
+0+b4e <[^>]+> fb30 0000 smlawb r0, r0, r0, r0
+0+b52 <[^>]+> fb30 0010 smlawt r0, r0, r0, r0
+0+b56 <[^>]+> fb20 0000 smlad r0, r0, r0, r0
+0+b5a <[^>]+> fb20 0010 smladx r0, r0, r0, r0
+0+b5e <[^>]+> fb40 0000 smlsd r0, r0, r0, r0
+0+b62 <[^>]+> fb40 0010 smlsdx r0, r0, r0, r0
+0+b66 <[^>]+> fb50 0000 smmla r0, r0, r0, r0
+0+b6a <[^>]+> fb50 0010 smmlar r0, r0, r0, r0
+0+b6e <[^>]+> fb60 0000 smmls r0, r0, r0, r0
+0+b72 <[^>]+> fb60 0010 smmlsr r0, r0, r0, r0
+0+b76 <[^>]+> fb70 0000 usada8 r0, r0, r0, r0
+0+b7a <[^>]+> fbc0 0080 smlalbb r0, r0, r0, r0
+0+b7e <[^>]+> fbc0 9080 smlalbb r9, r0, r0, r0
+0+b82 <[^>]+> fbc0 0980 smlalbb r0, r9, r0, r0
+0+b86 <[^>]+> fbc9 0080 smlalbb r0, r0, r9, r0
+0+b8a <[^>]+> fbc0 0089 smlalbb r0, r0, r0, r9
+0+b8e <[^>]+> fbc0 00a0 smlaltb r0, r0, r0, r0
+0+b92 <[^>]+> fbc0 0090 smlalbt r0, r0, r0, r0
+0+b96 <[^>]+> fbc0 00b0 smlaltt r0, r0, r0, r0
+0+b9a <[^>]+> fbc0 00c0 smlald r0, r0, r0, r0
+0+b9e <[^>]+> fbc0 00d0 smlaldx r0, r0, r0, r0
+0+ba2 <[^>]+> fbd0 00c0 smlsld r0, r0, r0, r0
+0+ba6 <[^>]+> fbd0 00d0 smlsldx r0, r0, r0, r0
+0+baa <[^>]+> fbe0 0060 umaal r0, r0, r0, r0
+0+bae <[^>]+> fb10 f000 smulbb r0, r0, r0
+0+bb2 <[^>]+> fb10 f900 smulbb r9, r0, r0
+0+bb6 <[^>]+> fb19 f000 smulbb r0, r9, r0
+0+bba <[^>]+> fb10 f009 smulbb r0, r0, r9
+0+bbe <[^>]+> fb10 f020 smultb r0, r0, r0
+0+bc2 <[^>]+> fb10 f010 smulbt r0, r0, r0
+0+bc6 <[^>]+> fb10 f030 smultt r0, r0, r0
+0+bca <[^>]+> fb30 f000 smulwb r0, r0, r0
+0+bce <[^>]+> fb30 f010 smulwt r0, r0, r0
+0+bd2 <[^>]+> fb50 f000 smmul r0, r0, r0
+0+bd6 <[^>]+> fb50 f010 smmulr r0, r0, r0
+0+bda <[^>]+> fb20 f000 smuad r0, r0, r0
+0+bde <[^>]+> fb20 f010 smuadx r0, r0, r0
+0+be2 <[^>]+> fb40 f000 smusd r0, r0, r0
+0+be6 <[^>]+> fb40 f010 smusdx r0, r0, r0
+0+bea <[^>]+> fb70 f000 usad8 r0, r0, r0
+0+bee <[^>]+> f300 0000 ssat r0, #0, r0
+0+bf2 <[^>]+> f300 0000 ssat r0, #0, r0
+0+bf6 <[^>]+> f300 0000 ssat r0, #0, r0
+0+bfa <[^>]+> f300 0900 ssat r9, #0, r0
+0+bfe <[^>]+> f300 0011 ssat r0, #17, r0
+0+c02 <[^>]+> f309 0000 ssat r0, #0, r9
+0+c06 <[^>]+> f300 7000 ssat r0, #0, r0, lsl #28
+0+c0a <[^>]+> f320 00c0 ssat r0, #0, r0, asr #3
+0+c0e <[^>]+> f320 0000 ssat16 r0, #0, r0
+0+c12 <[^>]+> f320 0900 ssat16 r9, #0, r0
+0+c16 <[^>]+> f320 0009 ssat16 r0, #9, r0
+0+c1a <[^>]+> f329 0000 ssat16 r0, #0, r9
+0+c1e <[^>]+> f380 0000 usat r0, #0, r0
+0+c22 <[^>]+> f380 0000 usat r0, #0, r0
+0+c26 <[^>]+> f380 0000 usat r0, #0, r0
+0+c2a <[^>]+> f380 0900 usat r9, #0, r0
+0+c2e <[^>]+> f380 0011 usat r0, #17, r0
+0+c32 <[^>]+> f389 0000 usat r0, #0, r9
+0+c36 <[^>]+> f380 7000 usat r0, #0, r0, lsl #28
+0+c3a <[^>]+> f3a0 00c0 usat r0, #0, r0, asr #3
+0+c3e <[^>]+> f3a0 0000 usat16 r0, #0, r0
+0+c42 <[^>]+> f3a0 0900 usat16 r9, #0, r0
+0+c46 <[^>]+> f3a0 0009 usat16 r0, #9, r0
+0+c4a <[^>]+> f3a9 0000 usat16 r0, #0, r9
+0+c4e <[^>]+> b240 sxtb r0, r0
+0+c50 <[^>]+> b240 sxtb r0, r0
+0+c52 <[^>]+> b245 sxtb r5, r0
+0+c54 <[^>]+> b268 sxtb r0, r5
+0+c56 <[^>]+> fa4f f182 sxtb\.w r1, r2
+0+c5a <[^>]+> fa4f f192 sxtb\.w r1, r2, ror #8
+0+c5e <[^>]+> fa4f f1a2 sxtb\.w r1, r2, ror #16
+0+c62 <[^>]+> fa4f f1b2 sxtb\.w r1, r2, ror #24
+0+c66 <[^>]+> fa2f f182 sxtb16 r1, r2
+0+c6a <[^>]+> fa2f f889 sxtb16 r8, r9
+0+c6e <[^>]+> b211 sxth r1, r2
+0+c70 <[^>]+> fa0f f889 sxth\.w r8, r9
+0+c74 <[^>]+> b2d1 uxtb r1, r2
+0+c76 <[^>]+> fa5f f889 uxtb\.w r8, r9
+0+c7a <[^>]+> fa3f f182 uxtb16 r1, r2
+0+c7e <[^>]+> fa3f f889 uxtb16 r8, r9
+0+c82 <[^>]+> b291 uxth r1, r2
+0+c84 <[^>]+> fa1f f889 uxth\.w r8, r9
+0+c88 <[^>]+> fa40 f080 sxtab r0, r0, r0
+0+c8c <[^>]+> fa40 f080 sxtab r0, r0, r0
+0+c90 <[^>]+> fa40 f990 sxtab r9, r0, r0, ror #8
+0+c94 <[^>]+> fa49 f0a0 sxtab r0, r9, r0, ror #16
+0+c98 <[^>]+> fa40 f0b9 sxtab r0, r0, r9, ror #24
+0+c9c <[^>]+> fa22 f183 sxtab16 r1, r2, r3
+0+ca0 <[^>]+> fa02 f183 sxtah r1, r2, r3
+0+ca4 <[^>]+> fa52 f183 uxtab r1, r2, r3
+0+ca8 <[^>]+> fa32 f183 uxtab16 r1, r2, r3
+0+cac <[^>]+> fa12 f183 uxtah r1, r2, r3
===================================================================
Index: gas/testsuite/gas/arm/thumb32.s
--- gas/testsuite/gas/arm/thumb32.s (revision 0)
+++ gas/testsuite/gas/arm/thumb32.s (revision 79)
@@ -0,0 +1,734 @@
+ .text
+ .thumb32
+
+encode_thumb32_immediate:
+ orr r0, r1, #0x00000000
+ orr r0, r1, #0x000000a5
+ orr r0, r1, #0x00a500a5
+ orr r0, r1, #0xa500a500
+ orr r0, r1, #0xa5a5a5a5
+
+ orr r0, r1, #0xa5 << 31
+ orr r0, r1, #0xa5 << 30
+ orr r0, r1, #0xa5 << 29
+ orr r0, r1, #0xa5 << 28
+ orr r0, r1, #0xa5 << 27
+ orr r0, r1, #0xa5 << 26
+ orr r0, r1, #0xa5 << 25
+ orr r0, r1, #0xa5 << 24
+ orr r0, r1, #0xa5 << 23
+ orr r0, r1, #0xa5 << 22
+ orr r0, r1, #0xa5 << 21
+ orr r0, r1, #0xa5 << 20
+ orr r0, r1, #0xa5 << 19
+ orr r0, r1, #0xa5 << 18
+ orr r0, r1, #0xa5 << 17
+ orr r0, r1, #0xa5 << 16
+ orr r0, r1, #0xa5 << 15
+ orr r0, r1, #0xa5 << 14
+ orr r0, r1, #0xa5 << 13
+ orr r0, r1, #0xa5 << 12
+ orr r0, r1, #0xa5 << 11
+ orr r0, r1, #0xa5 << 10
+ orr r0, r1, #0xa5 << 9
+ orr r0, r1, #0xa5 << 8
+ orr r0, r1, #0xa5 << 7
+ orr r0, r1, #0xa5 << 6
+ orr r0, r1, #0xa5 << 5
+ orr r0, r1, #0xa5 << 4
+ orr r0, r1, #0xa5 << 3
+ orr r0, r1, #0xa5 << 2
+ orr r0, r1, #0xa5 << 1
+
+add_sub:
+ adds r0, r0, #0 @ format 1
+ adds r5, r0, #0
+ adds r0, r5, #0
+ adds r0, r0, #5
+
+ adds r0, #129 @ format 2
+ adds r0, r0, #129
+ adds r5, #126
+
+ adds r0, r0, r0 @ format 3
+ adds r5, r0, r0
+ adds r0, r5, r0
+ adds r0, r0, r5
+ adds r1, r2, r3
+
+ add r8, r0 @ format 4
+ add r0, r8
+ add r0, r8, r0
+ add r0, r0, r8
+ add r8, r0, r0 @ ... not this one
+
+ add r1, r0
+ add r0, r1
+
+ add r0, pc, #0 @ format 5
+ add r5, pc, #0
+ add r0, pc, #516
+
+ add r0, sp, #0 @ format 6
+ add r5, sp, #0
+ add r0, sp, #516
+
+ add sp, #0 @ format 7
+ add sp, sp, #0
+ add sp, #260
+
+ add.w r0, r0, #0 @ T32 format 1
+ adds.w r0, r0, #0
+ add.w r9, r0, #0
+ add.w r0, r9, #0
+ add.w r0, r0, #129
+
+ add.w r0, r0, r0 @ T32 format 2
+ adds.w r0, r0, r0
+ add.w r9, r0, r0
+ add.w r0, r9, r0
+ add.w r0, r0, r9
+
+ add.w r8, r9, r10
+ add.w r8, r9, r10, lsl #17
+ add.w r8, r8, r10, lsr #32
+ add.w r8, r8, r10, lsr #17
+ add.w r8, r9, r10, asr #32
+ add.w r8, r9, r10, asr #17
+ add.w r8, r9, r10, rrx
+ add.w r8, r9, r10, ror #17
+
+ subs r0, r0, #0 @ format 1
+ subs r5, r0, #0
+ subs r0, r5, #0
+ subs r0, r0, #5
+
+ subs r0, r0, #129
+ subs r5, #8
+
+ subs r0, r0, r0 @ format 3
+ subs r5, r0, r0
+ subs r0, r5, r0
+ subs r0, r0, r5
+
+ sub sp, #260 @ format 4
+ sub sp, sp, #260
+
+ subs r8, r0 @ T32 format 2
+ subs r0, r8
+ subs r0, #260 @ T32 format 1
+
+arit3:
+ .macro arit3 op ops opw opsw
+ \ops r0, r0
+ \ops r5, r0
+ \ops r0, r5
+ \ops r0, r0, r5
+ \ops r0, r5, r0
+ \op r0, r5, r0
+ \op r0, r1, r2
+ \op r9, r0, r0
+ \op r0, r9, r0
+ \op r0, r0, r9
+ \opsw r0, r0, r0
+ \opw r0, r1, r2, asr #17
+ \opw r0, r1, #129
+ .endm
+
+ arit3 adc adcs adc.w adcs.w
+ arit3 and ands and.w ands.w
+ arit3 bic bics bic.w bics.w
+ arit3 eor eors eor.w eors.w
+ arit3 orr orrs orr.w orrs.w
+ arit3 rsb rsbs rsb.w rsbs.w
+ arit3 sbc sbcs sbc.w sbcs.w
+
+ .purgem arit3
+
+bfc_bfi_bfx:
+ bfc r0, #0, #1
+ bfc r9, #0, #1
+ bfi r9, #0, #0, #1
+ bfc r0, #21, #1
+ bfc r0, #0, #18
+
+ bfi r0, r0, #0, #1
+ bfi r9, r0, #0, #1
+ bfi r0, r9, #0, #1
+ bfi r0, r0, #21, #1
+ bfi r0, r0, #0, #18
+
+ sbfx r0, r0, #0, #1
+ ubfx r9, r0, #0, #1
+ sbfx r0, r9, #0, #1
+ ubfx r0, r0, #21, #1
+ sbfx r0, r0, #0, #18
+
+ .globl branches
+branches:
+ .macro bra op
+ \op 1b
+ \op 1f
+ .endm
+1:
+ bra beq.n
+ bra bne.n
+ bra bcs.n
+ bra bhs.n
+ bra bcc.n
+ bra bul.n
+ bra blo.n
+ bra bmi.n
+ bra bpl.n
+ bra bvs.n
+ bra bvc.n
+ bra bhi.n
+ bra bls.n
+ bra bvc.n
+ bra bhi.n
+ bra bls.n
+ bra bge.n
+ bra blt.n
+ bra bgt.n
+ bra ble.n
+ bra bal.n
+ bra b.n
+ @ bl, blx have no short form.
+1:
+ bra beq
+ bra bne
+ bra bcs
+ bra bhs
+ bra bcc
+ bra bul
+ bra blo
+ bra bmi
+ bra bpl
+ bra bvs
+ bra bvc
+ bra bhi
+ bra bls
+ bra bvc
+ bra bhi
+ bra bls
+ bra bge
+ bra blt
+ bra bgt
+ bra ble
+ bra b
+ bra bl
+ bra blx
+1:
+
+ bx r0
+ bx r9
+ blx r0
+ blx r9
+ bxj r0
+ bxj r9
+ .purgem bra
+
+clz:
+ clz r0, r0
+ clz r9, r0
+ clz r0, r9
+
+cps:
+ cpsie f
+ cpsid i
+ cpsie a
+ cpsid.w f
+ cpsie.w i
+ cpsid.w a
+ cpsie i, #0
+ cpsid i, #17
+ cps #0
+ cps #17
+
+cpy:
+ cpy r0, r0
+ cpy r9, r0
+ cpy r0, r9
+ cpy.w r0, r0
+ cpy.w r9, r0
+ cpy.w r0, r9
+
+czb:
+ czbne r0, 2f
+ czbeq r5, 1f
+
+nop_hint:
+ nop
+1: yield
+2: wfe
+ wfi
+ sev
+
+ nop.w
+ yield.w
+ wfe.w
+ wfi.w
+ sev.w
+
+ nop {9}
+ nop {129}
+
+it:
+ .macro itx opc cond n
+ \opc \cond
+ .rept \n
+ nop
+ .endr
+ .endm
+
+ itx it eq 1
+ itx it ne 1
+ itx it cs 1
+ itx it hs 1
+ itx it cc 1
+ itx it ul 1
+ itx it lo 1
+ itx it mi 1
+ itx it pl 1
+ itx it vs 1
+ itx it vc 1
+ itx it hi 1
+ itx it ge 1
+ itx it lt 1
+ itx it gt 1
+ itx it le 1
+ itx it al 1
+
+ itx itt eq 2
+ itx ite eq 2
+ itx ittt eq 3
+ itx itet eq 3
+ itx itte eq 3
+ itx itee eq 3
+ itx itttt eq 4
+ itx itett eq 4
+ itx ittet eq 4
+ itx ittte eq 4
+ itx ittee eq 4
+ itx itete eq 4
+ itx iteet eq 4
+ itx iteee eq 4
+
+ itx itt ne 2
+ itx ite ne 2
+ itx ittt ne 3
+ itx itet ne 3
+ itx itte ne 3
+ itx itee ne 3
+ itx itttt ne 4
+ itx itett ne 4
+ itx ittet ne 4
+ itx ittte ne 4
+ itx ittee ne 4
+ itx itete ne 4
+ itx iteet ne 4
+ itx iteee ne 4
+
+ .purgem itx
+
+ldst:
+ .macro ls op
+ \op r1, [r5]
+ \op r1, [r5, #0x330]
+ \op r1, [r5, #-0x30]
+ \op r1, [r5], #0x30
+ \op r1, [r5], #-0x30
+ \op r1, [r5, #0x30]!
+ \op r1, [r5, #-0x30]!
+ \op r1, [r5, r4]
+ \op r1, [r9, ip]
+ \op r1, 1f
+ \op r1, 1b
+ .endm
+1:
+ ls ldrb
+ ls ldrsb
+ ls ldrh
+ ls ldrsh
+ ls ldr
+1:
+ ls strb
+ ls strh
+ ls str
+
+ pld [r5]
+ pld [r5, #0x330]
+ pld [r5, #-0x30]
+ pld [r5], #0x30
+ pld [r5], #-0x30
+ pld [r5, #0x30]!
+ pld [r5, #-0x30]!
+ pld [r5, r4]
+ pld [r9, ip]
+ pld 1f
+ pld 1b
+1:
+
+ ldrd r2, r3, [r5]
+ ldrd r2, [r5, #0x30]
+ ldrd r2, [r5, #-0x30]
+ strd r2, r3, [r5]
+ strd r2, [r5, #0x30]
+ strd r2, [r5, #-0x30]
+
+ ldrbt r1, [r5]
+ ldrbt r1, [r5, #0x30]
+ ldrsbt r1, [r5]
+ ldrsbt r1, [r5, #0x30]
+ ldrht r1, [r5]
+ ldrht r1, [r5, #0x30]
+ ldrsht r1, [r5]
+ ldrsht r1, [r5, #0x30]
+ ldrt r1, [r5]
+ ldrt r1, [r5, #0x30]
+
+ .purgem ls
+
+ldxstx:
+ ldrexb r1, [r4]
+ ldrexh r1, [r4]
+ ldrex r1, [r4]
+ ldrexd r1, r2, [r4]
+
+ strexb r1, r2, [r4]
+ strexh r1, r2, [r4]
+ strex r1, r2, [r4]
+ strexd r1, r2, r3, [r4]
+
+ ldrex r1, [r4,#516]
+ strex r1, r2, [r4,#516]
+
+ldmstm:
+ ldmia r0!, {r1,r2,r3}
+ ldmia r2, {r0,r1,r2}
+ ldmia.w r2, {r0,r1,r2}
+ ldmia r9, {r0,r1,r2}
+ ldmia r0, {r7,r8,r10}
+ ldmia r0!, {r7,r8,r10}
+
+ stmia r0!, {r1,r2,r3}
+ stmia r2!, {r0,r1,r3}
+ stmia.w r2!, {r0,r1,r3}
+ stmia r9, {r0,r1,r2}
+ stmia r0, {r7,r8,r10}
+ stmia r0!, {r7,r8,r10}
+
+ ldmdb r0, {r7,r8,r10}
+ stmdb r0, {r7,r8,r10}
+
+mlas:
+ mla r0, r0, r0, r0
+ mls r0, r0, r0, r0
+ mla r9, r0, r0, r0
+ mla r0, r9, r0, r0
+ mla r0, r0, r9, r0
+ mla r0, r0, r0, r9
+
+tst_teq_cmp_cmn_mov_mvn:
+ .macro mt op ops opw opsw
+ \ops r0, r0
+ \op r0, r0
+ \ops r5, r0
+ \op r0, r5
+ \op r0, r5, asr #17
+ \opw r0, r0
+ \ops r9, r0
+ \opsw r0, r9
+ \op r0, #129
+ \op r5, #129
+ .endm
+
+ mt tst tsts tst.w tsts.w
+ mt teq teqs teq.w teqs.w
+ mt cmp cmps cmp.w cmps.w
+ mt cmn cmns cmn.w cmns.w
+ mt mov movs mov.w movs.w
+ mt mvn mvns mvn.w mvns.w
+ .purgem mt
+
+mov16:
+ movw r0, #0
+ movt r0, #0
+ movw r9, #0
+ movw r0, #0x9000
+ movw r0, #0x0800
+ movw r0, #0x0500
+ movw r0, #0x0081
+ movw r0, #0xffff
+
+mrs_msr:
+ mrs r0, CPSR
+ mrs r0, SPSR
+ mrs r9, CPSR_all
+ mrs r9, SPSR_all
+
+ msr CPSR_c, r0
+ msr SPSR_c, r0
+ msr CPSR_c, r9
+ msr CPSR_x, r0
+ msr CPSR_s, r0
+ msr CPSR_f, r0
+
+mul:
+ mul r0, r0, r0
+ mul r0, r9, r0
+ mul r0, r0, r9
+ mul r0, r0
+ mul r9, r0
+ muls r5, r0
+ muls r5, r0, r5
+ muls r0, r5
+
+mull:
+ smull r0, r1, r0, r0
+ umull r0, r1, r0, r0
+ smlal r0, r1, r0, r0
+ umlal r0, r1, r0, r0
+ smull r9, r0, r0, r0
+ smull r0, r9, r0, r0
+ smull r0, r1, r9, r0
+ smull r0, r1, r0, r9
+
+neg:
+ negs r0, r0
+ negs r0, r5
+ negs r5, r0
+ negs.w r0, r0
+ negs.w r5, r0
+ negs.w r0, r5
+
+ neg r0, r9
+ neg r9, r0
+ negs r0, r9
+ negs r9, r0
+
+pkh:
+ pkhbt r0, r0, r0
+ pkhbt r9, r0, r0
+ pkhbt r0, r9, r0
+ pkhbt r0, r0, r9
+ pkhbt r0, r0, r0, lsl #0x14
+ pkhbt r0, r0, r0, lsl #3
+ pkhtb r1, r2, r3
+ pkhtb r1, r2, r3, asr #0x11
+
+push_pop:
+ push {r0}
+ pop {r0}
+ push {r1,lr}
+ pop {r1,pc}
+ push {r8,r9,r10,r11,r12}
+ pop {r8,r9,r10,r11,r12}
+
+qadd:
+ qadd16 r1, r2, r3
+ qadd8 r1, r2, r3
+ qaddsubx r1, r2, r3
+ qsub16 r1, r2, r3
+ qsub8 r1, r2, r3
+ qsubaddx r1, r2, r3
+ sadd16 r1, r2, r3
+ sadd8 r1, r2, r3
+ saddsubx r1, r2, r3
+ ssub16 r1, r2, r3
+ ssub8 r1, r2, r3
+ ssubaddx r1, r2, r3
+ shadd16 r1, r2, r3
+ shadd8 r1, r2, r3
+ shaddsubx r1, r2, r3
+ shsub16 r1, r2, r3
+ shsub8 r1, r2, r3
+ shsubaddx r1, r2, r3
+ uadd16 r1, r2, r3
+ uadd8 r1, r2, r3
+ uaddsubx r1, r2, r3
+ usub16 r1, r2, r3
+ usub8 r1, r2, r3
+ usubaddx r1, r2, r3
+ uhadd16 r1, r2, r3
+ uhadd8 r1, r2, r3
+ uhaddsubx r1, r2, r3
+ uhsub16 r1, r2, r3
+ uhsub8 r1, r2, r3
+ uhsubaddx r1, r2, r3
+ uqadd16 r1, r2, r3
+ uqadd8 r1, r2, r3
+ uqaddsubx r1, r2, r3
+ uqsub16 r1, r2, r3
+ uqsub8 r1, r2, r3
+ uqsubaddx r1, r2, r3
+ sel r1, r2, r3
+
+rbit_rev:
+ .macro rx op opw
+ \op r0, r0
+ \opw r0, r0
+ \op r0, r5
+ \op r5, r0
+ \op r0, r9
+ \op r9, r0
+ .endm
+
+ rx rev rev.w
+ rx rev16 rev16.w
+ rx revsh revsh.w
+ rx rbit rbit.w
+
+ .purgem rx
+
+shift:
+ .macro sh op ops opw opsw
+ \ops r0, #17 @ 16-bit format 1
+ \ops r0, r0, #14
+ \ops r5, r0, #17
+ \ops r0, r5, #14
+ \ops r0, r0 @ 16-bit format 2
+ \ops r0, r5
+ \ops r0, r0, r5
+ \op r9, #17 @ 32-bit format 1
+ \op r9, r9, #14
+ \ops r0, r9, #17
+ \op r9, r0, #14
+ \opw r0, r0, r0 @ 32-bit format 2
+ \op r9, r9
+ \ops r9, r0
+ \op r0, r9
+ \op r0, r5
+ \ops r0, r1, r2
+ .endm
+
+ sh lsl lsls lsl.w lsls.w
+ sh lsr lsrs lsr.w lsrs.w
+ sh asr asrs asr.w asrs.w
+ sh ror rors ror.w rors.w
+
+ .purgem sh
+
+smi:
+ smi #0
+ smi #0xabcd
+
+smla:
+ smlabb r0, r0, r0, r0
+ smlabb r9, r0, r0, r0
+ smlabb r0, r9, r0, r0
+ smlabb r0, r0, r9, r0
+ smlabb r0, r0, r0, r9
+
+ smlatb r0, r0, r0, r0
+ smlabt r0, r0, r0, r0
+ smlatt r0, r0, r0, r0
+ smlawb r0, r0, r0, r0
+ smlawt r0, r0, r0, r0
+ smlad r0, r0, r0, r0
+ smladx r0, r0, r0, r0
+ smlsd r0, r0, r0, r0
+ smlsdx r0, r0, r0, r0
+ smmla r0, r0, r0, r0
+ smmlar r0, r0, r0, r0
+ smmls r0, r0, r0, r0
+ smmlsr r0, r0, r0, r0
+ usada8 r0, r0, r0, r0
+
+smlal:
+ smlalbb r0, r0, r0, r0
+ smlalbb r9, r0, r0, r0
+ smlalbb r0, r9, r0, r0
+ smlalbb r0, r0, r9, r0
+ smlalbb r0, r0, r0, r9
+
+ smlaltb r0, r0, r0, r0
+ smlalbt r0, r0, r0, r0
+ smlaltt r0, r0, r0, r0
+ smlald r0, r0, r0, r0
+ smlaldx r0, r0, r0, r0
+ smlsld r0, r0, r0, r0
+ smlsldx r0, r0, r0, r0
+ umaal r0, r0, r0, r0
+
+smul:
+ smulbb r0, r0, r0
+ smulbb r9, r0, r0
+ smulbb r0, r9, r0
+ smulbb r0, r0, r9
+
+ smultb r0, r0, r0
+ smulbt r0, r0, r0
+ smultt r0, r0, r0
+ smulwb r0, r0, r0
+ smulwt r0, r0, r0
+ smmul r0, r0, r0
+ smmulr r0, r0, r0
+ smuad r0, r0, r0
+ smuadx r0, r0, r0
+ smusd r0, r0, r0
+ smusdx r0, r0, r0
+ usad8 r0, r0, r0
+
+sat:
+ ssat r0, #1, r0
+ ssat r0, #1, r0, lsl #0
+ ssat r0, #1, r0, asr #0
+ ssat r9, #1, r0
+ ssat r0, #18, r0
+ ssat r0, #1, r9
+ ssat r0, #1, r0, lsl #0x1c
+ ssat r0, #1, r0, asr #0x03
+
+ ssat16 r0, #1, r0
+ ssat16 r9, #1, r0
+ ssat16 r0, #10, r0
+ ssat16 r0, #1, r9
+
+ usat r0, #0, r0
+ usat r0, #0, r0, lsl #0
+ usat r0, #0, r0, asr #0
+ usat r9, #0, r0
+ usat r0, #17, r0
+ usat r0, #0, r9
+ usat r0, #0, r0, lsl #0x1c
+ usat r0, #0, r0, asr #0x03
+
+ usat16 r0, #0, r0
+ usat16 r9, #0, r0
+ usat16 r0, #9, r0
+ usat16 r0, #0, r9
+
+xt:
+ sxtb r0, r0
+ sxtb r0, r0, ror #0
+ sxtb r5, r0
+ sxtb r0, r5
+ sxtb.w r1, r2
+ sxtb r1, r2, ror #8
+ sxtb r1, r2, ror #16
+ sxtb r1, r2, ror #24
+
+ sxtb16 r1, r2
+ sxtb16 r8, r9
+ sxth r1, r2
+ sxth r8, r9
+ uxtb r1, r2
+ uxtb r8, r9
+ uxtb16 r1, r2
+ uxtb16 r8, r9
+ uxth r1, r2
+ uxth r8, r9
+
+xta:
+ sxtab r0, r0, r0
+ sxtab r0, r0, r0, ror #0
+ sxtab r9, r0, r0, ror #8
+ sxtab r0, r9, r0, ror #16
+ sxtab r0, r0, r9, ror #24
+
+ sxtab16 r1, r2, r3
+ sxtah r1, r2, r3
+ uxtab r1, r2, r3
+ uxtab16 r1, r2, r3
+ uxtah r1, r2, r3
===================================================================
Index: gas/testsuite/gas/arm/t16-bad.l
--- gas/testsuite/gas/arm/t16-bad.l (revision 78)
+++ gas/testsuite/gas/arm/t16-bad.l (revision 79)
@@ -24,19 +24,23 @@
[^:]*:42: Error: lo register required -- `revsh r0,r8'
[^:]*:43: Error: lo register required -- `sxtb r8,r0'
[^:]*:43: Error: lo register required -- `sxtb r0,r8'
+[^:]*:43: Error: Thumb encoding does not support rotation -- `sxtb r0,r1,ror#8'
[^:]*:44: Error: lo register required -- `sxth r8,r0'
[^:]*:44: Error: lo register required -- `sxth r0,r8'
+[^:]*:44: Error: Thumb encoding does not support rotation -- `sxth r0,r1,ror#8'
[^:]*:45: Error: lo register required -- `uxtb r8,r0'
[^:]*:45: Error: lo register required -- `uxtb r0,r8'
+[^:]*:45: Error: Thumb encoding does not support rotation -- `uxtb r0,r1,ror#8'
[^:]*:46: Error: lo register required -- `uxth r8,r0'
[^:]*:46: Error: lo register required -- `uxth r0,r8'
-[^:]*:48: Error: dest and source1 must be the same register -- `adc r1,r2,r3'
+[^:]*:46: Error: Thumb encoding does not support rotation -- `uxth r0,r1,ror#8'
+[^:]*:48: Error: dest must overlap one source register -- `adc r1,r2,r3'
[^:]*:48: Error: lo register required -- `adc r8,r0'
[^:]*:48: Error: lo register required -- `adc r0,r8'
[^:]*:48: Error: unshifted register required -- `adc r0,#12'
[^:]*:48: Error: unshifted register required -- `adc r0,r1,lsl#2'
[^:]*:48: Error: unshifted register required -- `adc r0,r1,lsl r3'
-[^:]*:49: Error: dest and source1 must be the same register -- `and r1,r2,r3'
+[^:]*:49: Error: dest must overlap one source register -- `and r1,r2,r3'
[^:]*:49: Error: lo register required -- `and r8,r0'
[^:]*:49: Error: lo register required -- `and r0,r8'
[^:]*:49: Error: unshifted register required -- `and r0,#12'
@@ -48,13 +52,13 @@
[^:]*:50: Error: unshifted register required -- `bic r0,#12'
[^:]*:50: Error: unshifted register required -- `bic r0,r1,lsl#2'
[^:]*:50: Error: unshifted register required -- `bic r0,r1,lsl r3'
-[^:]*:51: Error: dest and source1 must be the same register -- `eor r1,r2,r3'
+[^:]*:51: Error: dest must overlap one source register -- `eor r1,r2,r3'
[^:]*:51: Error: lo register required -- `eor r8,r0'
[^:]*:51: Error: lo register required -- `eor r0,r8'
[^:]*:51: Error: unshifted register required -- `eor r0,#12'
[^:]*:51: Error: unshifted register required -- `eor r0,r1,lsl#2'
[^:]*:51: Error: unshifted register required -- `eor r0,r1,lsl r3'
-[^:]*:52: Error: dest and source1 must be the same register -- `orr r1,r2,r3'
+[^:]*:52: Error: dest must overlap one source register -- `orr r1,r2,r3'
[^:]*:52: Error: lo register required -- `orr r8,r0'
[^:]*:52: Error: lo register required -- `orr r0,r8'
[^:]*:52: Error: unshifted register required -- `orr r0,#12'
@@ -91,9 +95,9 @@
[^:]*:71: Error: lo register required -- `add r8,r0,#1'
[^:]*:72: Error: lo register required -- `add r0,r8,#1'
[^:]*:73: Error: lo register required -- `add r8,#10'
-[^:]*:74: Error: dest and source1 must be the same register -- `add r8,r1,r2'
-[^:]*:75: Error: dest and source1 must be the same register -- `add r1,r8,r2'
-[^:]*:76: Error: dest and source1 must be the same register -- `add r1,r2,r8'
+[^:]*:74: Error: dest must overlap one source register -- `add r8,r1,r2'
+[^:]*:75: Error: dest must overlap one source register -- `add r1,r8,r2'
+[^:]*:76: Error: dest must overlap one source register -- `add r1,r2,r8'
[^:]*:77: Error: lo register required -- `add r8,pc,#4'
[^:]*:78: Error: lo register required -- `add r8,sp,#4'
[^:]*:80: Error: lo register required -- `sub r8,r0'
@@ -129,15 +133,15 @@
[^:]*:108: Error: Thumb does not support this addressing mode -- `ldrh r0,\[r1\],#4'
[^:]*:108: Error: Thumb does not support this addressing mode -- `ldrh r0,\[r1,-r2\]'
[^:]*:108: Error: Thumb does not support this addressing mode -- `ldrh r0,\[r1\],r2'
-[^:]*:109: Error: Thumb does not support this addressing mode -- `ldrsb r8,\[r0\]'
-[^:]*:109: Error: Thumb does not support this addressing mode -- `ldrsb r0,\[r8\]'
+[^:]*:109: Error: lo register required -- `ldrsb r8,\[r0\]'
+[^:]*:109: Error: lo register required -- `ldrsb r0,\[r8\]'
[^:]*:109: Error: lo register required -- `ldrsb r0,\[r0,r8\]'
[^:]*:109: Error: Thumb does not support this addressing mode -- `ldrsb r0,\[r1,#4\]!'
[^:]*:109: Error: Thumb does not support this addressing mode -- `ldrsb r0,\[r1\],#4'
[^:]*:109: Error: Thumb does not support this addressing mode -- `ldrsb r0,\[r1,-r2\]'
[^:]*:109: Error: Thumb does not support this addressing mode -- `ldrsb r0,\[r1\],r2'
-[^:]*:110: Error: Thumb does not support this addressing mode -- `ldrsh r8,\[r0\]'
-[^:]*:110: Error: Thumb does not support this addressing mode -- `ldrsh r0,\[r8\]'
+[^:]*:110: Error: lo register required -- `ldrsh r8,\[r0\]'
+[^:]*:110: Error: lo register required -- `ldrsh r0,\[r8\]'
[^:]*:110: Error: lo register required -- `ldrsh r0,\[r0,r8\]'
[^:]*:110: Error: Thumb does not support this addressing mode -- `ldrsh r0,\[r1,#4\]!'
[^:]*:110: Error: Thumb does not support this addressing mode -- `ldrsh r0,\[r1\],#4'
===================================================================
Index: gas/config/tc-arm.c
--- gas/config/tc-arm.c (revision 78)
+++ gas/config/tc-arm.c (revision 79)
@@ -184,11 +184,20 @@
instructions. */
static int thumb_mode = 0;
+/* If "thumb32_mode" is not true, we are processing old-style
+ Thumb assembly. Most importantly, that means that a large number
+ of arithmetic mnemonics set the flags even though they don't have
+ an 's' suffix. Note that encoders for instructions that only exist
+ in V6T2 or later, ignore thumb32_mode. */
+
+static bfd_boolean thumb32_mode = FALSE;
+
struct arm_it
{
const char * error;
unsigned long instruction;
int size;
+ int size_req;
struct
{
bfd_reloc_code_real_type type;
@@ -459,7 +468,6 @@
#define T_OPCODE_BRANCH 0xe7fe
#define THUMB_SIZE 2 /* Size of thumb instruction. */
-
#define THUMB_PP_PC_LR 0x0100
#define THUMB_LOAD_BIT 0x0800
@@ -468,6 +476,7 @@
#define BAD_COND _("instruction cannot be conditional")
#define BAD_OVERLAP _("registers may not be the same")
#define BAD_HIREG _("lo register required")
+#define BAD_THUMB32 _("instruction not supported in Thumb16 mode")
static struct hash_control *arm_ops_hsh;
static struct hash_control *arm_cond_hsh;
@@ -1414,6 +1423,7 @@
as_bad (_("selected processor does not support THUMB opcodes"));
thumb_mode = 1;
+ thumb32_mode = FALSE;
/* No need to force the alignment, since we will have been
coming from ARM mode, which is word-aligned. */
record_alignment (now_seg, 1);
@@ -1457,6 +1467,16 @@
}
static void
+s_thumb32 (int ignore ATTRIBUTE_UNUSED)
+{
+ opcode_select (16);
+ if (! (cpu_variant & ARM_EXT_V6T2))
+ as_bad (_("selected processor does not support 32-bit Thumb opcodes"));
+ thumb32_mode = TRUE;
+ demand_empty_rest_of_line ();
+}
+
+static void
s_code (int unused ATTRIBUTE_UNUSED)
{
int temp;
@@ -1485,6 +1505,7 @@
if (! thumb_mode)
{
thumb_mode = 2;
+ thumb32_mode = FALSE;
record_alignment (now_seg, 1);
}
@@ -1495,14 +1516,21 @@
static void
s_thumb_func (int ignore ATTRIBUTE_UNUSED)
{
- if (! thumb_mode)
- opcode_select (16);
+ s_thumb (0);
/* The following label is the name/address of the start of a Thumb function.
We need to know this for the interworking support. */
label_is_thumb_function_name = TRUE;
+}
- demand_empty_rest_of_line ();
+static void
+s_thumb32_func (int ignore ATTRIBUTE_UNUSED)
+{
+ s_thumb32 (0);
+
+ /* The following label is the name/address of the start of a Thumb function.
+ We need to know this for the interworking support. */
+ label_is_thumb_function_name = TRUE;
}
/* Perform a .set directive, but also mark the alias as
@@ -2745,9 +2773,11 @@
{ "align", s_align, 0 },
{ "arm", s_arm, 0 },
{ "thumb", s_thumb, 0 },
+ { "thumb32", s_thumb32, 0 },
{ "code", s_code, 0 },
{ "force_thumb", s_force_thumb, 0 },
{ "thumb_func", s_thumb_func, 0 },
+ { "thumb32_func",s_thumb32_func,0 },
{ "thumb_set", s_thumb_set, 0 },
{ "even", s_even, 0 },
{ "ltorg", s_ltorg, 0 },
@@ -3031,6 +3061,10 @@
inst.operands[i].reg = value;
inst.operands[i].isreg = 1;
+ /* parse_shift will override this if appropriate */
+ inst.reloc.exp.X_op = O_constant;
+ inst.reloc.exp.X_add_number = 0;
+
if (skip_past_comma (str) == FAIL)
return SUCCESS;
@@ -3498,6 +3532,7 @@
OP_oI255c, /* curly-brace enclosed, 0 .. 255 */
OP_oRR, /* ARM register */
+ OP_oRRnpc, /* ARM register, not the PC */
OP_oSHll, /* LSL immediate */
OP_oSHar, /* ASR immediate */
OP_oSHllar, /* LSL or ASR immediate */
@@ -3573,6 +3608,7 @@
switch (upat[i])
{
/* Registers */
+ case OP_oRRnpc:
case OP_RRnpc:
case OP_oRR:
case OP_RR: po_reg_or_fail (REG_TYPE_RN); break;
@@ -3771,6 +3807,7 @@
this allows a syntax error to take precedence. */
switch (upat[i])
{
+ case OP_oRRnpc:
case OP_RRnpc:
case OP_RRnpcb:
case OP_RRw:
@@ -3854,8 +3891,7 @@
static unsigned int
encode_arm_immediate (unsigned int val)
{
- unsigned int a;
- unsigned int i;
+ unsigned int a, i;
for (i = 0; i < 32; i += 2)
if ((a = rotate_left (val, i)) <= 0xff)
@@ -3864,6 +3900,35 @@
return FAIL;
}
+/* If VAL can be encoded in the immediate field of a Thumb32 instruction,
+ return the encoded form. Otherwise, return FAIL. */
+static unsigned int
+encode_thumb32_immediate (unsigned int val)
+{
+ unsigned int a, i;
+
+ if (val <= 255)
+ return val;
+
+ for (i = 0; i < 32; i++)
+ {
+ a = rotate_left (val, i);
+ if (a >= 128 && a <= 255)
+ return (a & 0x7f) | (i << 7);
+ }
+
+ a = val & 0xff;
+ if (val == ((a << 16) | a))
+ return 0x100 | a;
+ if (val == ((a << 24) | (a << 16) | (a << 8) | a))
+ return 0x300 | a;
+
+ a = val & 0xff00;
+ if (val == ((a << 16) | a))
+ return 0x200 | (a >> 8);
+
+ return FAIL;
+}
/* Encode a VFP SP register number into inst.instruction. */
static void
@@ -4108,7 +4173,7 @@
{
if ((inst.reloc.exp.X_add_number & ~0xFF) == 0)
{
- /* This can be done with a mov instruction. */
+ /* This can be done with a mov(1) instruction. */
inst.instruction = T_OPCODE_MOV_I8 | (inst.operands[i].reg << 8);
inst.instruction |= inst.reloc.exp.X_add_number;
return 1;
@@ -4191,7 +4256,7 @@
inst.instruction |= inst.operands[1].reg << 12;
}
-static void
+static void
do_rd_rm_rn (void)
{
inst.instruction |= inst.operands[0].reg << 12;
@@ -4530,34 +4595,77 @@
static void
do_ldrd (void)
{
- constraint (!inst.operands[1].isreg, _("'[' expected"));
constraint (inst.operands[0].reg % 2 != 0,
- _("destination register must be even"));
+ _("first destination register must be even"));
+ constraint (inst.operands[1].present
+ && inst.operands[1].reg != inst.operands[0].reg + 1,
+ _("can only load two consecutive registers"));
constraint (inst.operands[0].reg == REG_LR, _("r14 not allowed here"));
+ constraint (!inst.operands[2].isreg, _("'[' expected"));
+
+ if (!inst.operands[1].present)
+ inst.operands[1].reg = inst.operands[0].reg + 1;
+
if (inst.instruction & LOAD_BIT)
{
/* encode_arm_addr_mode_3 will diagnose overlap between the base
register and the first register written; we have to diagnose
overlap between the base and the second register written here. */
- if ((inst.operands[1].reg == inst.operands[0].reg + 1)
- && (inst.operands[1].writeback || inst.operands[1].postind))
+ if (inst.operands[2].reg == inst.operands[1].reg
+ && (inst.operands[2].writeback || inst.operands[2].postind))
as_warn (_("base register written back, and overlaps "
"second destination register"));
/* For an index-register load, the index register must not overlap the
destination (even if not write-back). */
- else if (inst.operands[1].immisreg
- && (inst.operands[1].imm == inst.operands[0].reg
- || inst.operands[1].imm == inst.operands[0].reg + 1))
+ else if (inst.operands[2].immisreg
+ && (inst.operands[2].imm == inst.operands[0].reg
+ || inst.operands[2].imm == inst.operands[1].reg))
as_warn (_("index register overlaps destination register"));
}
inst.instruction |= inst.operands[0].reg << 12;
- encode_arm_addr_mode_3 (1, /*is_t=*/FALSE);
+ encode_arm_addr_mode_3 (2, /*is_t=*/FALSE);
}
static void
+do_ldrex (void)
+{
+ constraint (!inst.operands[1].isreg || !inst.operands[1].preind
+ || inst.operands[1].postind || inst.operands[1].writeback
+ || inst.operands[1].immisreg || inst.operands[1].shifted
+ || inst.operands[1].negative,
+ _("instruction does not accept this addressing mode"));
+
+ constraint (inst.operands[1].reg == REG_PC, BAD_PC);
+
+ constraint (inst.reloc.exp.X_op != O_constant
+ || inst.reloc.exp.X_add_number != 0,
+ _("offset must be zero in ARM encoding"));
+
+ inst.instruction |= inst.operands[0].reg << 12;
+ inst.instruction |= inst.operands[1].reg << 16;
+ inst.reloc.type = BFD_RELOC_UNUSED;
+}
+
+static void
+do_ldrexd (void)
+{
+ constraint (inst.operands[0].reg % 2 != 0,
+ _("even register required"));
+ constraint (inst.operands[1].present
+ && inst.operands[1].reg != inst.operands[0].reg + 1,
+ _("can only load two consecutive registers"));
+ /* If op 1 were present and equal to PC, this function wouldn't
+ have been called in the first place. */
+ constraint (inst.operands[0].reg == REG_LR, _("r14 not allowed here"));
+
+ inst.instruction |= inst.operands[0].reg << 12;
+ inst.instruction |= inst.operands[2].reg << 16;
+}
+
+static void
do_ldst (void)
{
inst.instruction |= inst.operands[0].reg << 12;
@@ -4967,14 +5075,49 @@
static void
do_strex (void)
{
+ constraint (!inst.operands[2].isreg || !inst.operands[2].preind
+ || inst.operands[2].postind || inst.operands[2].writeback
+ || inst.operands[2].immisreg || inst.operands[2].shifted
+ || inst.operands[2].negative,
+ _("instruction does not accept this addressing mode"));
+
+ constraint (inst.operands[2].reg == REG_PC, BAD_PC);
+
constraint (inst.operands[0].reg == inst.operands[1].reg
|| inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
+ constraint (inst.reloc.exp.X_op != O_constant
+ || inst.reloc.exp.X_add_number != 0,
+ _("offset must be zero in ARM encoding"));
+
inst.instruction |= inst.operands[0].reg << 12;
inst.instruction |= inst.operands[1].reg;
inst.instruction |= inst.operands[2].reg << 16;
+ inst.reloc.type = BFD_RELOC_UNUSED;
}
+static void
+do_strexd (void)
+{
+ constraint (inst.operands[1].reg % 2 != 0,
+ _("even register required"));
+ constraint (inst.operands[2].present
+ && inst.operands[2].reg != inst.operands[1].reg + 1,
+ _("can only store two consecutive registers"));
+ /* If op 2 were present and equal to PC, this function wouldn't
+ have been called in the first place. */
+ constraint (inst.operands[1].reg == REG_LR, _("r14 not allowed here"));
+
+ constraint (inst.operands[0].reg == inst.operands[1].reg
+ || inst.operands[0].reg == inst.operands[1].reg + 1
+ || inst.operands[0].reg == inst.operands[3].reg,
+ BAD_OVERLAP);
+
+ inst.instruction |= inst.operands[0].reg << 12;
+ inst.instruction |= inst.operands[1].reg;
+ inst.instruction |= inst.operands[3].reg << 16;
+}
+
/* ARM V6 SXTAH extracts a 16-bit value from a register, sign
extends it to 32-bits, and adds the result to a value in another
register. You can specify a rotation by 0, 8, 16, or 24 bits
@@ -5197,7 +5340,7 @@
if ((inst.instruction & PRE_INDEX) || inst.operands[2].writeback)
inst.reloc.exp.X_add_number = 12 * inst.operands[1].imm;
-
+
if (!(inst.instruction & INDEX_UP))
inst.reloc.exp.X_add_number = -inst.reloc.exp.X_add_number;
@@ -5404,50 +5547,324 @@
inst.instruction |= inst.operands[1].reg << 16;
}
-/* Thumb instructions, in alphabetical order. */
+/* Encoding functions relevant only to Thumb. */
-/* Parse an add or subtract instruction. The high bit of inst.instruction
- is set if the opcode was SUB. */
+/* inst.operands[i] is a shifted-register operand; encode
+ it into inst.instruction in the format used by Thumb32. */
static void
+encode_thumb32_shifted_operand (int i)
+{
+ unsigned int value = inst.reloc.exp.X_add_number;
+ unsigned int shift = inst.operands[i].shift_kind;
+
+ inst.instruction |= inst.operands[i].reg;
+ if (shift == SHIFT_RRX)
+ inst.instruction |= SHIFT_ROR << 4;
+ else
+ {
+ constraint (inst.reloc.exp.X_op != O_constant,
+ _("expression too complex"));
+
+ constraint (value > 32
+ || (value == 32 && (shift == SHIFT_LSL
+ || shift == SHIFT_ROR)),
+ _("shift expression is too large"));
+
+ if (value == 0)
+ shift = SHIFT_LSL;
+ else if (value == 32)
+ value = 0;
+
+ inst.instruction |= shift << 4;
+ inst.instruction |= (value & 0x1c) << 10;
+ inst.instruction |= (value & 0x03) << 6;
+ }
+}
+
+
+/* inst.operands[i] was set up by parse_address. Encode it into a
+ Thumb32 format load or store instruction. Reject forms that cannot
+ be used with such instructions. If is_t is true, reject forms that
+ cannot be used with a T instruction; if is_d is true, reject forms
+ that cannot be used with a D instruction. */
+
+static void
+encode_thumb32_addr_mode (int i, bfd_boolean is_t, bfd_boolean is_d)
+{
+ bfd_boolean is_pc = (inst.operands[i].reg == REG_PC);
+
+ constraint (!inst.operands[i].isreg,
+ _("Thumb does not support the ldr =N pseudo-operation"));
+
+ inst.instruction |= inst.operands[i].reg << 16;
+ if (inst.operands[i].immisreg)
+ {
+ constraint (is_pc, _("cannot use register index with PC-relative addressing"));
+ constraint (is_t || is_d, _("cannot use register index with this instruction"));
+ constraint (inst.operands[i].negative,
+ _("Thumb does not support negative register indexing"));
+ constraint (inst.operands[i].postind,
+ _("Thumb does not support register post-indexing"));
+ constraint (inst.operands[i].writeback,
+ _("Thumb does not support register indexing with writeback"));
+ constraint (inst.operands[i].shifted && inst.operands[i].shift_kind != SHIFT_LSL,
+ _("Thumb supports only LSL in shifted register indexing"));
+
+ inst.instruction |= inst.operands[1].imm;
+ if (inst.operands[i].shifted)
+ {
+ constraint (inst.reloc.exp.X_op != O_constant,
+ _("expression too complex"));
+ constraint (inst.reloc.exp.X_add_number < 0 || inst.reloc.exp.X_add_number > 3,
+ _("shift out of range"));
+ inst.instruction |= inst.reloc.exp.X_op << 4;
+ }
+ inst.reloc.type = BFD_RELOC_UNUSED;
+ }
+ else if (inst.operands[i].preind)
+ {
+ constraint (is_pc && inst.operands[i].writeback,
+ _("cannot use writeback with PC-relative addressing"));
+ constraint (is_t && inst.operands[1].writeback,
+ _("cannot use writeback with this instruction"));
+
+ if (is_d)
+ {
+ inst.instruction |= 0x01000000;
+ if (inst.operands[i].writeback)
+ inst.instruction |= 0x00200000;
+ }
+ else
+ {
+ inst.instruction |= 0x00000c00;
+ if (inst.operands[i].writeback)
+ inst.instruction |= 0x00000100;
+ }
+ inst.reloc.type = BFD_RELOC_ARM_T32_OFFSET_IMM;
+ }
+ else if (inst.operands[i].postind)
+ {
+ assert (inst.operands[i].writeback);
+ constraint (is_pc, _("cannot use post-indexing with PC-relative addressing"));
+ constraint (is_t, _("cannot use post-indexing with this instruction"));
+
+ if (is_d)
+ inst.instruction |= 0x00200000;
+ else
+ inst.instruction |= 0x00000900;
+ inst.reloc.type = BFD_RELOC_ARM_T32_OFFSET_IMM;
+ }
+ else /* unindexed - only for coprocessor */
+ inst.error = _("instruction does not accept unindexed addressing");
+}
+
+/* Table of Thumb instructions which exist in both 16- and 32-bit
+ encodings (the latter only in post-V6T2 cores). The index is the
+ value used in the insns table below. When there is more than one
+ possible 16-bit encoding for the instruction, this table always
+ holds variant (1). */
+#define T16_32_TAB \
+ X(adc, 4140, eb400000), \
+ X(adcs, 4140, eb500000), \
+ X(add, 1c00, eb000000), \
+ X(adds, 1c00, eb100000), \
+ X(and, 4000, ea000000), \
+ X(ands, 4000, ea100000), \
+ X(asr, 1000, fa40f000), \
+ X(asrs, 1000, fa50f000), \
+ X(bic, 4380, ea200000), \
+ X(bics, 4380, ea300000), \
+ X(blx, 4780, f000c000), \
+ X(cmn, 42c0, eb100f00), \
+ X(cmp, 2800, ebb00f00), \
+ X(cpsie, b660, f3af8400), \
+ X(cpsid, b670, f3af8600), \
+ X(cpy, 4600, ea4f0000), \
+ X(eor, 4040, ea800000), \
+ X(eors, 4040, ea900000), \
+ X(ldmia, c800, e8900000), \
+ X(ldr, 6800, f8500000), \
+ X(ldrb, 7800, f8100000), \
+ X(ldrh, 8800, f8300000), \
+ X(ldrsb, 5600, f9100000), \
+ X(ldrsh, 5e00, f9300000), \
+ X(lsl, 0000, fa00f000), \
+ X(lsls, 0000, fa10f000), \
+ X(lsr, 0800, fa20f000), \
+ X(lsrs, 0800, fa30f000), \
+ X(mov, 2000, ea4f0000), \
+ X(movs, 2000, ea5f0000), \
+ X(mul, 4340, fb00f000), \
+ X(muls, 4340, ffffffff), /* no 32b muls */ \
+ X(mvn, 43c0, ea6f0000), \
+ X(mvns, 43c0, ea7f0000), \
+ X(neg, 4240, f1c00000), /* rsb #0 */ \
+ X(negs, 4240, f1d00000), /* rsbs #0 */ \
+ X(orr, 4300, ea400000), \
+ X(orrs, 4300, ea500000), \
+ X(pop, bc00, e8ad0000), /* ldmia sp!,... */ \
+ X(push, b400, e8bd0000), /* stmia sp!,... */ \
+ X(rev, ba00, fa90f080), \
+ X(rev16, ba40, fa90f090), \
+ X(revsh, bac0, fa90f0b0), \
+ X(ror, 41c0, fa60f000), \
+ X(rors, 41c0, fa70f000), \
+ X(sbc, 4180, eb600000), \
+ X(sbcs, 4180, eb700000), \
+ X(stmia, c000, e8800000), \
+ X(str, 6000, f8400000), \
+ X(strb, 7000, f8000000), \
+ X(strh, 8000, f8200000), \
+ X(sub, 1e00, eba00000), \
+ X(subs, 1e00, ebb00000), \
+ X(sxtb, b240, fa4ff080), \
+ X(sxth, b200, fa0ff080), \
+ X(tst, 4200, ea100f00), \
+ X(uxtb, b2c0, fa5ff080), \
+ X(uxth, b280, fa1ff080), \
+ X(nop, bf00, f3af8000), \
+ X(yield, bf10, f3af8001), \
+ X(wfe, bf20, f3af8002), \
+ X(wfi, bf30, f3af8003), \
+ X(sev, bf40, f3af9004), /* typo, 8004? */
+
+/* To catch errors in encoding functions, the codes are all offset by
+ 0xF800, putting them in one of the 32-bit prefix ranges, ergo undefined
+ as 16-bit instructions. */
+#define X(a,b,c) T_MNEM_##a
+enum t16_32_codes { T16_32_OFFSET = 0xF7FF, T16_32_TAB };
+#undef X
+
+#define X(a,b,c) 0x##b
+static const unsigned short thumb_op16[] = { T16_32_TAB };
+#define THUMB_OP16(n) (thumb_op16[(n) - (T16_32_OFFSET + 1)])
+#undef X
+
+#define X(a,b,c) 0x##c
+static const unsigned int thumb_op32[] = { T16_32_TAB };
+#define THUMB_OP32(n) (thumb_op32[(n) - (T16_32_OFFSET + 1)])
+#define THUMB_SETS_FLAGS(n) (THUMB_OP32 (n) & 0x00100000)
+#undef X
+#undef T16_32_TAB
+
+/* Thumb instruction encoders, in alphabetical order. */
+
+/* Parse an add or subtract instruction. We get here with inst.instruction
+ equalling any of THUMB_OPCODE_add, adds, sub, or subs. */
+
+static void
do_t_add_sub (void)
{
int Rd, Rs, Rn;
- int subtract = !!(inst.instruction & 0x8000);
Rd = inst.operands[0].reg;
Rs = (inst.operands[1].present
? inst.operands[1].reg /* Rd, Rs, foo */
: inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
- if (!inst.operands[2].isreg) /* Rd, Rs, #imm */
+ if (thumb32_mode)
{
- constraint ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
- || (Rs > 7 && Rs != REG_SP && Rs != REG_PC),
- BAD_HIREG);
- inst.instruction |= (Rd << 4) | Rs;
- inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
- return;
- }
+ if (!inst.operands[2].isreg)
+ {
+ /* For an immediate, we always generate a 32-bit opcode;
+ section relaxation will shrink it later if possible. */
+ inst.instruction = THUMB_OP32 (inst.instruction);
+ inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
+ inst.instruction |= inst.operands[0].reg << 8;
+ inst.instruction |= inst.operands[1].reg << 16;
+ inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE;
+ }
+ else
+ {
+ Rn = inst.operands[2].reg;
+ /* See if we can do this with a 16-bit instruction. */
+ if (!inst.operands[2].shifted && inst.size_req != 4)
+ {
+ if (Rd <= 7 && Rn <= 7 && Rn <= 7
+ && (inst.instruction == T_MNEM_adds
+ || inst.instruction == T_MNEM_subs))
+ {
+ inst.instruction = (inst.instruction == T_MNEM_adds
+ ? T_OPCODE_ADD_R3
+ : T_OPCODE_SUB_R3);
+ inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
+ return;
+ }
- Rn = inst.operands[2].reg;
- constraint (inst.operands[2].shifted, _("unshifted register required"));
-
- /* We now have Rd, Rs, and Rn set to registers. */
- if (Rd > 7 || Rs > 7 || Rn > 7)
- {
- /* Can't do this for SUB. */
- constraint (subtract, BAD_HIREG);
- constraint (Rs != Rd, _("dest and source1 must be the same register"));
- inst.instruction = T_OPCODE_ADD_HI;
- inst.instruction |= (Rd & 8) << 4;
- inst.instruction |= (Rd & 7);
- inst.instruction |= Rn << 3;
+ if (inst.instruction == T_MNEM_add)
+ {
+ if (Rd == Rs)
+ {
+ inst.instruction = T_OPCODE_ADD_HI;
+ inst.instruction |= (Rd & 8) << 4;
+ inst.instruction |= (Rd & 7);
+ inst.instruction |= Rn << 3;
+ return;
+ }
+ /* ... because addition is commutative! */
+ else if (Rd == Rn)
+ {
+ inst.instruction = T_OPCODE_ADD_HI;
+ inst.instruction |= (Rd & 8) << 4;
+ inst.instruction |= (Rd & 7);
+ inst.instruction |= Rs << 3;
+ return;
+ }
+ }
+ }
+ /* If we get here, it can't be done in 16 bits. */
+ constraint (inst.operands[2].shifted && inst.operands[2].immisreg,
+ _("shift must be constant"));
+ inst.instruction = THUMB_OP32 (inst.instruction);
+ inst.instruction |= Rd << 8;
+ inst.instruction |= Rs << 16;
+ encode_thumb32_shifted_operand (2);
+ }
}
else
{
- inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
- inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
+ constraint (inst.instruction == T_MNEM_adds
+ || inst.instruction == T_MNEM_subs,
+ BAD_THUMB32);
+
+ if (!inst.operands[2].isreg) /* Rd, Rs, #imm */
+ {
+ constraint ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
+ || (Rs > 7 && Rs != REG_SP && Rs != REG_PC),
+ BAD_HIREG);
+
+ inst.instruction = (inst.instruction == T_MNEM_add
+ ? 0x0000 : 0x8000);
+ inst.instruction |= (Rd << 4) | Rs;
+ inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
+ return;
+ }
+
+ Rn = inst.operands[2].reg;
+ constraint (inst.operands[2].shifted, _("unshifted register required"));
+
+ /* We now have Rd, Rs, and Rn set to registers. */
+ if (Rd > 7 || Rs > 7 || Rn > 7)
+ {
+ /* Can't do this for SUB. */
+ constraint (inst.instruction == T_MNEM_sub, BAD_HIREG);
+ inst.instruction = T_OPCODE_ADD_HI;
+ inst.instruction |= (Rd & 8) << 4;
+ inst.instruction |= (Rd & 7);
+ if (Rs == Rd)
+ inst.instruction |= Rn << 3;
+ else if (Rn == Rd)
+ inst.instruction |= Rs << 3;
+ else
+ constraint (1, _("dest must overlap one source register"));
+ }
+ else
+ {
+ inst.instruction = (inst.instruction == T_MNEM_add
+ ? T_OPCODE_ADD_R3 : T_OPCODE_SUB_R3);
+ inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
+ }
}
}
@@ -5461,45 +5878,218 @@
inst.instruction |= inst.operands[0].reg << 4;
}
-/* Handle the Format 4 instructions that do not have equivalents in
- other formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN,
- ORR, BIC and MVN. */
+/* Arithmetic instructions for which there is just one 16-bit
+ instruction encoding, and it allows only two low registers.
+ For maximal compatibility with ARM syntax, we allow three register
+ operands even when Thumb-32 instructions are not available, as long
+ as the first two are identical. For instance, both "sbc r0,r1" and
+ "sbc r0,r0,r1" are allowed. */
+static void
+do_t_arit3 (void)
+{
+ int Rd, Rs, Rn;
+ Rd = inst.operands[0].reg;
+ Rs = (inst.operands[1].present
+ ? inst.operands[1].reg /* Rd, Rs, foo */
+ : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
+ Rn = inst.operands[2].reg;
+
+ if (thumb32_mode)
+ {
+ if (!inst.operands[2].isreg)
+ {
+ /* For an immediate, we always generate a 32-bit opcode;
+ section relaxation will shrink it later if possible. */
+ inst.instruction = THUMB_OP32 (inst.instruction);
+ inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
+ inst.instruction |= Rd << 8;
+ inst.instruction |= Rs << 16;
+ inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE;
+ }
+ else
+ {
+ /* See if we can do this with a 16-bit instruction. */
+ if (THUMB_SETS_FLAGS (inst.instruction)
+ && !inst.operands[2].shifted
+ && inst.size_req != 4
+ && Rd == Rs)
+ {
+ inst.instruction = THUMB_OP16 (inst.instruction);
+ inst.instruction |= Rd;
+ inst.instruction |= Rn << 3;
+ return;
+ }
+
+ /* If we get here, it can't be done in 16 bits. */
+ constraint (inst.operands[2].shifted
+ && inst.operands[2].immisreg,
+ _("shift must be constant"));
+ inst.instruction = THUMB_OP32 (inst.instruction);
+ inst.instruction |= Rd << 8;
+ inst.instruction |= Rs << 16;
+ encode_thumb32_shifted_operand (2);
+ }
+ }
+ else
+ {
+ /* On its face this is a lie - the instruction does set the
+ flags. However, the only supported mnemonic in this mode
+ says it doesn't. */
+ constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
+
+ constraint (!inst.operands[2].isreg || inst.operands[2].shifted,
+ _("unshifted register required"));
+ constraint (Rd > 7 || Rs > 7 || Rn > 7, BAD_HIREG);
+ constraint (Rd != Rs,
+ _("dest and source1 must be the same register"));
+
+ inst.instruction = THUMB_OP16 (inst.instruction);
+ inst.instruction |= Rd;
+ inst.instruction |= Rn << 3;
+ }
+}
+
+/* Similarly, but for instructions where the arithmetic operation is
+ commutative, so we can allow either of them to be different from
+ the destination operand in a 16-bit instruction. For instance, all
+ three of "adc r0,r1", "adc r0,r0,r1", and "adc r0,r1,r0" are
+ accepted. */
static void
-do_t_arit (void)
+do_t_arit3c (void)
{
- constraint (!inst.operands[1].isreg || inst.operands[1].shifted,
- _("unshifted register required"));
- constraint (inst.operands[0].reg > 7 || inst.operands[1].reg > 7, BAD_HIREG);
- inst.instruction |= inst.operands[0].reg;
- inst.instruction |= inst.operands[1].reg << 3;
+ int Rd, Rs, Rn;
+
+ Rd = inst.operands[0].reg;
+ Rs = (inst.operands[1].present
+ ? inst.operands[1].reg /* Rd, Rs, foo */
+ : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
+ Rn = inst.operands[2].reg;
+
+ if (thumb32_mode)
+ {
+ if (!inst.operands[2].isreg)
+ {
+ /* For an immediate, we always generate a 32-bit opcode;
+ section relaxation will shrink it later if possible. */
+ inst.instruction = THUMB_OP32 (inst.instruction);
+ inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
+ inst.instruction |= Rd << 8;
+ inst.instruction |= Rs << 16;
+ inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE;
+ }
+ else
+ {
+ /* See if we can do this with a 16-bit instruction. */
+ if (THUMB_SETS_FLAGS (inst.instruction)
+ && !inst.operands[2].shifted
+ && inst.size_req != 4)
+ {
+ if (Rd == Rs)
+ {
+ inst.instruction = THUMB_OP16 (inst.instruction);
+ inst.instruction |= Rd;
+ inst.instruction |= Rn << 3;
+ return;
+ }
+ if (Rd == Rn)
+ {
+ inst.instruction = THUMB_OP16 (inst.instruction);
+ inst.instruction |= Rd;
+ inst.instruction |= Rs << 3;
+ return;
+ }
+ }
+
+ /* If we get here, it can't be done in 16 bits. */
+ constraint (inst.operands[2].shifted
+ && inst.operands[2].immisreg,
+ _("shift must be constant"));
+ inst.instruction = THUMB_OP32 (inst.instruction);
+ inst.instruction |= Rd << 8;
+ inst.instruction |= Rs << 16;
+ encode_thumb32_shifted_operand (2);
+ }
+ }
+ else
+ {
+ /* On its face this is a lie - the instruction does set the
+ flags. However, the only supported mnemonic in this mode
+ says it doesn't. */
+ constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
+
+ constraint (!inst.operands[2].isreg || inst.operands[2].shifted,
+ _("unshifted register required"));
+ constraint (Rd > 7 || Rs > 7 || Rn > 7, BAD_HIREG);
+
+ inst.instruction = THUMB_OP16 (inst.instruction);
+ inst.instruction |= Rd;
+
+ if (Rd == Rs)
+ inst.instruction |= Rn << 3;
+ else if (Rd == Rn)
+ inst.instruction |= Rn << 3;
+ else
+ constraint (1, _("dest must overlap one source register"));
+ }
}
-/* Fake three-argument form for instructions that take three arguments
- in ARM mode, e.g. you may write "adc r0,r0,r1" instead of "adc r0,r1". */
static void
-do_t_arit3 (void)
+do_t_bfc (void)
{
- constraint (!inst.operands[2].isreg || inst.operands[2].shifted,
- _("unshifted register required"));
- constraint (inst.operands[0].reg > 7
- || inst.operands[1].reg > 7
- || inst.operands[2].reg > 7, BAD_HIREG);
- constraint (inst.operands[1].present
- && inst.operands[0].reg != inst.operands[1].reg,
- _("dest and source1 must be the same register"));
+ unsigned int msb = inst.operands[1].imm + inst.operands[2].imm;
+ constraint (msb > 32, _("bit-field extends past end of register"));
+ /* The instruction encoding stores the LSB and MSB,
+ not the LSB and width. */
+ inst.instruction |= inst.operands[0].reg << 8;
+ inst.instruction |= (inst.operands[1].imm & 0x1c) << 10;
+ inst.instruction |= (inst.operands[1].imm & 0x03) << 6;
+ inst.instruction |= msb - 1;
+}
- inst.instruction |= inst.operands[0].reg;
- inst.instruction |= inst.operands[2].reg << 3;
+static void
+do_t_bfi (void)
+{
+ unsigned int msb;
+
+ /* #0 in second position is alternative syntax for bfc, which is
+ the same instruction but with REG_PC in the Rm field. */
+ if (!inst.operands[1].isreg)
+ inst.operands[1].reg = REG_PC;
+
+ msb = inst.operands[2].imm + inst.operands[3].imm;
+ constraint (msb > 32, _("bit-field extends past end of register"));
+ /* The instruction encoding stores the LSB and MSB,
+ not the LSB and width. */
+ inst.instruction |= inst.operands[0].reg << 8;
+ inst.instruction |= inst.operands[1].reg << 16;
+ inst.instruction |= (inst.operands[2].imm & 0x1c) << 10;
+ inst.instruction |= (inst.operands[2].imm & 0x03) << 6;
+ inst.instruction |= msb - 1;
}
+static void
+do_t_bfx (void)
+{
+ constraint (inst.operands[2].imm + inst.operands[3].imm > 32,
+ _("bit-field extends past end of register"));
+ inst.instruction |= inst.operands[0].reg << 8;
+ inst.instruction |= inst.operands[1].reg << 16;
+ inst.instruction |= (inst.operands[2].imm & 0x1c) << 10;
+ inst.instruction |= (inst.operands[2].imm & 0x03) << 6;
+ inst.instruction |= inst.operands[3].imm - 1;
+}
+
/* ARM V5 Thumb BLX (argument parse)
BLX <target_addr> which is BLX(1)
BLX <Rm> which is BLX(2)
Unfortunately, there are two different opcodes for this mnemonic.
So, the insns[].value is not used, and the code here zaps values
- into inst.instruction. */
+ into inst.instruction.
+ ??? How to take advantage of the additional two bits of displacement
+ available in Thumb32 mode? Need new relocation? */
+
static void
do_t_blx (void)
{
@@ -5510,7 +6100,6 @@
{
/* No register. This must be BLX(1). */
inst.instruction = 0xf7ffeffe;
- inst.size = 4;
inst.reloc.type = BFD_RELOC_THUMB_PCREL_BLX;
inst.reloc.pc_rel = 1;
}
@@ -5519,9 +6108,27 @@
static void
do_t_branch (void)
{
- inst.reloc.type = (inst.instruction == T_OPCODE_BRANCH
- ? BFD_RELOC_THUMB_PCREL_BRANCH12
- : BFD_RELOC_THUMB_PCREL_BRANCH9);
+ if (thumb32_mode && inst.size_req != 2)
+ {
+ if (inst.instruction == T_OPCODE_BRANCH)
+ {
+ inst.instruction = 0xf7ffbffe;
+ inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH25;
+ }
+ else
+ {
+ int cond = inst.instruction & 0x0f00;
+ constraint (cond == 0xE00 || cond == 0xF00,
+ _("invalid condition for wide conditional branch"));
+ inst.instruction = (cond << 14) | 0xf43faffe;
+ inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH20;
+ }
+ }
+ else
+ inst.reloc.type = (inst.instruction == T_OPCODE_BRANCH
+ ? BFD_RELOC_THUMB_PCREL_BRANCH12
+ : BFD_RELOC_THUMB_PCREL_BRANCH9);
+
inst.reloc.pc_rel = 1;
}
@@ -5564,12 +6171,42 @@
}
static void
+do_t_bxj (void)
+{
+ if (inst.operands[0].reg == REG_PC)
+ as_tsktsk (_("use of r15 in bxj is not really useful"));
+
+ inst.instruction |= inst.operands[0].reg << 16;
+}
+
+static void
+do_t_clz (void)
+{
+ inst.instruction |= inst.operands[0].reg << 8;
+ inst.instruction |= inst.operands[1].reg << 16;
+ inst.instruction |= inst.operands[1].reg;
+}
+
+static void
do_t_cpsi (void)
{
- constraint (inst.operands[1].present,
- _("Thumb does not support the 2-argument "
- "form of this instruction"));
- inst.instruction |= inst.operands[0].imm;
+ if (thumb32_mode
+ && (inst.operands[1].present || inst.size_req == 4))
+ {
+ unsigned int imod = (inst.instruction & 0x0030) >> 4;
+ inst.instruction = 0xf3af8000;
+ inst.instruction |= imod << 9;
+ inst.instruction |= inst.operands[0].imm << 5;
+ if (inst.operands[1].present)
+ inst.instruction |= 0x100 | inst.operands[1].imm;
+ }
+ else
+ {
+ constraint (inst.operands[1].present,
+ _("Thumb does not support the 2-argument "
+ "form of this instruction"));
+ inst.instruction |= inst.operands[0].imm;
+ }
}
/* THUMB CPY instruction (argument parse). */
@@ -5577,9 +6214,18 @@
static void
do_t_cpy (void)
{
- inst.instruction |= (inst.operands[0].reg & 0x8) << 4;
- inst.instruction |= (inst.operands[0].reg & 0x7);
- inst.instruction |= inst.operands[1].reg << 3;
+ if (inst.size_req == 4)
+ {
+ inst.instruction = THUMB_OP32 (T_MNEM_mov);
+ inst.instruction |= inst.operands[0].reg << 8;
+ inst.instruction |= inst.operands[1].reg;
+ }
+ else
+ {
+ inst.instruction |= (inst.operands[0].reg & 0x8) << 4;
+ inst.instruction |= (inst.operands[0].reg & 0x7);
+ inst.instruction |= inst.operands[1].reg << 3;
+ }
}
static void
@@ -5592,10 +6238,19 @@
}
static void
+do_t_hint (void)
+{
+ if (thumb32_mode && inst.size_req == 4)
+ inst.instruction = THUMB_OP32 (inst.instruction);
+ else
+ inst.instruction = THUMB_OP16 (inst.instruction);
+}
+
+static void
do_t_it (void)
{
unsigned int cond = inst.operands[0].imm;
- if (cond & 0x1)
+ if ((cond & 0x1) == 0x0)
{
unsigned int mask = inst.instruction & 0x000f;
inst.instruction &= 0xfff0;
@@ -5621,55 +6276,160 @@
/* This really doesn't seem worth it. */
constraint (inst.reloc.type != BFD_RELOC_UNUSED,
_("expression too complex"));
- constraint (inst.operands[0].reg > 7
- || (inst.operands[1].imm & ~0xff), BAD_HIREG);
constraint (inst.operands[1].writeback,
_("Thumb load/store multiple does not support {reglist}^"));
- if (!(inst.instruction & THUMB_LOAD_BIT))
+
+ if (thumb32_mode)
{
- if (!inst.operands[0].writeback)
- as_warn (_("this instruction will write back the base register"));
- if ((inst.operands[1].imm & (1 << inst.operands[0].reg))
- && (inst.operands[1].imm & ((1 << inst.operands[0].reg) - 1)))
- as_warn (_("value stored for r%d is UNPREDICTABLE"),
- inst.operands[0].reg);
+ /* See if we can use a 16-bit instruction. */
+ if (inst.instruction < 0xffff /* not ldmdb/stmdb */
+ && inst.size_req != 4
+ && inst.operands[0].reg <= 7
+ && !(inst.operands[1].imm & ~0xff)
+ && (inst.instruction == T_MNEM_stmia
+ ? inst.operands[0].writeback
+ : (inst.operands[0].writeback
+ == !(inst.operands[1].imm & (1 << inst.operands[0].reg)))))
+ {
+ if (inst.instruction == T_MNEM_stmia
+ && (inst.operands[1].imm & (1 << inst.operands[0].reg))
+ && (inst.operands[1].imm & ((1 << inst.operands[0].reg) - 1)))
+ as_warn (_("value stored for r%d is UNPREDICTABLE"),
+ inst.operands[0].reg);
+
+ inst.instruction = THUMB_OP16 (inst.instruction);
+ inst.instruction |= inst.operands[0].reg << 8;
+ inst.instruction |= inst.operands[1].imm;
+ }
+ else
+ {
+ if (inst.operands[1].imm & (1 << 13))
+ as_warn (_("SP should not be in register list"));
+ if (inst.instruction == T_MNEM_stmia)
+ {
+ if (inst.operands[1].imm & (1 << 15))
+ as_warn (_("PC should not be in register list"));
+ if (inst.operands[1].imm & (1 << inst.operands[0].reg))
+ as_warn (_("value stored for r%d is UNPREDICTABLE"),
+ inst.operands[0].reg);
+ }
+ else
+ {
+ if (inst.operands[1].imm & (1 << 14)
+ && inst.operands[1].imm & (1 << 15))
+ as_warn (_("LR and PC should not both be in register list"));
+ if ((inst.operands[1].imm & (1 << inst.operands[0].reg))
+ && inst.operands[0].writeback)
+ as_warn (_("base register should not be in register list "
+ "when written back"));
+ }
+ if (inst.instruction < 0xffff)
+ inst.instruction = THUMB_OP32 (inst.instruction);
+ inst.instruction |= inst.operands[0].reg << 16;
+ inst.instruction |= inst.operands[1].imm;
+ if (inst.operands[0].writeback)
+ inst.instruction |= WRITE_BACK;
+ }
}
else
{
- if (!inst.operands[0].writeback
- && !(inst.operands[1].imm & (1 << inst.operands[0].reg)))
- as_warn (_("this instruction will write back the base register"));
- else if (inst.operands[0].writeback
- && (inst.operands[1].imm & (1 << inst.operands[0].reg)))
- as_warn (_("this instruction will not write back the base register"));
+ constraint (inst.operands[0].reg > 7
+ || (inst.operands[1].imm & ~0xff), BAD_HIREG);
+ if (inst.instruction == T_MNEM_stmia)
+ {
+ if (!inst.operands[0].writeback)
+ as_warn (_("this instruction will write back the base register"));
+ if ((inst.operands[1].imm & (1 << inst.operands[0].reg))
+ && (inst.operands[1].imm & ((1 << inst.operands[0].reg) - 1)))
+ as_warn (_("value stored for r%d is UNPREDICTABLE"),
+ inst.operands[0].reg);
+ }
+ else
+ {
+ if (!inst.operands[0].writeback
+ && !(inst.operands[1].imm & (1 << inst.operands[0].reg)))
+ as_warn (_("this instruction will write back the base register"));
+ else if (inst.operands[0].writeback
+ && (inst.operands[1].imm & (1 << inst.operands[0].reg)))
+ as_warn (_("this instruction will not write back the base register"));
+ }
+
+ inst.instruction = THUMB_OP16 (inst.instruction);
+ inst.instruction |= inst.operands[0].reg << 8;
+ inst.instruction |= inst.operands[1].imm;
}
-
- inst.instruction |= inst.operands[0].reg << 8;
- inst.instruction |= inst.operands[1].imm;
}
static void
-do_t_lds (void)
+do_t_ldrex (void)
{
- /* Only [Rn,Rm] is acceptable. */
- constraint (!inst.operands[1].isreg || !inst.operands[1].immisreg
- || inst.operands[1].postind || inst.operands[1].shifted
+ constraint (!inst.operands[1].isreg || !inst.operands[1].preind
+ || inst.operands[1].postind || inst.operands[1].writeback
+ || inst.operands[1].immisreg || inst.operands[1].shifted
|| inst.operands[1].negative,
- _("Thumb does not support this addressing mode"));
- constraint (inst.operands[0].reg > 7
- || inst.operands[1].reg > 7
- || inst.operands[1].imm > 7, BAD_HIREG);
+ _("instruction does not accept this addressing mode"));
- inst.instruction |= inst.operands[0].reg;
- inst.instruction |= inst.operands[1].reg << 3;
- inst.instruction |= inst.operands[1].imm << 6;
+ inst.instruction |= inst.operands[0].reg << 12;
+ inst.instruction |= inst.operands[1].reg << 16;
+ inst.reloc.type = BFD_RELOC_ARM_T32_OFFSET_U8;
}
static void
+do_t_ldrexd (void)
+{
+ if (!inst.operands[1].present)
+ {
+ constraint (inst.operands[0].reg == REG_LR,
+ _("r14 not allowed as first register "
+ "when second register is omitted"));
+ inst.operands[1].reg = inst.operands[0].reg + 1;
+ }
+ constraint (inst.operands[0].reg == inst.operands[1].reg,
+ BAD_OVERLAP);
+
+ inst.instruction |= inst.operands[0].reg << 12;
+ inst.instruction |= inst.operands[1].reg << 8;
+ inst.instruction |= inst.operands[2].reg << 16;
+}
+
+static void
do_t_ldst (void)
{
+ if (thumb32_mode)
+ {
+ /* Generation of 16-bit instructions for anything other than
+ Rd, [Rn, Ri] is deferred to section relaxation time. */
+ if (inst.operands[1].isreg && inst.operands[1].immisreg
+ && !inst.operands[1].shifted && !inst.operands[1].postind
+ && !inst.operands[1].negative && inst.operands[0].reg <= 7
+ && inst.operands[1].reg <= 7 && inst.operands[1].imm <= 7
+ && inst.instruction <= 0xffff)
+ {
+ inst.instruction = THUMB_OP16 (inst.instruction);
+ goto op16;
+ }
+
+ inst.instruction = THUMB_OP32 (inst.instruction);
+ inst.instruction |= inst.operands[0].reg << 12;
+ encode_thumb32_addr_mode (1, /*is_t=*/FALSE, /*is_d=*/FALSE);
+ return;
+ }
+
constraint (inst.operands[0].reg > 7, BAD_HIREG);
+ if (inst.instruction == T_MNEM_ldrsh || inst.instruction == T_MNEM_ldrsb)
+ {
+ /* Only [Rn,Rm] is acceptable. */
+ constraint (inst.operands[1].reg > 7 || inst.operands[1].imm > 7, BAD_HIREG);
+ constraint (!inst.operands[1].isreg || !inst.operands[1].immisreg
+ || inst.operands[1].postind || inst.operands[1].shifted
+ || inst.operands[1].negative,
+ _("Thumb does not support this addressing mode"));
+ inst.instruction = THUMB_OP16 (inst.instruction);
+ goto op16;
+ }
+
+ inst.instruction = THUMB_OP16 (inst.instruction);
if (!inst.operands[1].isreg)
if (move_or_literal_pool (0, /*thumb_p=*/TRUE, /*mode_3=*/FALSE))
return;
@@ -5706,44 +6466,137 @@
if (!inst.operands[1].immisreg)
{
/* Immediate offset. */
- switch (inst.instruction)
- {
- case T_OPCODE_STR_RW: inst.instruction = T_OPCODE_STR_IW; break;
- case T_OPCODE_STR_RH: inst.instruction = T_OPCODE_STR_IH; break;
- case T_OPCODE_STR_RB: inst.instruction = T_OPCODE_STR_IB; break;
- case T_OPCODE_LDR_RW: inst.instruction = T_OPCODE_LDR_IW; break;
- case T_OPCODE_LDR_RH: inst.instruction = T_OPCODE_LDR_IH; break;
- case T_OPCODE_LDR_RB: inst.instruction = T_OPCODE_LDR_IB; break;
- default: abort ();
- }
-
inst.instruction |= inst.operands[0].reg;
inst.instruction |= inst.operands[1].reg << 3;
inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
+ return;
}
- else
+
+ /* Register offset. */
+ constraint (inst.operands[1].imm > 7, BAD_HIREG);
+ constraint (inst.operands[1].negative,
+ _("Thumb does not support this addressing mode"));
+
+ op16:
+ switch (inst.instruction)
{
- /* Register offset. Opcode is already correct. */
- constraint (inst.operands[1].reg > 7
- || inst.operands[1].imm > 7, BAD_HIREG);
- constraint (inst.operands[1].negative,
- _("Thumb does not support this addressing mode"));
- inst.instruction |= inst.operands[0].reg;
- inst.instruction |= inst.operands[1].reg << 3;
- inst.instruction |= inst.operands[1].imm << 6;
+ case T_OPCODE_STR_IW: inst.instruction = T_OPCODE_STR_RW; break;
+ case T_OPCODE_STR_IH: inst.instruction = T_OPCODE_STR_RH; break;
+ case T_OPCODE_STR_IB: inst.instruction = T_OPCODE_STR_RB; break;
+ case T_OPCODE_LDR_IW: inst.instruction = T_OPCODE_LDR_RW; break;
+ case T_OPCODE_LDR_IH: inst.instruction = T_OPCODE_LDR_RH; break;
+ case T_OPCODE_LDR_IB: inst.instruction = T_OPCODE_LDR_RB; break;
+ case 0x5600 /* ldrsb */:
+ case 0x5e00 /* ldrsh */: break;
+ default: abort ();
}
+
+ inst.instruction |= inst.operands[0].reg;
+ inst.instruction |= inst.operands[1].reg << 3;
+ inst.instruction |= inst.operands[1].imm << 6;
}
static void
+do_t_ldstd (void)
+{
+ if (!inst.operands[1].present)
+ {
+ inst.operands[1].reg = inst.operands[0].reg + 1;
+ constraint (inst.operands[0].reg == REG_LR,
+ _("r14 not allowed here"));
+ }
+ inst.instruction |= inst.operands[0].reg << 12;
+ inst.instruction |= inst.operands[1].reg << 8;
+ encode_thumb32_addr_mode (2, /*is_t=*/FALSE, /*is_d=*/TRUE);
+
+}
+
+static void
+do_t_ldstt (void)
+{
+ inst.instruction |= inst.operands[0].reg << 12;
+ encode_thumb32_addr_mode (1, /*is_t=*/TRUE, /*is_d=*/FALSE);
+}
+
+static void
+do_t_mlas (void)
+{
+ inst.instruction |= inst.operands[0].reg << 8;
+ inst.instruction |= inst.operands[1].reg << 16;
+ inst.instruction |= inst.operands[2].reg;
+ inst.instruction |= inst.operands[3].reg << 12;
+}
+
+static void
do_t_mov_cmp (void)
{
+ if (thumb32_mode)
+ {
+ int r0off = (inst.instruction == T_MNEM_mov
+ || inst.instruction == T_MNEM_movs) ? 8 : 16;
+ if (!inst.operands[1].isreg)
+ {
+ /* For an immediate, we always generate a 32-bit opcode;
+ section relaxation will shrink it later if possible. */
+ inst.instruction = THUMB_OP32 (inst.instruction);
+ inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
+ inst.instruction |= inst.operands[0].reg << r0off;
+ inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE;
+ }
+ else if (inst.size_req == 4
+ || inst.operands[1].shifted
+ || (inst.instruction == T_MNEM_movs
+ && (inst.operands[0].reg > 7 || inst.operands[1].reg > 7)))
+ {
+ inst.instruction = THUMB_OP32 (inst.instruction);
+ inst.instruction |= inst.operands[0].reg << r0off;
+ encode_thumb32_shifted_operand (1);
+ }
+ else
+ switch (inst.instruction)
+ {
+ case T_MNEM_mov:
+ inst.instruction = T_OPCODE_MOV_HR;
+ inst.instruction |= (inst.operands[0].reg & 0x8) << 4;
+ inst.instruction |= (inst.operands[0].reg & 0x7);
+ inst.instruction |= inst.operands[1].reg << 3;
+ break;
+
+ case T_MNEM_movs:
+ /* We know we have low registers at this point.
+ Generate ADD Rd, Rs, #0. */
+ inst.instruction = T_OPCODE_ADD_I3;
+ inst.instruction |= inst.operands[0].reg;
+ inst.instruction |= inst.operands[1].reg << 3;
+ break;
+
+ case T_MNEM_cmp:
+ if (inst.operands[0].reg <= 7 && inst.operands[1].reg <= 7)
+ {
+ inst.instruction = T_OPCODE_CMP_LR;
+ inst.instruction |= inst.operands[0].reg;
+ inst.instruction |= inst.operands[1].reg << 3;
+ }
+ else
+ {
+ inst.instruction = T_OPCODE_CMP_HR;
+ inst.instruction |= (inst.operands[0].reg & 0x8) << 4;
+ inst.instruction |= (inst.operands[0].reg & 0x7);
+ inst.instruction |= inst.operands[1].reg << 3;
+ }
+ break;
+ }
+ return;
+ }
+
+ inst.instruction = THUMB_OP16 (inst.instruction);
if (inst.operands[1].isreg)
{
if (inst.operands[0].reg < 8 && inst.operands[1].reg < 8)
{
/* A move of two lowregs is encoded as ADD Rd, Rs, #0
since a MOV instruction produces unpredictable results. */
- if (inst.instruction == T_OPCODE_MOV_HR)
+ if (inst.instruction == T_OPCODE_MOV_I8)
inst.instruction = T_OPCODE_ADD_I3;
else
inst.instruction = T_OPCODE_CMP_LR;
@@ -5752,90 +6605,241 @@
inst.instruction |= inst.operands[1].reg << 3;
}
else
- do_t_cpy ();
+ {
+ if (inst.instruction == T_OPCODE_MOV_I8)
+ inst.instruction = T_OPCODE_MOV_HR;
+ else
+ inst.instruction = T_OPCODE_CMP_HR;
+ do_t_cpy ();
+ }
}
else
{
constraint (inst.operands[0].reg > 7,
_("only lo regs allowed with immediate"));
- if (inst.instruction == T_OPCODE_MOV_HR)
- inst.instruction = T_OPCODE_MOV_I8;
- else
- inst.instruction = T_OPCODE_CMP_I8;
-
inst.instruction |= inst.operands[0].reg << 8;
inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
}
}
static void
-do_t_mul (void)
+do_t_mov16 (void)
{
- constraint (inst.operands[0].reg > 7 || inst.operands[1].reg > 7, BAD_HIREG);
- constraint (inst.operands[2].present
- && inst.operands[0].reg != inst.operands[2].reg,
- _("dest and source2 must be the same register"));
- if (inst.operands[0].reg == inst.operands[1].reg)
- as_tsktsk (_("dest and source must be different in MUL"));
+ inst.instruction |= inst.operands[0].reg << 8;
+ inst.instruction |= (inst.operands[1].imm & 0xf000) << 4;
+ inst.instruction |= (inst.operands[1].imm & 0x0800) << 15;
+ inst.instruction |= (inst.operands[1].imm & 0x0700) << 4;
+ inst.instruction |= (inst.operands[1].imm & 0x00ff);
+}
- inst.instruction |= inst.operands[0].reg;
- inst.instruction |= inst.operands[1].reg << 3;
+static void
+do_t_mvn_tst (void)
+{
+ if (thumb32_mode)
+ {
+ int r0off = (inst.instruction == T_MNEM_mvn
+ || inst.instruction == T_MNEM_mvns) ? 8 : 16;
+ if (!inst.operands[1].isreg)
+ {
+ /* For an immediate, we always generate a 32-bit opcode;
+ section relaxation will shrink it later if possible. */
+ if (inst.instruction < 0xffff)
+ inst.instruction = THUMB_OP32 (inst.instruction);
+ inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
+ inst.instruction |= inst.operands[0].reg << r0off;
+ inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE;
+ }
+ else
+ {
+ /* See if we can do this with a 16-bit instruction. */
+ if (inst.instruction < 0xffff
+ && THUMB_SETS_FLAGS (inst.instruction)
+ && !inst.operands[1].shifted
+ && inst.operands[0].reg <= 7
+ && inst.operands[1].reg <= 7
+ && inst.size_req != 4)
+ {
+ inst.instruction = THUMB_OP16 (inst.instruction);
+ inst.instruction |= inst.operands[0].reg;
+ inst.instruction |= inst.operands[1].reg << 3;
+ }
+ else
+ {
+ constraint (inst.operands[1].shifted
+ && inst.operands[1].immisreg,
+ _("shift must be constant"));
+ if (inst.instruction < 0xffff)
+ inst.instruction = THUMB_OP32 (inst.instruction);
+ inst.instruction |= inst.operands[0].reg << r0off;
+ encode_thumb32_shifted_operand (1);
+ }
+ }
+ }
+ else
+ {
+ constraint (inst.instruction > 0xffff
+ || inst.instruction == T_MNEM_mvns, BAD_THUMB32);
+ constraint (!inst.operands[1].isreg || inst.operands[1].shifted,
+ _("unshifted register required"));
+ constraint (inst.operands[0].reg > 7 || inst.operands[1].reg > 7,
+ BAD_HIREG);
+
+ inst.instruction = THUMB_OP16 (inst.instruction);
+ inst.instruction |= inst.operands[0].reg;
+ inst.instruction |= inst.operands[1].reg << 3;
+ }
}
static void
-do_t_nop (void)
+do_t_mrs (void)
{
- constraint (inst.operands[0].present,
- _("Thumb does not support NOP with hints"));
+ /* mrs only accepts CPSR/SPSR/CPSR_all/SPSR_all. */
+ constraint ((inst.operands[1].imm & (PSR_c|PSR_x|PSR_s|PSR_f))
+ != (PSR_c|PSR_f),
+ _("'CPSR' or 'SPSR' expected"));
+ inst.instruction |= inst.operands[0].reg << 8;
+ inst.instruction |= (inst.operands[1].imm & SPSR_BIT) >> 2;
}
static void
-do_t_setend (void)
+do_t_msr (void)
{
- if (inst.operands[0].imm)
- inst.instruction |= 0x8;
+ constraint (!inst.operands[1].isreg,
+ _("Thumb encoding does not support an immediate here"));
+ inst.instruction |= (inst.operands[0].imm & SPSR_BIT) >> 2;
+ inst.instruction |= (inst.operands[0].imm & ~SPSR_BIT) >> 8;
+ inst.instruction |= inst.operands[1].reg << 16;
}
static void
-do_t_shift (void)
+do_t_mul (void)
{
- unsigned int Rs = (inst.operands[1].present
- ? inst.operands[1].reg
- : inst.operands[0].reg);
+ if (!inst.operands[2].present)
+ inst.operands[2].reg = inst.operands[0].reg;
- constraint (inst.operands[0].reg > 7 || Rs > 7, BAD_HIREG);
+ /* There is no 32-bit MULS and no 16-bit MUL. */
+ if (thumb32_mode && inst.instruction == T_MNEM_mul)
+ {
+ inst.instruction = THUMB_OP32 (inst.instruction);
+ inst.instruction |= inst.operands[0].reg << 8;
+ inst.instruction |= inst.operands[1].reg << 16;
+ inst.instruction |= inst.operands[2].reg << 0;
+ }
+ else
+ {
+ constraint (!thumb32_mode
+ && inst.instruction == T_MNEM_muls, BAD_THUMB32);
+ constraint (inst.operands[0].reg > 7 || inst.operands[1].reg > 7, BAD_HIREG);
+ constraint (inst.operands[0].reg != inst.operands[2].reg,
+ _("dest and source2 must be the same register"));
+ if (inst.operands[0].reg == inst.operands[1].reg)
+ as_tsktsk (_("dest and source must be different in MUL"));
- if (inst.operands[2].isreg) /* Rd, {Rs,} Rn */
+ inst.instruction = THUMB_OP16 (inst.instruction);
+ inst.instruction |= inst.operands[0].reg;
+ inst.instruction |= inst.operands[1].reg << 3;
+ }
+}
+
+static void
+do_t_mull (void)
+{
+ inst.instruction |= inst.operands[0].reg << 12;
+ inst.instruction |= inst.operands[1].reg << 8;
+ inst.instruction |= inst.operands[2].reg << 16;
+ inst.instruction |= inst.operands[3].reg;
+
+ if (inst.operands[0].reg == inst.operands[1].reg)
+ as_tsktsk (_("rdhi and rdlo must be different"));
+}
+
+static void
+do_t_nop (void)
+{
+ if (thumb32_mode)
{
- constraint (inst.operands[2].reg > 7, BAD_HIREG);
- constraint (inst.operands[0].reg != Rs,
- _("source1 and dest must be same register"));
+ if (inst.size_req == 4 || inst.operands[0].imm > 15)
+ {
+ inst.instruction = THUMB_OP32 (inst.instruction);
+ inst.instruction |= inst.operands[0].imm;
+ }
+ else
+ {
+ inst.instruction = THUMB_OP16 (inst.instruction);
+ inst.instruction |= inst.operands[0].imm << 4;
+ }
+ }
+ else
+ {
+ constraint (inst.operands[0].present,
+ _("Thumb does not support NOP with hints"));
+ inst.instruction = 0x46c0;
+ }
+}
+
+static void
+do_t_neg (void)
+{
+ if (thumb32_mode)
+ {
+ if (inst.operands[0].reg > 7 || inst.operands[1].reg > 7
+ || !THUMB_SETS_FLAGS (inst.instruction)
+ || inst.size_req == 4)
+ {
+ inst.instruction = THUMB_OP32 (inst.instruction);
+ inst.instruction |= inst.operands[0].reg << 8;
+ inst.instruction |= inst.operands[1].reg << 16;
+ }
+ else
+ {
+ inst.instruction = THUMB_OP16 (inst.instruction);
+ inst.instruction |= inst.operands[0].reg;
+ inst.instruction |= inst.operands[1].reg << 3;
+ }
+ }
+ else
+ {
+ constraint (inst.operands[0].reg > 7 || inst.operands[1].reg > 7,
+ BAD_HIREG);
+ constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
+
+ inst.instruction = THUMB_OP16 (inst.instruction);
inst.instruction |= inst.operands[0].reg;
- inst.instruction |= inst.operands[2].reg << 3;
- return;
+ inst.instruction |= inst.operands[1].reg << 3;
}
+}
- /* If we get here, we are doing a shift by an immediate. inst.operands[0].reg
- and Rs are the registers, and inst.reloc is the immediate. */
- switch (inst.instruction)
+static void
+do_t_pkhbt (void)
+{
+ inst.instruction |= inst.operands[0].reg << 8;
+ inst.instruction |= inst.operands[1].reg << 16;
+ inst.instruction |= inst.operands[2].reg;
+ if (inst.operands[3].present)
{
- case T_OPCODE_ASR_R: inst.instruction = T_OPCODE_ASR_I; break;
- case T_OPCODE_LSL_R: inst.instruction = T_OPCODE_LSL_I; break;
- case T_OPCODE_LSR_R: inst.instruction = T_OPCODE_LSR_I; break;
- case T_OPCODE_ROR_R: inst.error = _("ror #imm not supported"); return;
- default: abort ();
+ unsigned int val = inst.reloc.exp.X_add_number;
+ constraint (inst.reloc.exp.X_op != O_constant,
+ _("expression too complex"));
+ inst.instruction |= (val & 0x1c) << 10;
+ inst.instruction |= (val & 0x03) << 6;
}
- inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
- inst.instruction |= inst.operands[0].reg | (Rs << 3);
}
static void
-do_t_swi (void)
+do_t_pkhtb (void)
{
- inst.reloc.type = BFD_RELOC_ARM_SWI;
+ if (!inst.operands[3].present)
+ inst.instruction &= ~0x00000020;
+ do_t_pkhbt ();
}
static void
+do_t_pld (void)
+{
+ encode_thumb32_addr_mode (0, /*is_t=*/FALSE, /*is_d=*/FALSE);
+}
+
+static void
do_t_push_pop (void)
{
constraint (inst.operands[0].writeback,
@@ -5843,25 +6847,400 @@
constraint (inst.reloc.type != BFD_RELOC_UNUSED,
_("expression too complex"));
- if (inst.operands[0].imm & ~0xff)
+ if ((inst.operands[0].imm & ~0xff) == 0)
+ inst.instruction = THUMB_OP16 (inst.instruction);
+ else if ((inst.instruction == T_MNEM_push
+ && (inst.operands[0].imm & ~0xff) == 1 << REG_LR)
+ || (inst.instruction == T_MNEM_pop
+ && (inst.operands[0].imm & ~0xff) == 1 << REG_PC))
{
- if ((inst.instruction == T_OPCODE_PUSH
- && (inst.operands[0].imm & ~0xff) == 1 << REG_LR)
- || (inst.instruction == T_OPCODE_POP
- && (inst.operands[0].imm & ~0xff) == 1 << REG_PC))
+ inst.instruction = THUMB_OP16 (inst.instruction);
+ inst.instruction |= THUMB_PP_PC_LR;
+ inst.operands[0].imm &= 0xff;
+ }
+ else if (thumb32_mode)
+ {
+ if (inst.operands[1].imm & (1 << 13))
+ as_warn (_("SP should not be in register list"));
+ if (inst.instruction == T_MNEM_push)
{
- inst.instruction |= THUMB_PP_PC_LR;
- inst.operands[0].imm &= 0xff;
+ if (inst.operands[1].imm & (1 << 15))
+ as_warn (_("PC should not be in register list"));
}
else
{
- inst.error = _("invalid register list to push/pop instruction");
- return;
+ if (inst.operands[1].imm & (1 << 14)
+ && inst.operands[1].imm & (1 << 15))
+ as_warn (_("LR and PC should not both be in register list"));
}
+
+ inst.instruction = THUMB_OP32 (inst.instruction);
}
+ else
+ {
+ inst.error = _("invalid register list to push/pop instruction");
+ return;
+ }
inst.instruction |= inst.operands[0].imm;
}
+
+static void
+do_t_qadd (void)
+{
+ inst.instruction |= inst.operands[0].reg << 8;
+ inst.instruction |= inst.operands[1].reg << 16;
+ inst.instruction |= inst.operands[2].reg;
+}
+
+static void
+do_t_rbit (void)
+{
+ inst.instruction |= inst.operands[0].reg << 8;
+ inst.instruction |= inst.operands[1].reg << 16;
+}
+
+static void
+do_t_rev (void)
+{
+ if (inst.operands[0].reg <= 7 && inst.operands[1].reg <= 7
+ && inst.size_req != 4)
+ {
+ inst.instruction = THUMB_OP16 (inst.instruction);
+ inst.instruction |= inst.operands[0].reg;
+ inst.instruction |= inst.operands[1].reg << 3;
+ }
+ else if (thumb32_mode)
+ {
+ inst.instruction = THUMB_OP32 (inst.instruction);
+ inst.instruction |= inst.operands[0].reg << 8;
+ inst.instruction |= inst.operands[1].reg << 16;
+ inst.instruction |= inst.operands[1].reg;
+ }
+ else
+ inst.error = BAD_HIREG;
+}
+
+static void
+do_t_rsb (void)
+{
+ int Rd, Rs;
+
+ Rd = inst.operands[0].reg;
+ Rs = (inst.operands[1].present
+ ? inst.operands[1].reg /* Rd, Rs, foo */
+ : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
+
+ inst.instruction |= Rd << 8;
+ inst.instruction |= Rs << 16;
+ if (!inst.operands[2].isreg)
+ {
+ inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
+ inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE;
+ }
+ else
+ encode_thumb32_shifted_operand (2);
+}
+
+static void
+do_t_setend (void)
+{
+ if (inst.operands[0].imm)
+ inst.instruction |= 0x8;
+}
+
+static void
+do_t_shift (void)
+{
+ if (!inst.operands[1].present)
+ inst.operands[1].reg = inst.operands[0].reg;
+
+ if (thumb32_mode)
+ {
+ if (inst.operands[0].reg > 7
+ || inst.operands[1].reg > 7
+ || !THUMB_SETS_FLAGS (inst.instruction)
+ || (!inst.operands[2].isreg && inst.instruction == T_MNEM_rors)
+ || (inst.operands[2].isreg && inst.operands[1].reg != inst.operands[0].reg)
+ || inst.size_req == 4)
+ {
+ if (inst.operands[2].isreg)
+ {
+ inst.instruction = THUMB_OP32 (inst.instruction);
+ inst.instruction |= inst.operands[0].reg << 8;
+ inst.instruction |= inst.operands[1].reg << 16;
+ inst.instruction |= inst.operands[2].reg;
+ }
+ else
+ {
+ inst.operands[1].shifted = 1;
+ switch (inst.instruction)
+ {
+ case T_MNEM_asr:
+ case T_MNEM_asrs: inst.operands[1].shift_kind = SHIFT_ASR; break;
+ case T_MNEM_lsl:
+ case T_MNEM_lsls: inst.operands[1].shift_kind = SHIFT_LSL; break;
+ case T_MNEM_lsr:
+ case T_MNEM_lsrs: inst.operands[1].shift_kind = SHIFT_LSR; break;
+ case T_MNEM_ror:
+ case T_MNEM_rors: inst.operands[1].shift_kind = SHIFT_ROR; break;
+ default: abort ();
+ }
+
+ inst.instruction = THUMB_OP32 (THUMB_SETS_FLAGS (inst.instruction)
+ ? T_MNEM_movs : T_MNEM_mov);
+ inst.instruction |= inst.operands[0].reg << 8;
+ encode_thumb32_shifted_operand (1);
+ /* Prevent the incorrect generation of an ARM_IMMEDIATE fixup. */
+ inst.reloc.type = BFD_RELOC_UNUSED;
+ }
+ }
+ else
+ {
+ if (inst.operands[2].isreg)
+ {
+ switch (inst.instruction)
+ {
+ case T_MNEM_asrs: inst.instruction = T_OPCODE_ASR_R; break;
+ case T_MNEM_lsls: inst.instruction = T_OPCODE_LSL_R; break;
+ case T_MNEM_lsrs: inst.instruction = T_OPCODE_LSR_R; break;
+ case T_MNEM_rors: inst.instruction = T_OPCODE_ROR_R; break;
+ default: abort ();
+ }
+
+ inst.instruction |= inst.operands[0].reg;
+ inst.instruction |= inst.operands[2].reg << 3;
+ }
+ else
+ {
+ switch (inst.instruction)
+ {
+ case T_MNEM_asrs: inst.instruction = T_OPCODE_ASR_I; break;
+ case T_MNEM_lsls: inst.instruction = T_OPCODE_LSL_I; break;
+ case T_MNEM_lsrs: inst.instruction = T_OPCODE_LSR_I; break;
+ default: abort ();
+ }
+ inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
+ inst.instruction |= inst.operands[0].reg;
+ inst.instruction |= inst.operands[1].reg << 3;
+ }
+ }
+ }
+ else
+ {
+ constraint (inst.operands[0].reg > 7
+ || inst.operands[1].reg > 7, BAD_HIREG);
+ constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
+
+ if (inst.operands[2].isreg) /* Rd, {Rs,} Rn */
+ {
+ constraint (inst.operands[2].reg > 7, BAD_HIREG);
+ constraint (inst.operands[0].reg != inst.operands[1].reg,
+ _("source1 and dest must be same register"));
+
+ switch (inst.instruction)
+ {
+ case T_MNEM_asr: inst.instruction = T_OPCODE_ASR_R; break;
+ case T_MNEM_lsl: inst.instruction = T_OPCODE_LSL_R; break;
+ case T_MNEM_lsr: inst.instruction = T_OPCODE_LSR_R; break;
+ case T_MNEM_ror: inst.instruction = T_OPCODE_ROR_R; break;
+ default: abort ();
+ }
+
+ inst.instruction |= inst.operands[0].reg;
+ inst.instruction |= inst.operands[2].reg << 3;
+ }
+ else
+ {
+ switch (inst.instruction)
+ {
+ case T_MNEM_asr: inst.instruction = T_OPCODE_ASR_I; break;
+ case T_MNEM_lsl: inst.instruction = T_OPCODE_LSL_I; break;
+ case T_MNEM_lsr: inst.instruction = T_OPCODE_LSR_I; break;
+ case T_MNEM_ror: inst.error = _("ror #imm not supported"); return;
+ default: abort ();
+ }
+ inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
+ inst.instruction |= inst.operands[0].reg;
+ inst.instruction |= inst.operands[1].reg << 3;
+ }
+ }
+}
+
+static void
+do_t_smi (void)
+{
+ unsigned int value = inst.reloc.exp.X_add_number;
+ constraint (inst.reloc.exp.X_op != O_constant,
+ _("expression too complex"));
+ inst.reloc.type = BFD_RELOC_UNUSED;
+ inst.instruction |= (value & 0xf000) >> 12;
+ inst.instruction |= (value & 0x0ff0);
+ inst.instruction |= (value & 0x000f) << 16;
+}
+
+static void
+do_t_smla (void)
+{
+ inst.instruction |= inst.operands[0].reg << 8;
+ inst.instruction |= inst.operands[1].reg << 16;
+ inst.instruction |= inst.operands[2].reg;
+ inst.instruction |= inst.operands[3].reg << 12;
+}
+
+static void
+do_t_smlal (void)
+{
+ inst.instruction |= inst.operands[0].reg << 12;
+ inst.instruction |= inst.operands[1].reg << 8;
+ inst.instruction |= inst.operands[2].reg << 16;
+ inst.instruction |= inst.operands[3].reg;
+}
+
+static void
+do_t_smul (void)
+{
+ inst.instruction |= inst.operands[0].reg << 8;
+ inst.instruction |= inst.operands[1].reg << 16;
+ inst.instruction |= inst.operands[2].reg;
+}
+
+static void
+do_t_ssat (void)
+{
+ inst.instruction |= inst.operands[0].reg << 8;
+ inst.instruction |= inst.operands[1].imm - 1;
+ inst.instruction |= inst.operands[2].reg << 16;
+
+ if (inst.operands[3].present)
+ {
+ constraint (inst.reloc.exp.X_op != O_constant,
+ _("expression too complex"));
+
+ if (inst.reloc.exp.X_add_number != 0)
+ {
+ if (inst.operands[3].shift_kind == SHIFT_ASR)
+ inst.instruction |= 0x00200000; /* sh bit */
+ inst.instruction |= (inst.reloc.exp.X_add_number & 0x1c) << 10;
+ inst.instruction |= (inst.reloc.exp.X_add_number & 0x03) << 6;
+ }
+ inst.reloc.type = BFD_RELOC_UNUSED;
+ }
+}
+
+static void
+do_t_ssat16 (void)
+{
+ inst.instruction |= inst.operands[0].reg << 8;
+ inst.instruction |= inst.operands[1].imm - 1;
+ inst.instruction |= inst.operands[2].reg << 16;
+}
+
+static void
+do_t_strex (void)
+{
+ constraint (!inst.operands[2].isreg || !inst.operands[2].preind
+ || inst.operands[2].postind || inst.operands[2].writeback
+ || inst.operands[2].immisreg || inst.operands[2].shifted
+ || inst.operands[2].negative,
+ _("instruction does not accept this addressing mode"));
+
+ inst.instruction |= inst.operands[0].reg << 8;
+ inst.instruction |= inst.operands[1].reg << 12;
+ inst.instruction |= inst.operands[2].reg << 16;
+ inst.reloc.type = BFD_RELOC_ARM_T32_OFFSET_U8;
+}
+
+static void
+do_t_strexd (void)
+{
+ if (!inst.operands[2].present)
+ inst.operands[2].reg = inst.operands[1].reg + 1;
+
+ constraint (inst.operands[0].reg == inst.operands[1].reg
+ || inst.operands[0].reg == inst.operands[2].reg
+ || inst.operands[0].reg == inst.operands[3].reg
+ || inst.operands[1].reg == inst.operands[2].reg,
+ BAD_OVERLAP);
+
+ inst.instruction |= inst.operands[0].reg;
+ inst.instruction |= inst.operands[1].reg << 12;
+ inst.instruction |= inst.operands[2].reg << 8;
+ inst.instruction |= inst.operands[3].reg << 16;
+}
+
+static void
+do_t_sxtah (void)
+{
+ inst.instruction |= inst.operands[0].reg << 8;
+ inst.instruction |= inst.operands[1].reg << 16;
+ inst.instruction |= inst.operands[2].reg;
+ inst.instruction |= inst.operands[3].imm << 4;
+}
+
+static void
+do_t_sxth (void)
+{
+ if (inst.instruction <= 0xffff && inst.size_req != 4
+ && inst.operands[0].reg <= 7 && inst.operands[1].reg <= 7
+ && (!inst.operands[2].present || inst.operands[2].imm == 0))
+ {
+ inst.instruction = THUMB_OP16 (inst.instruction);
+ inst.instruction |= inst.operands[0].reg;
+ inst.instruction |= inst.operands[1].reg << 3;
+ }
+ else if (thumb32_mode)
+ {
+ if (inst.instruction <= 0xffff)
+ inst.instruction = THUMB_OP32 (inst.instruction);
+ inst.instruction |= inst.operands[0].reg << 8;
+ inst.instruction |= inst.operands[1].reg;
+ inst.instruction |= inst.operands[2].imm << 4;
+ }
+ else
+ {
+ constraint (inst.operands[2].present && inst.operands[2].imm != 0,
+ _("Thumb encoding does not support rotation"));
+ constraint (1, BAD_HIREG);
+ }
+}
+
+static void
+do_t_swi (void)
+{
+ inst.reloc.type = BFD_RELOC_ARM_SWI;
+}
+
+static void
+do_t_usat (void)
+{
+ inst.instruction |= inst.operands[0].reg << 8;
+ inst.instruction |= inst.operands[1].imm;
+ inst.instruction |= inst.operands[2].reg << 16;
+
+ if (inst.operands[3].present)
+ {
+ constraint (inst.reloc.exp.X_op != O_constant,
+ _("expression too complex"));
+ if (inst.reloc.exp.X_add_number != 0)
+ {
+ if (inst.operands[3].shift_kind == SHIFT_ASR)
+ inst.instruction |= 0x00200000; /* sh bit */
+
+ inst.instruction |= (inst.reloc.exp.X_add_number & 0x1c) << 10;
+ inst.instruction |= (inst.reloc.exp.X_add_number & 0x03) << 6;
+ }
+ inst.reloc.type = BFD_RELOC_UNUSED;
+ }
+}
+
+static void
+do_t_usat16 (void)
+{
+ inst.instruction |= inst.operands[0].reg << 8;
+ inst.instruction |= inst.operands[1].imm;
+ inst.instruction |= inst.operands[2].reg << 16;
+}
/* Overall per-instruction processing. */
@@ -5960,7 +7339,7 @@
/* Scan up to the end of the op-code, which must end in white space or
end of string. */
for (p = str; *p != '\0'; p++)
- if (*p == ' ')
+ if (*p == ' ' || (thumb32_mode && *p == '.'))
break;
if (p == str)
@@ -5982,9 +7361,35 @@
}
mapping_state (MAP_THUMB);
inst.instruction = opcode->tvalue;
- inst.size = (opcode->tvalue > 0xffff ? 4 : 2);
+
+ /* Check for .W or .N suffix. */
+ if (thumb32_mode && p[0] == '.')
+ {
+ if (p[1] == 'w')
+ inst.size_req = 4;
+ else if (p[1] == 'n')
+ inst.size_req = 2;
+ else
+ {
+ as_bad (_("unrecognized width suffix -- `%s'"), str);
+ return;
+ }
+ p += 2;
+ }
+
if (!parse_operands (p, opcode->operands))
opcode->tencode ();
+
+ if (!inst.error)
+ {
+ assert (inst.instruction < 0xe800 || inst.instruction > 0xffff);
+ inst.size = (inst.instruction > 0xffff ? 4 : 2);
+ if (inst.size_req && inst.size_req != inst.size)
+ {
+ as_bad (_("cannot honor width suffix -- `%s'"), str);
+ return;
+ }
+ }
}
else
{
@@ -6004,17 +7409,7 @@
output_inst (str);
return;
}
- else
- {
- opcode = hash_find_n (arm_ops_hsh, str, p - str);
- if (opcode)
- {
- output_inst (str);
- return;
- }
- }
-
/* It wasn't an instruction, but it might be a register alias of the form
alias .req reg. */
if (create_register_alias (str, p))
@@ -6356,8 +7751,8 @@
/* These macros assemble the conditional variants of each instruction
from its bare form. */
-#define TCE(mnem, op, top, nops, ops, ae, te) \
- { #mnem, OPS##nops ops, 0xe##op, 0x##top, ARM_VARIANT, THUMB_VARIANT, do_##ae, do_##te }, \
+#define TxCE(mnem, op, top, nops, ops, ae, te) \
+ { #mnem, OPS##nops ops, 0xe##op, top, ARM_VARIANT, THUMB_VARIANT, do_##ae, do_##te }, \
{ #mnem "eq", OPS##nops ops, 0x0##op, 0, ARM_VARIANT, 0, do_##ae, 0 }, \
{ #mnem "ne", OPS##nops ops, 0x1##op, 0, ARM_VARIANT, 0, do_##ae, 0 }, \
{ #mnem "cs", OPS##nops ops, 0x2##op, 0, ARM_VARIANT, 0, do_##ae, 0 }, \
@@ -6377,6 +7772,11 @@
{ #mnem "le", OPS##nops ops, 0xd##op, 0, ARM_VARIANT, 0, do_##ae, 0 }, \
{ #mnem "al", OPS##nops ops, 0xe##op, 0, ARM_VARIANT, 0, do_##ae, 0 }
+#define TCE(mnem, aop, top, nops, ops, ae, te) \
+ TxCE(mnem, aop, 0x##top, nops, ops, ae, te)
+#define tCE(mnem, aop, top, nops, ops, ae, te) \
+ TxCE(mnem, aop, T_MNEM_##top, nops, ops, ae, te)
+
#define TCC(mnem, op, tu, t1, t2, nops, ops, ae, te) \
{ #mnem, OPS##nops ops,0xe##op,0x##tu, ARM_VARIANT,THUMB_VARIANT,do_##ae,do_##te }, \
{ #mnem "eq", OPS##nops ops,0x0##op,0x##t1##0##t2,ARM_VARIANT,THUMB_VARIANT,do_##ae,do_##te }, \
@@ -6398,8 +7798,8 @@
{ #mnem "le", OPS##nops ops,0xd##op,0x##t1##d##t2,ARM_VARIANT,THUMB_VARIANT,do_##ae,do_##te }, \
{ #mnem "al", OPS##nops ops,0xe##op,0x##t1##e##t2,ARM_VARIANT,THUMB_VARIANT,do_##ae,do_##te }
-#define TCM(m1, m2, op, top, nops, ops, ae, te) \
- { #m1 #m2, OPS##nops ops, 0xe##op, 0x##top, ARM_VARIANT, THUMB_VARIANT, do_##ae, do_##te }, \
+#define TxCM(m1, m2, op, top, nops, ops, ae, te) \
+ { #m1 #m2, OPS##nops ops, 0xe##op, top, ARM_VARIANT, THUMB_VARIANT, do_##ae, do_##te }, \
{ #m1 "eq" #m2, OPS##nops ops, 0x0##op, 0, ARM_VARIANT, 0, do_##ae, 0 }, \
{ #m1 "ne" #m2, OPS##nops ops, 0x1##op, 0, ARM_VARIANT, 0, do_##ae, 0 }, \
{ #m1 "cs" #m2, OPS##nops ops, 0x2##op, 0, ARM_VARIANT, 0, do_##ae, 0 }, \
@@ -6419,6 +7819,11 @@
{ #m1 "le" #m2, OPS##nops ops, 0xd##op, 0, ARM_VARIANT, 0, do_##ae, 0 }, \
{ #m1 "al" #m2, OPS##nops ops, 0xe##op, 0, ARM_VARIANT, 0, do_##ae, 0 }
+#define TCM(m1,m2, aop, top, nops, ops, ae, te) \
+ TxCM(m1,m2, aop, 0x##top, nops, ops, ae, te)
+#define tCM(m1,m2, aop, top, nops, ops, ae, te) \
+ TxCM(m1,m2, aop, T_MNEM_##top, nops, ops, ae, te)
+
#define TUE(mnem, op, top, nops, ops, ae, te) \
{ #mnem, OPS##nops ops, 0xe##op, 0x##top, ARM_VARIANT, THUMB_VARIANT, do_##ae, do_##te }
@@ -6440,73 +7845,52 @@
{
#define ARM_VARIANT ARM_EXT_V1 /* Core ARM Instructions. */
#define THUMB_VARIANT ARM_EXT_V4T
- TCE(and, 0000000, 4000, 3, (RR, oRR, SH), arit, t_arit3),
- CM(and,s, 0100000, 3, (RR, oRR, SH), arit),
- TCE(eor, 0200000, 4040, 3, (RR, oRR, SH), arit, t_arit3),
- CM(eor,s, 0300000, 3, (RR, oRR, SH), arit),
- TCE(sub, 0400000, 8000, 3, (RR, oRR, SH), arit, t_add_sub),
- CM(sub,s, 0500000, 3, (RR, oRR, SH), arit),
- CE(rsb, 0600000, 3, (RR, oRR, SH), arit),
- CM(rsb,s, 0700000, 3, (RR, oRR, SH), arit),
- TCE(add, 0800000, 0000, 3, (RR, oRR, SH), arit, t_add_sub),
- CM(add,s, 0900000, 3, (RR, oRR, SH), arit),
- TCE(adc, 0a00000, 4140, 3, (RR, oRR, SH), arit, t_arit3),
- CM(adc,s, 0b00000, 3, (RR, oRR, SH), arit),
- TCE(sbc, 0c00000, 4180, 3, (RR, oRR, SH), arit, t_arit3),
- CM(sbc,s, 0d00000, 3, (RR, oRR, SH), arit),
- CE(rsc, 0e00000, 3, (RR, oRR, SH), arit),
- CM(rsc,s, 0f00000, 3, (RR, oRR, SH), arit),
- TCE(orr, 1800000, 4300, 3, (RR, oRR, SH), arit, t_arit3),
- CM(orr,s, 1900000, 3, (RR, oRR, SH), arit),
- TCE(bic, 1c00000, 4380, 3, (RR, oRR, SH), arit, t_arit3),
- CM(bic,s, 1d00000, 3, (RR, oRR, SH), arit),
+ tCE(and, 0000000, and, 3, (RR, oRR, SH), arit, t_arit3c),
+ tCM(and,s, 0100000, ands, 3, (RR, oRR, SH), arit, t_arit3c),
+ tCE(eor, 0200000, eor, 3, (RR, oRR, SH), arit, t_arit3c),
+ tCM(eor,s, 0300000, eors, 3, (RR, oRR, SH), arit, t_arit3c),
+ tCE(sub, 0400000, sub, 3, (RR, oRR, SH), arit, t_add_sub),
+ tCM(sub,s, 0500000, subs, 3, (RR, oRR, SH), arit, t_add_sub),
+ tCE(add, 0800000, add, 3, (RR, oRR, SH), arit, t_add_sub),
+ tCM(add,s, 0900000, adds, 3, (RR, oRR, SH), arit, t_add_sub),
+ tCE(adc, 0a00000, adc, 3, (RR, oRR, SH), arit, t_arit3c),
+ tCM(adc,s, 0b00000, adcs, 3, (RR, oRR, SH), arit, t_arit3c),
+ tCE(sbc, 0c00000, sbc, 3, (RR, oRR, SH), arit, t_arit3),
+ tCM(sbc,s, 0d00000, sbcs, 3, (RR, oRR, SH), arit, t_arit3),
+ tCE(orr, 1800000, orr, 3, (RR, oRR, SH), arit, t_arit3c),
+ tCM(orr,s, 1900000, orrs, 3, (RR, oRR, SH), arit, t_arit3c),
+ tCE(bic, 1c00000, bic, 3, (RR, oRR, SH), arit, t_arit3),
+ tCM(bic,s, 1d00000, bics, 3, (RR, oRR, SH), arit, t_arit3),
- TCE(tst, 1100000, 4200, 2, (RR, SH), cmp, t_arit),
- CM(tst,s, 1100000, 2, (RR, SH), cmp),
- CM(tst,p, 110f000, 2, (RR, SH), cmp),
- CE(teq, 1300000, 2, (RR, SH), cmp),
- CM(teq,s, 1300000, 2, (RR, SH), cmp),
- CM(teq,p, 130f000, 2, (RR, SH), cmp),
- TCE(cmp, 1500000, 4500, 2, (RR, SH), cmp, t_mov_cmp),
- CM(cmp,s, 1500000, 2, (RR, SH), cmp),
- CM(cmp,p, 150f000, 2, (RR, SH), cmp),
- TCE(cmn, 1700000, 42c0, 2, (RR, SH), cmp, t_arit),
- CM(cmn,s, 1700000, 2, (RR, SH), cmp),
- CM(cmn,p, 170f000, 2, (RR, SH), cmp),
+ /* The p-variants of tst/cmp/cmn/teq (below) are the pre-V6 mechanism
+ for setting PSR flag bits. They are obsolete in V6 and do not
+ have Thumb equivalents. */
+ tCE(tst, 1100000, tst, 2, (RR, SH), cmp, t_mvn_tst),
+ tCM(tst,s, 1100000, tst, 2, (RR, SH), cmp, t_mvn_tst),
+ CM(tst,p, 110f000, 2, (RR, SH), cmp),
+ tCE(cmp, 1500000, cmp, 2, (RR, SH), cmp, t_mov_cmp),
+ tCM(cmp,s, 1500000, cmp, 2, (RR, SH), cmp, t_mov_cmp),
+ CM(cmp,p, 150f000, 2, (RR, SH), cmp),
+ tCE(cmn, 1700000, cmn, 2, (RR, SH), cmp, t_mvn_tst),
+ tCM(cmn,s, 1700000, cmn, 2, (RR, SH), cmp, t_mvn_tst),
+ CM(cmn,p, 170f000, 2, (RR, SH), cmp),
- TCE(mov, 1a00000, 4600, 2, (RR, SH), mov, t_mov_cmp),
- CM(mov,s, 1b00000, 2, (RR, SH), mov),
- TCE(mvn, 1e00000, 43c0, 2, (RR, SH), mov, t_arit),
- CM(mvn,s, 1f00000, 2, (RR, SH), mov),
+ tCE(mov, 1a00000, mov, 2, (RR, SH), mov, t_mov_cmp),
+ tCM(mov,s, 1b00000, movs, 2, (RR, SH), mov, t_mov_cmp),
+ tCE(mvn, 1e00000, mvn, 2, (RR, SH), mov, t_mvn_tst),
+ tCM(mvn,s, 1f00000, mvns, 2, (RR, SH), mov, t_mvn_tst),
- TCE(ldr, 4100000, 5800, 2, (RR, ADDR), ldst, t_ldst),
- TCM(ldr,b, 4500000, 5c00, 2, (RR, ADDR), ldst, t_ldst),
- CM(ldr,t, 4300000, 2, (RR, ADDR), ldstt),
- CM(ldr,bt, 4700000, 2, (RR, ADDR), ldstt),
- TCE(str, 4000000, 5000, 2, (RR, ADDR), ldst, t_ldst),
- TCM(str,b, 4400000, 5400, 2, (RR, ADDR), ldst, t_ldst),
- CM(str,t, 4200000, 2, (RR, ADDR), ldstt),
- CM(str,bt, 4600000, 2, (RR, ADDR), ldstt),
+ tCE(ldr, 4100000, ldr, 2, (RR, ADDR), ldst, t_ldst),
+ tCM(ldr,b, 4500000, ldrb, 2, (RR, ADDR), ldst, t_ldst),
+ tCE(str, 4000000, str, 2, (RR, ADDR), ldst, t_ldst),
+ tCM(str,b, 4400000, strb, 2, (RR, ADDR), ldst, t_ldst),
- TCM(stm,ia, 8800000, c000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
- CM(stm,ib, 9800000, 2, (RRw, REGLST), ldmstm),
- CM(stm,da, 8000000, 2, (RRw, REGLST), ldmstm),
- CM(stm,db, 9000000, 2, (RRw, REGLST), ldmstm),
- CM(stm,fd, 9000000, 2, (RRw, REGLST), ldmstm),
- CM(stm,fa, 9800000, 2, (RRw, REGLST), ldmstm),
- CM(stm,ea, 8800000, 2, (RRw, REGLST), ldmstm),
- CM(stm,ed, 8000000, 2, (RRw, REGLST), ldmstm),
+ tCM(stm,ia, 8800000, stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
+ tCM(stm,ea, 8800000, stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
+ tCM(ldm,ia, 8900000, ldmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
+ tCM(ldm,fd, 8900000, ldmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
- TCM(ldm,ia, 8900000, c800, 2, (RRw, REGLST), ldmstm, t_ldmstm),
- CM(ldm,ib, 9900000, 2, (RRw, REGLST), ldmstm),
- CM(ldm,da, 8100000, 2, (RRw, REGLST), ldmstm),
- CM(ldm,db, 9100000, 2, (RRw, REGLST), ldmstm),
- CM(ldm,fd, 8900000, 2, (RRw, REGLST), ldmstm),
- CM(ldm,fa, 8100000, 2, (RRw, REGLST), ldmstm),
- CM(ldm,ea, 9100000, 2, (RRw, REGLST), ldmstm),
- CM(ldm,ed, 9900000, 2, (RRw, REGLST), ldmstm),
-
- TCE(swi, f000000, df00, 1, (EXPi), swi, t_swi),
+ TCE(swi, f000000, df00, 1, (EXPi), swi, t_swi),
#ifdef TE_WINCE
/* XXX This is the wrong place to do this. Think multi-arch. */
TCC(b, a000000, e7fe, d,fe, 1, (EXPr), branch, t_branch),
@@ -6517,76 +7901,113 @@
#endif
/* Pseudo ops. */
- TCE(adr, 28f0000, 000f, 2, (RR, EXP), adr, t_adr),
- CM(adr,l, 28f0000, 2, (RR, EXP), adrl),
- TCE(nop, 1a00000, 46c0, 1, (oI255c), nop, t_nop),
+ TCE(adr, 28f0000, 000f, 2, (RR, EXP), adr, t_adr),
+ CM(adr,l, 28f0000, 2, (RR, EXP), adrl),
+ tCE(nop, 1a00000, nop, 1, (oI255c), nop, t_nop),
- /* Thumb-compatibility pseudo ops. Note that the 16-bit Thumb
- instruction is equivalent to the s-form of the ARM instruction
- in all cases where that form exists. */
- TCE(lsl, 1a00000, 4080, 3, (RR, oRR, RR_EXi), shift, t_shift),
- CM(lsl,s, 1b00000, 3, (RR, oRR, RR_EXi), shift),
- TCE(lsr, 1a00020, 40c0, 3, (RR, oRR, RR_EXi), shift, t_shift),
- CM(lsr,s, 1b00020, 3, (RR, oRR, RR_EXi), shift),
- TCE(asr, 1a00040, 4100, 3, (RR, oRR, RR_EXi), shift, t_shift),
- CM(asr,s, 1b00040, 3, (RR, oRR, RR_EXi), shift),
- TCE(ror, 1a00060, 41c0, 3, (RR, oRR, RR_EXi), shift, t_shift),
- CM(ror,s, 1b00060, 3, (RR, oRR, RR_EXi), shift),
- TCE(neg, 2600000, 4240, 2, (RR, RR), rd_rn, t_arit),
- CM(neg,s, 2700000, 2, (RR, RR), rd_rn),
- TCE(push, 92d0000, b400, 1, (REGLST), push_pop, t_push_pop),
- TCE(pop, 8bd0000, bc00, 1, (REGLST), push_pop, t_push_pop),
+ /* Thumb-compatibility pseudo ops. */
+ tCE(lsl, 1a00000, lsl, 3, (RR, oRR, SH), shift, t_shift),
+ tCM(lsl,s, 1b00000, lsls, 3, (RR, oRR, SH), shift, t_shift),
+ tCE(lsr, 1a00020, lsr, 3, (RR, oRR, SH), shift, t_shift),
+ tCM(lsr,s, 1b00020, lsrs, 3, (RR, oRR, SH), shift, t_shift),
+ tCE(asr, 1a00040, asr, 3, (RR, oRR, SH), shift, t_shift),
+ tCM(asr,s, 1b00040, asrs, 3, (RR, oRR, SH), shift, t_shift),
+ tCE(ror, 1a00060, ror, 3, (RR, oRR, SH), shift, t_shift),
+ tCM(ror,s, 1b00060, rors, 3, (RR, oRR, SH), shift, t_shift),
+ tCE(neg, 2600000, neg, 2, (RR, RR), rd_rn, t_neg),
+ tCM(neg,s, 2700000, negs, 2, (RR, RR), rd_rn, t_neg),
+ tCE(push, 92d0000, push, 1, (REGLST), push_pop, t_push_pop),
+ tCE(pop, 8bd0000, pop, 1, (REGLST), push_pop, t_push_pop),
+
#undef THUMB_VARIANT
#define THUMB_VARIANT ARM_EXT_V6
- TCE(cpy, 1a00000, 4600, 2, (RR, RR), rd_rm, t_cpy),
+ TCE(cpy, 1a00000, 4600, 2, (RR, RR), rd_rm, t_cpy),
+ /* V1 instructions with no Thumb analogue prior to V6T2. */
+#undef THUMB_VARIANT
+#define THUMB_VARIANT ARM_EXT_V6T2
+ TCE(rsb, 0600000, ebc00000, 3, (RR, oRR, SH), arit, t_rsb),
+ TCM(rsb,s, 0700000, ebd00000, 3, (RR, oRR, SH), arit, t_rsb),
+ TCE(teq, 1300000, ea900f00, 2, (RR, SH), cmp, t_mvn_tst),
+ TCM(teq,s, 1300000, ea900f00, 2, (RR, SH), cmp, t_mvn_tst),
+ CM(teq,p, 130f000, 2, (RR, SH), cmp),
+
+ TCM(ldr,t, 4300000, f8500e00, 2, (RR, ADDR), ldstt, t_ldstt),
+ TCM(ldr,bt, 4700000, f8300e00, 2, (RR, ADDR), ldstt, t_ldstt),
+ TCM(str,t, 4200000, f8400e00, 2, (RR, ADDR), ldstt, t_ldstt),
+ TCM(str,bt, 4600000, f8200e00, 2, (RR, ADDR), ldstt, t_ldstt),
+
+ TCM(stm,db, 9000000, e9100000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
+ TCM(stm,fd, 9000000, e9100000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
+
+ TCM(ldm,db, 9100000, e9000000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
+ TCM(ldm,ea, 9100000, e9000000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
+
+ /* V1 instructions with no Thumb analogue at all. */
+ CE(rsc, 0e00000, 3, (RR, oRR, SH), arit),
+ CM(rsc,s, 0f00000, 3, (RR, oRR, SH), arit),
+
+ CM(stm,ib, 9800000, 2, (RRw, REGLST), ldmstm),
+ CM(stm,fa, 9800000, 2, (RRw, REGLST), ldmstm),
+ CM(stm,da, 8000000, 2, (RRw, REGLST), ldmstm),
+ CM(stm,ed, 8000000, 2, (RRw, REGLST), ldmstm),
+ CM(ldm,ib, 9900000, 2, (RRw, REGLST), ldmstm),
+ CM(ldm,ed, 9900000, 2, (RRw, REGLST), ldmstm),
+ CM(ldm,da, 8100000, 2, (RRw, REGLST), ldmstm),
+ CM(ldm,fa, 8100000, 2, (RRw, REGLST), ldmstm),
+
#undef ARM_VARIANT
#define ARM_VARIANT ARM_EXT_V2 /* ARM 2 - multiplies. */
#undef THUMB_VARIANT
#define THUMB_VARIANT ARM_EXT_V4T
- TCE(mul, 0000090, 4340, 3, (RRnpc, RRnpc, oRR), mul, t_mul),
- CM(mul,s, 0100090, 3, (RRnpc, RRnpc, oRR), mul),
- CE(mla, 0200090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas),
- CM(mla,s, 0300090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas),
+ tCE(mul, 0000090, mul, 3, (RRnpc, RRnpc, oRR), mul, t_mul),
+ tCM(mul,s, 0100090, muls, 3, (RRnpc, RRnpc, oRR), mul, t_mul),
+#undef THUMB_VARIANT
+#define THUMB_VARIANT ARM_EXT_V6T2
+ TCE(mla, 0200090, fb000000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas, t_mlas),
+ CM(mla,s, 0300090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas),
+
/* Generic coprocessor instructions. */
- CE(cdp, e000000, 6, (RCP, I15b, RCN, RCN, RCN, oI7b), cdp),
- CE(ldc, c100000, 3, (RCP, RCN, ADDR), lstc),
- CM(ldc,l, c500000, 3, (RCP, RCN, ADDR), lstc),
- CE(stc, c000000, 3, (RCP, RCN, ADDR), lstc),
- CM(stc,l, c400000, 3, (RCP, RCN, ADDR), lstc),
- CE(mcr, e000010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg),
- CE(mrc, e100010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg),
+ TCE(cdp, e000000, ee000000, 6, (RCP, I15b, RCN, RCN, RCN, oI7b), cdp, cdp),
+ TCE(ldc, c100000, ec100000, 3, (RCP, RCN, ADDR), lstc, lstc),
+ TCM(ldc,l, c500000, ec500000, 3, (RCP, RCN, ADDR), lstc, lstc),
+ TCE(stc, c000000, ec000000, 3, (RCP, RCN, ADDR), lstc, lstc),
+ TCM(stc,l, c400000, ec400000, 3, (RCP, RCN, ADDR), lstc, lstc),
+ TCE(mcr, e000010, ee000010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
+ TCE(mrc, e100010, ee100010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
#undef ARM_VARIANT
#define ARM_VARIANT ARM_EXT_V2S /* ARM 3 - swp instructions. */
- CE(swp, 1000090, 3, (RRnpc, RRnpc, RRnpcb), rd_rm_rn),
- CM(swp,b, 1400090, 3, (RRnpc, RRnpc, RRnpcb), rd_rm_rn),
+ CE(swp, 1000090, 3, (RRnpc, RRnpc, RRnpcb), rd_rm_rn),
+ CM(swp,b, 1400090, 3, (RRnpc, RRnpc, RRnpcb), rd_rm_rn),
#undef ARM_VARIANT
#define ARM_VARIANT ARM_EXT_V3 /* ARM 6 Status register instructions. */
- CE(mrs, 10f0000, 2, (RR, PSR), mrs),
- CE(msr, 120f000, 2, (PSR, RR_EXi), msr),
+ TCE(mrs, 10f0000, f3ef8000, 2, (RR, PSR), mrs, t_mrs),
+ TCE(msr, 120f000, f3808000, 2, (PSR, RR_EXi), msr, t_msr),
#undef ARM_VARIANT
#define ARM_VARIANT ARM_EXT_V3M /* ARM 7M long multiplies. */
- CE(smull, 0c00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
- CM(smull,s, 0d00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
- CE(umull, 0800090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
- CM(umull,s, 0900090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
- CE(smlal, 0e00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
- CM(smlal,s, 0f00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
- CE(umlal, 0a00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
- CM(umlal,s, 0b00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
+ TCE(smull, 0c00090, fb800000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
+ CM(smull,s, 0d00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
+ TCE(umull, 0800090, fba00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
+ CM(umull,s, 0900090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
+ TCE(smlal, 0e00090, fbc00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
+ CM(smlal,s, 0f00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
+ TCE(umlal, 0a00090, fbe00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
+ CM(umlal,s, 0b00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
#undef ARM_VARIANT
#define ARM_VARIANT ARM_EXT_V4 /* ARM Architecture 4. */
- TCM(ldr,h, 01000b0, 5a00, 2, (RR, ADDR), ldstv4, t_ldst),
- TCM(str,h, 00000b0, 5200, 2, (RR, ADDR), ldstv4, t_ldst),
- TCM(ldr,sh, 01000f0, 5e00, 2, (RR, ADDR), ldstv4, t_lds),
- TCM(ldr,sb, 01000d0, 5600, 2, (RR, ADDR), ldstv4, t_lds),
- TCM(ld,sh, 01000f0, 5e00, 2, (RR, ADDR), ldstv4, t_lds),
- TCM(ld,sb, 01000d0, 5600, 2, (RR, ADDR), ldstv4, t_lds),
+#undef THUMB_VARIANT
+#define THUMB_VARIANT ARM_EXT_V4T
+ tCM(ldr,h, 01000b0, ldrh, 2, (RR, ADDR), ldstv4, t_ldst),
+ tCM(str,h, 00000b0, strh, 2, (RR, ADDR), ldstv4, t_ldst),
+ tCM(ldr,sh, 01000f0, ldrsh, 2, (RR, ADDR), ldstv4, t_ldst),
+ tCM(ldr,sb, 01000d0, ldrsb, 2, (RR, ADDR), ldstv4, t_ldst),
+ tCM(ld,sh, 01000f0, ldrsh, 2, (RR, ADDR), ldstv4, t_ldst),
+ tCM(ld,sb, 01000d0, ldrsb, 2, (RR, ADDR), ldstv4, t_ldst),
#undef ARM_VARIANT
#define ARM_VARIANT ARM_EXT_V4T|ARM_EXT_V5
@@ -6601,198 +8022,207 @@
#define THUMB_VARIANT ARM_EXT_V5T
/* Note: blx has 2 variants; the .value coded here is for
BLX(2). Only this variant has conditional execution. */
- TCE(blx, 12fff30, 4780, 1, (RR_EXr), blx, t_blx),
- CE(clz, 16f0f10, 2, (RRnpc, RRnpc), rd_rm),
+ TCE(blx, 12fff30, 4780, 1, (RR_EXr), blx, t_blx),
TUE(bkpt, 1200070, be00, 1, (oIffffb), bkpt, t_bkpt),
- UF(ldc2, c100000, 3, (RCP, RCN, ADDR), lstc),
- UF(ldc2l, c500000, 3, (RCP, RCN, ADDR), lstc),
- UF(stc2, c000000, 3, (RCP, RCN, ADDR), lstc),
- UF(stc2l, c400000, 3, (RCP, RCN, ADDR), lstc),
- UF(cdp2, e000000, 6, (RCP, I15b, RCN, RCN, RCN, oI7b), cdp),
- UF(mcr2, e000010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg),
- UF(mrc2, e100010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg),
+#undef THUMB_VARIANT
+#define THUMB_VARIANT ARM_EXT_V6T2
+ TCE(clz, 16f0f10, fab0f080, 2, (RRnpc, RRnpc), rd_rm, t_clz),
+ TUF(ldc2, c100000, fc100000, 3, (RCP, RCN, ADDR), lstc, lstc),
+ TUF(ldc2l, c500000, fc500000, 3, (RCP, RCN, ADDR), lstc, lstc),
+ TUF(stc2, c000000, fc000000, 3, (RCP, RCN, ADDR), lstc, lstc),
+ TUF(stc2l, c400000, fc400000, 3, (RCP, RCN, ADDR), lstc, lstc),
+ TUF(cdp2, e000000, fe000000, 6, (RCP, I15b, RCN, RCN, RCN, oI7b), cdp, cdp),
+ TUF(mcr2, e000010, fe000010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
+ TUF(mrc2, e100010, fe100010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
+
#undef ARM_VARIANT
#define ARM_VARIANT ARM_EXT_V5ExP /* ARM Architecture 5TExP. */
- CE(smlabb, 1000080, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla),
- CE(smlatb, 10000a0, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla),
- CE(smlabt, 10000c0, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla),
- CE(smlatt, 10000e0, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla),
+ TCE(smlabb, 1000080, fb100000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_smla),
+ TCE(smlatb, 10000a0, fb100020, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_smla),
+ TCE(smlabt, 10000c0, fb100010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_smla),
+ TCE(smlatt, 10000e0, fb100030, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_smla),
- CE(smlawb, 1200080, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla),
- CE(smlawt, 12000c0, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla),
+ TCE(smlawb, 1200080, fb300000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_smla),
+ TCE(smlawt, 12000c0, fb300010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_smla),
- CE(smlalbb, 1400080, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal),
- CE(smlaltb, 14000a0, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal),
- CE(smlalbt, 14000c0, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal),
- CE(smlaltt, 14000e0, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal),
+ TCE(smlalbb, 1400080, fbc00080, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_smlal),
+ TCE(smlaltb, 14000a0, fbc000a0, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_smlal),
+ TCE(smlalbt, 14000c0, fbc00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_smlal),
+ TCE(smlaltt, 14000e0, fbc000b0, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_smlal),
- CE(smulbb, 1600080, 3, (RRnpc, RRnpc, RRnpc), smul),
- CE(smultb, 16000a0, 3, (RRnpc, RRnpc, RRnpc), smul),
- CE(smulbt, 16000c0, 3, (RRnpc, RRnpc, RRnpc), smul),
- CE(smultt, 16000e0, 3, (RRnpc, RRnpc, RRnpc), smul),
+ TCE(smulbb, 1600080, fb10f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_smul),
+ TCE(smultb, 16000a0, fb10f020, 3, (RRnpc, RRnpc, RRnpc), smul, t_smul),
+ TCE(smulbt, 16000c0, fb10f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_smul),
+ TCE(smultt, 16000e0, fb10f030, 3, (RRnpc, RRnpc, RRnpc), smul, t_smul),
- CE(smulwb, 12000a0, 3, (RRnpc, RRnpc, RRnpc), smul),
- CE(smulwt, 12000e0, 3, (RRnpc, RRnpc, RRnpc), smul),
+ TCE(smulwb, 12000a0, fb30f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_smul),
+ TCE(smulwt, 12000e0, fb30f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_smul),
- CE(qadd, 1000050, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn),
- CE(qdadd, 1400050, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn),
- CE(qsub, 1200050, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn),
- CE(qdsub, 1600050, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn),
+ TCE(qadd, 1000050, fa80f080, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, rd_rm_rn),
+ TCE(qdadd, 1400050, fa80f090, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, rd_rm_rn),
+ TCE(qsub, 1200050, fa80f0a0, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, rd_rm_rn),
+ TCE(qdsub, 1600050, fa80f0b0, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, rd_rm_rn),
#undef ARM_VARIANT
#define ARM_VARIANT ARM_EXT_V5E /* ARM Architecture 5TE. */
- UF(pld, 450f000, 1, (ADDR), pld),
- CM(ldr,d, 00000d0, 2, (RR, ADDR), ldrd),
- CM(str,d, 00000f0, 2, (RR, ADDR), ldrd),
+ TUF(pld, 450f000, f810f000, 1, (ADDR), pld, t_pld),
+ TCM(ldr,d, 00000d0, e9500000, 3, (RRnpc, oRRnpc, ADDR), ldrd, t_ldstd),
+ TCM(str,d, 00000f0, e9400000, 3, (RRnpc, oRRnpc, ADDR), ldrd, t_ldstd),
- CE(mcrr, c400000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c),
- CE(mrrc, c500000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c),
+ TCE(mcrr, c400000, ec400000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
+ TCE(mrrc, c500000, ec500000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
#undef ARM_VARIANT
#define ARM_VARIANT ARM_EXT_V5J /* ARM Architecture 5TEJ. */
- CE(bxj, 12fff20, 1, (RR), bxj),
+ TCE(bxj, 12fff20, f3c08f00, 1, (RR), bxj, t_bxj),
#undef ARM_VARIANT
#define ARM_VARIANT ARM_EXT_V6 /* ARM V6. */
#undef THUMB_VARIANT
#define THUMB_VARIANT ARM_EXT_V6
- UF(cps, 1020000, 1, (I31b), imm0),
- TUF(cpsie, 1080000, b660, 2, (CPSF, oI31b), cpsi, t_cpsi),
- TUF(cpsid, 10c0000, b670, 2, (CPSF, oI31b), cpsi, t_cpsi),
- CE(ldrex, 1900f9f, 2, (RRnpc, RRnpcb), rd_rn),
- UF(mcrr2, c400000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c),
- UF(mrrc2, c500000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c),
- CE(pkhbt, 6800010, 4, (RRnpc, RRnpc, RRnpc, oSHll), pkhbt),
- CE(pkhtb, 6800050, 4, (RRnpc, RRnpc, RRnpc, oSHar), pkhtb),
- CE(qadd16, 6200f10, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(qadd8, 6200f90, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(qaddsubx, 6200f30, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(qsub16, 6200f70, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(qsub8, 6200ff0, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(qsubaddx, 6200f50, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(sadd16, 6100f10, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(sadd8, 6100f90, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(saddsubx, 6100f30, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(shadd16, 6300f10, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(shadd8, 6300f90, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(shaddsubx, 6300f30, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(shsub16, 6300f70, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(shsub8, 6300ff0, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(shsubaddx, 6300f50, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(ssub16, 6100f70, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(ssub8, 6100ff0, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(ssubaddx, 6100f50, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(uadd16, 6500f10, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(uadd8, 6500f90, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(uaddsubx, 6500f30, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(uhadd16, 6700f10, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(uhadd8, 6700f90, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(uhaddsubx, 6700f30, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(uhsub16, 6700f70, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(uhsub8, 6700ff0, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(uhsubaddx, 6700f50, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(uqadd16, 6600f10, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(uqadd8, 6600f90, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(uqaddsubx, 6600f30, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(uqsub16, 6600f70, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(uqsub8, 6600ff0, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(uqsubaddx, 6600f50, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(usub16, 6500f70, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(usub8, 6500ff0, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- CE(usubaddx, 6500f50, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- TCE(rev, 6bf0f30, ba00, 2, (RRnpc, RRnpc), rd_rm, t_arit),
- TCE(rev16, 6bf0fb0, ba40, 2, (RRnpc, RRnpc), rd_rm, t_arit),
- TCE(revsh, 6ff0fb0, bac0, 2, (RRnpc, RRnpc), rd_rm, t_arit),
- UF(rfeia, 8900a00, 1, (RRw), rfe),
- UF(rfeib, 9900a00, 1, (RRw), rfe),
- UF(rfeda, 8100a00, 1, (RRw), rfe),
- UF(rfedb, 9100a00, 1, (RRw), rfe),
- UF(rfefd, 8900a00, 1, (RRw), rfe),
- UF(rfefa, 9900a00, 1, (RRw), rfe),
- UF(rfeea, 8100a00, 1, (RRw), rfe),
- UF(rfeed, 9100a00, 1, (RRw), rfe),
- CE(sxtah, 6b00070, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah),
- CE(sxtab16, 6800070, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah),
- CE(sxtab, 6a00070, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah),
- TCE(sxth, 6bf0070, b200, 3, (RRnpc, RRnpc, oROR), sxth, t_arit),
- CE(sxtb16, 68f0070, 3, (RRnpc, RRnpc, oROR), sxth),
- TCE(sxtb, 6af0070, b240, 3, (RRnpc, RRnpc, oROR), sxth, t_arit),
- CE(uxtah, 6f00070, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah),
- CE(uxtab16, 6c00070, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah),
- CE(uxtab, 6e00070, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah),
- TCE(uxth, 6ff0070, b280, 3, (RRnpc, RRnpc, oROR), sxth, t_arit),
- CE(uxtb16, 6cf0070, 3, (RRnpc, RRnpc, oROR), sxth),
- TCE(uxtb, 6ef0070, b2c0, 3, (RRnpc, RRnpc, oROR), sxth, t_arit),
- CE(sel, 68000b0, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm),
- TUF(setend, 1010000, b650, 1, (ENDI), setend, t_setend),
- CE(smlad, 7000010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla),
- CE(smladx, 7000030, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla),
- CE(smlald, 7400010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal),
- CE(smlaldx, 7400030, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal),
- CE(smlsd, 7000050, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla),
- CE(smlsdx, 7000070, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla),
- CE(smlsld, 7400050, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal),
- CE(smlsldx, 7400070, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal),
- CE(smmla, 7500010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla),
- CE(smmlar, 7500030, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla),
- CE(smmls, 75000d0, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla),
- CE(smmlsr, 75000f0, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla),
- CE(smmul, 750f010, 3, (RRnpc, RRnpc, RRnpc), smul),
- CE(smmulr, 750f030, 3, (RRnpc, RRnpc, RRnpc), smul),
- CE(smuad, 700f010, 3, (RRnpc, RRnpc, RRnpc), smul),
- CE(smuadx, 700f030, 3, (RRnpc, RRnpc, RRnpc), smul),
- CE(smusd, 700f050, 3, (RRnpc, RRnpc, RRnpc), smul),
- CE(smusdx, 700f070, 3, (RRnpc, RRnpc, RRnpc), smul),
- UF(srsia, 8cd0500, 1, (I31w), srs),
- UF(srsib, 9cd0500, 1, (I31w), srs),
- UF(srsda, 84d0500, 1, (I31w), srs),
- UF(srsdb, 94d0500, 1, (I31w), srs),
- CE(ssat, 6a00010, 4, (RRnpc, I32, RRnpc, oSHllar), ssat),
- CE(ssat16, 6a00f30, 3, (RRnpc, I16, RRnpc), ssat16),
- CE(strex, 1800f90, 3, (RRnpc, RRnpc, RRnpcb), strex),
- CE(umaal, 0400090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal),
- CE(usad8, 780f010, 3, (RRnpc, RRnpc, RRnpc), smul),
- CE(usada8, 7800010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla),
- CE(usat, 6e00010, 4, (RRnpc, I31, RRnpc, oSHllar), usat),
- CE(usat16, 6e00f30, 3, (RRnpc, I15, RRnpc), usat16),
+ TUF(cpsie, 1080000, b660, 2, (CPSF, oI31b), cpsi, t_cpsi),
+ TUF(cpsid, 10c0000, b670, 2, (CPSF, oI31b), cpsi, t_cpsi),
+ tCE(rev, 6bf0f30, rev, 2, (RRnpc, RRnpc), rd_rm, t_rev),
+ tCE(rev16, 6bf0fb0, rev16, 2, (RRnpc, RRnpc), rd_rm, t_rev),
+ tCE(revsh, 6ff0fb0, revsh, 2, (RRnpc, RRnpc), rd_rm, t_rev),
+ tCE(sxth, 6bf0070, sxth, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
+ tCE(uxth, 6ff0070, uxth, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
+ tCE(sxtb, 6af0070, sxtb, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
+ tCE(uxtb, 6ef0070, uxtb, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
+ TUF(setend, 1010000, b650, 1, (ENDI), setend, t_setend),
+#undef THUMB_VARIANT
+#define THUMB_VARIANT ARM_EXT_V6T2
+ TUF(cps, 1020000, f3af8100, 1, (I31b), imm0, imm0),
+ TCE(ldrex, 1900f9f, e8500f00, 2, (RRnpc, ADDR), ldrex, t_ldrex),
+ TUF(mcrr2, c400000, fc400000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
+ TUF(mrrc2, c500000, fc500000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
+ TCE(pkhbt, 6800010, eac00000, 4, (RRnpc, RRnpc, RRnpc, oSHll), pkhbt, t_pkhbt),
+ TCE(pkhtb, 6800050, eac00020, 4, (RRnpc, RRnpc, RRnpc, oSHar), pkhtb, t_pkhtb),
+ TCE(qadd16, 6200f10, fa90f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(qadd8, 6200f90, fa80f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(qaddsubx, 6200f30, faa0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(qsub16, 6200f70, fad0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(qsub8, 6200ff0, fac0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(qsubaddx, 6200f50, fae0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(sadd16, 6100f10, fa90f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(sadd8, 6100f90, fa80f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(saddsubx, 6100f30, faa0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(shadd16, 6300f10, fa90f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(shadd8, 6300f90, fa80f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(shaddsubx, 6300f30, faa0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(shsub16, 6300f70, fad0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(shsub8, 6300ff0, fac0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(shsubaddx, 6300f50, fae0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(ssub16, 6100f70, fad0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(ssub8, 6100ff0, fac0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(ssubaddx, 6100f50, fae0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(uadd16, 6500f10, fa90f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(uadd8, 6500f90, fa80f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(uaddsubx, 6500f30, faa0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(uhadd16, 6700f10, fa90f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(uhadd8, 6700f90, fa80f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(uhaddsubx, 6700f30, faa0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(uhsub16, 6700f70, fad0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(uhsub8, 6700ff0, fac0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(uhsubaddx, 6700f50, fae0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(uqadd16, 6600f10, fa90f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(uqadd8, 6600f90, fa80f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(uqaddsubx, 6600f30, faa0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(uqsub16, 6600f70, fad0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(uqsub8, 6600ff0, fac0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(uqsubaddx, 6600f50, fae0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(usub16, 6500f70, fad0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(usub8, 6500ff0, fac0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(usubaddx, 6500f50, fae0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TUF(rfeia, 8900a00, e990c000, 1, (RRw), rfe, rfe),
+ UF(rfeib, 9900a00, 1, (RRw), rfe),
+ UF(rfeda, 8100a00, 1, (RRw), rfe),
+ TUF(rfedb, 9100a00, e810c000, 1, (RRw), rfe, rfe),
+ TUF(rfefd, 8900a00, e990c000, 1, (RRw), rfe, rfe),
+ UF(rfefa, 9900a00, 1, (RRw), rfe),
+ UF(rfeea, 8100a00, 1, (RRw), rfe),
+ TUF(rfeed, 9100a00, e810c000, 1, (RRw), rfe, rfe),
+ TCE(sxtah, 6b00070, fa00f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
+ TCE(sxtab16, 6800070, fa20f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
+ TCE(sxtab, 6a00070, fa40f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
+ TCE(sxtb16, 68f0070, fa2ff080, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
+ TCE(uxtah, 6f00070, fa10f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
+ TCE(uxtab16, 6c00070, fa30f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
+ TCE(uxtab, 6e00070, fa50f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
+ TCE(uxtb16, 6cf0070, fa3ff080, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
+ TCE(sel, 68000b0, faa0f080, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_qadd),
+ TCE(smlad, 7000010, fb200000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_smla),
+ TCE(smladx, 7000030, fb200010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_smla),
+ TCE(smlald, 7400010, fbc000c0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_smlal),
+ TCE(smlaldx, 7400030, fbc000d0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_smlal),
+ TCE(smlsd, 7000050, fb400000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_smla),
+ TCE(smlsdx, 7000070, fb400010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_smla),
+ TCE(smlsld, 7400050, fbd000c0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_smlal),
+ TCE(smlsldx, 7400070, fbd000d0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_smlal),
+ TCE(smmla, 7500010, fb500000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_smla),
+ TCE(smmlar, 7500030, fb500010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_smla),
+ TCE(smmls, 75000d0, fb600000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_smla),
+ TCE(smmlsr, 75000f0, fb600010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_smla),
+ TCE(smmul, 750f010, fb50f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_smul),
+ TCE(smmulr, 750f030, fb50f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_smul),
+ TCE(smuad, 700f010, fb20f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_smul),
+ TCE(smuadx, 700f030, fb20f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_smul),
+ TCE(smusd, 700f050, fb40f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_smul),
+ TCE(smusdx, 700f070, fb40f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_smul),
+ TUF(srsia, 8cd0500, e980c000, 1, (I31w), srs, srs),
+ UF(srsib, 9cd0500, 1, (I31w), srs),
+ UF(srsda, 84d0500, 1, (I31w), srs),
+ TUF(srsdb, 94d0500, e800c000, 1, (I31w), srs, srs),
+ TCE(ssat, 6a00010, f3000000, 4, (RRnpc, I32, RRnpc, oSHllar),ssat, t_ssat),
+ TCE(ssat16, 6a00f30, f3200000, 3, (RRnpc, I16, RRnpc), ssat16, t_ssat16),
+ TCE(strex, 1800f90, e8400000, 3, (RRnpc, RRnpc, ADDR), strex, t_strex),
+ TCE(umaal, 0400090, fbe00060, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal, t_smlal),
+ TCE(usad8, 780f010, fb70f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_smul),
+ TCE(usada8, 7800010, fb700000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_smla),
+ TCE(usat, 6e00010, f3800000, 4, (RRnpc, I31, RRnpc, oSHllar),usat, t_usat),
+ TCE(usat16, 6e00f30, f3a00000, 3, (RRnpc, I15, RRnpc), usat16, t_usat16),
+
#undef ARM_VARIANT
#define ARM_VARIANT ARM_EXT_V6K
#undef THUMB_VARIANT
#define THUMB_VARIANT ARM_EXT_V6K
- CE(ldrexb, 1d00f9f, 2, (RRnpc, RRnpcb), rd_rn),
- CE(ldrexd, 1b00f9f, 2, (RRnpc, RRnpcb), rd_rn),
- CE(ldrexh, 1f00f9f, 2, (RRnpc, RRnpcb), rd_rn),
- CE(strexb, 1c00f90, 3, (RRnpc, RRnpc, RRnpcb), strex),
- CE(strexd, 1a00f90, 3, (RRnpc, RRnpc, RRnpcb), strex),
- CE(strexh, 1e00f90, 3, (RRnpc, RRnpc, RRnpcb), strex),
- UF(clrex, 57ff01f, 0, (), noargs),
- TCE(yield, 320f001, bf10, 0, (), noargs, noargs),
- TCE(wfe, 320f002, bf20, 0, (), noargs, noargs),
- TCE(wfi, 320f003, bf30, 0, (), noargs, noargs),
- TCE(sev, 320f004, bf40, 0, (), noargs, noargs),
+ tCE(yield, 320f001, yield, 0, (), noargs, t_hint),
+ tCE(wfe, 320f002, wfe, 0, (), noargs, t_hint),
+ tCE(wfi, 320f003, wfi, 0, (), noargs, t_hint),
+ tCE(sev, 320f004, sev, 0, (), noargs, t_hint),
+#undef THUMB_VARIANT
+#define THUMB_VARIANT ARM_EXT_V6T2
+ TCE(ldrexb, 1d00f9f, e8d00f4f, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
+ TCE(ldrexh, 1f00f9f, e8d00f5f, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
+ TCE(ldrexd, 1b00f9f, e8d0007f, 3, (RRnpc, oRRnpc, RRnpcb), ldrexd, t_ldrexd),
+ TCE(strexb, 1c00f90, e8c00f40, 3, (RRnpc, RRnpc, ADDR), strex, rm_rd_rn),
+ TCE(strexh, 1e00f90, e8c00f50, 3, (RRnpc, RRnpc, ADDR), strex, rm_rd_rn),
+ TCE(strexd, 1a00f90, e8c00070, 4, (RRnpc, RRnpc, oRRnpc, RRnpcb), strexd, t_strexd),
+ TUF(clrex, 57ff01f, f3bf8f2f, 0, (), noargs, noargs),
+
#undef ARM_VARIANT
#define ARM_VARIANT ARM_EXT_V6Z
- CE(smi, 1600070, 1, (EXPi), smi),
+ TCE(smi, 1600070, f7f08000, 1, (EXPi), smi, t_smi),
#undef ARM_VARIANT
#define ARM_VARIANT ARM_EXT_V6T2
- CE(bfc, 7c0001f, 3, (RRnpc, I31, I32), bfc),
- CE(bfi, 7c00010, 4, (RRnpc, RRnpc_I0, I31, I32), bfi),
- CE(sbfx, 7a00050, 4, (RR, RR, I31, I32), bfx),
- CE(ubfx, 7e00050, 4, (RR, RR, I31, I32), bfx),
+ TCE(bfc, 7c0001f, f36f0000, 3, (RRnpc, I31, I32), bfc, t_bfc),
+ TCE(bfi, 7c00010, f3600000, 4, (RRnpc, RRnpc_I0, I31, I32), bfi, t_bfi),
+ TCE(sbfx, 7a00050, f3400000, 4, (RR, RR, I31, I32), bfx, t_bfx),
+ TCE(ubfx, 7e00050, f3c00000, 4, (RR, RR, I31, I32), bfx, t_bfx),
- CE(mls, 0600090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas),
- CE(movw, 3000000, 2, (RRnpc, Iffff), mov16),
- CE(movt, 3400000, 2, (RRnpc, Iffff), mov16),
- CE(rbit, 3ff0f30, 2, (RR, RR), rd_rm),
+ TCE(mls, 0600090, fb000010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas, t_mlas),
+ TCE(movw, 3000000, f2400000, 2, (RRnpc, Iffff), mov16, t_mov16),
+ TCE(movt, 3400000, f2c00000, 2, (RRnpc, Iffff), mov16, t_mov16),
+ TCE(rbit, 3ff0f30, fa90f0a0, 2, (RR, RR), rd_rm, t_rbit),
- CM(ldr,ht, 03000b0, 2, (RR, ADDR), ldsttv4),
- CM(ldr,sht, 03000f0, 2, (RR, ADDR), ldsttv4),
- CM(ldr,sbt, 03000d0, 2, (RR, ADDR), ldsttv4),
- CM(str,ht, 02000b0, 2, (RR, ADDR), ldsttv4),
+ TCM(ldr,ht, 03000b0, f8300e00, 2, (RR, ADDR), ldsttv4, t_ldstt),
+ TCM(ldr,sht, 03000f0, f9300e00, 2, (RR, ADDR), ldsttv4, t_ldstt),
+ TCM(ldr,sbt, 03000d0, f9100e00, 2, (RR, ADDR), ldsttv4, t_ldstt),
+ TCM(str,ht, 02000b0, f8200e00, 2, (RR, ADDR), ldsttv4, t_ldstt),
UT(czbne, b900, 2, (RR, EXP), t_czb),
UT(czbeq, b100, 2, (RR, EXP), t_czb),
@@ -8603,6 +10033,133 @@
md_number_to_chars (buf, newval, INSN_SIZE);
break;
+ case BFD_RELOC_ARM_T32_OFFSET_U8:
+ if (value < 0 || value > 1020 || value % 4 != 0)
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("bad immediate value for offset (%ld)"), (long) value);
+ value /= 4;
+
+ newval = md_chars_to_number (buf+2, THUMB_SIZE);
+ newval &= 0xff00;
+ newval |= value;
+ md_number_to_chars (buf+2, newval, THUMB_SIZE);
+ break;
+
+ case BFD_RELOC_ARM_T32_OFFSET_IMM:
+ /* This is a complicated relocation used for all varieties of Thumb32
+ load/store instruction with immediate offset:
+
+ 1110 100P u1WL NNNN XXXX YYYY iiii iiii - +/-(U) pre/post(P) 8-bit,
+ *4, optional writeback(W)
+ (doubleword load/store)
+
+ 1111 100S uTTL 1111 XXXX iiii iiii iiii - +/-(U) 12-bit PC-rel
+ 1111 100S 0TTL NNNN XXXX 1Pu1 iiii iiii - +/-(U) pre/post(P) 8-bit
+ 1111 100S 0TTL NNNN XXXX 1110 iiii iiii - positive 8-bit (T instruction)
+ 1111 100S 1TTL NNNN XXXX iiii iiii iiii - positive 12-bit
+ 1111 100S 0TTL NNNN XXXX 1100 iiii iiii - negative 8-bit
+
+ Uppercase letters indicate bits that are already encoded at
+ this point. Lowercase letters are our problem. For the
+ second block of instructions, the secondary opcode nybble
+ (bits 8..11) is present, and bit 23 is zero, even if this is
+ a PC-relative operation. */
+ newval = md_chars_to_number (buf, THUMB_SIZE);
+ newval <<= 16;
+ newval |= md_chars_to_number (buf+THUMB_SIZE, THUMB_SIZE);
+
+ if ((newval & 0xf0000000) == 0xe0000000)
+ {
+ /* Doubleword load/store: 8-bit offset, scaled by 4. */
+ if (value >= 0)
+ newval |= (1 << 23);
+ else
+ value = -value;
+ if (value % 4 != 0)
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("offset not a multiple of 4"));
+ break;
+ }
+ value /= 4;
+ if (value >= 0xff)
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("offset out of range"));
+ break;
+ }
+ newval &= ~0xff;
+ }
+ else if ((newval & 0x0000f000) == 0x0000f0000)
+ {
+ /* PC-relative, 12-bit offset. */
+ if (value >= 0)
+ newval |= (1 << 23);
+ else
+ value = -value;
+ if (value >= 0xfff)
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("offset out of range"));
+ break;
+ }
+ newval &= ~0xfff;
+ }
+ else if ((newval & 0x00000100) == 0x00000100)
+ {
+ /* Writeback: 8-bit, +/- offset. */
+ if (value >= 0)
+ newval |= (1 << 9);
+ else
+ value = -value;
+ if (value >= 0xff)
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("offset out of range"));
+ break;
+ }
+ newval &= ~0xff;
+ }
+ else if ((newval & 0x00000f00) == 0x00000e00)
+ {
+ /* T-instruction: positive 8-bit offset. */
+ if (value < 0 || value >= 0xff)
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("offset out of range"));
+ break;
+ }
+ newval &= ~0xff;
+ newval |= value;
+ }
+ else
+ {
+ /* Positive 12-bit or negative 8-bit offset. */
+ int limit;
+ if (value >= 0)
+ {
+ newval |= (1 << 23);
+ limit = 0xfff;
+ }
+ else
+ {
+ value = -value;
+ limit = 0xff;
+ }
+ if (value > limit)
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("offset out of range"));
+ break;
+ }
+ newval &= ~limit;
+ }
+
+ newval |= value;
+ md_number_to_chars (buf, (newval >> 16) & 0xffff, THUMB_SIZE);
+ md_number_to_chars (buf + THUMB_SIZE, newval & 0xffff, THUMB_SIZE);
+ break;
+
case BFD_RELOC_ARM_SHIFT_IMM:
newval = md_chars_to_number (buf, INSN_SIZE);
if (((unsigned long) value) > 32
@@ -8624,6 +10181,45 @@
md_number_to_chars (buf, newval, INSN_SIZE);
break;
+ case BFD_RELOC_ARM_T32_IMMEDIATE:
+ /* We claim that this fixup has been processed here,
+ even if in fact we generate an error because we do
+ not have a reloc for it, so tc_gen_reloc will reject it. */
+ fixP->fx_done = 1;
+
+ if (fixP->fx_addsy
+ && ! S_IS_DEFINED (fixP->fx_addsy))
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("undefined symbol %s used as an immediate value"),
+ S_GET_NAME (fixP->fx_addsy));
+ break;
+ }
+
+ newval = md_chars_to_number (buf, THUMB_SIZE);
+ newval <<= 16;
+ newval |= md_chars_to_number (buf+2, THUMB_SIZE);
+
+ newimm = encode_thumb32_immediate (value);
+
+ /* FUTURE: Implement analogue of negate_data_op for T32. */
+ if (newimm == (unsigned int)FAIL)
+ {
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("invalid constant (%lx) after fixup"),
+ (unsigned long) value);
+ break;
+ }
+
+ newval &= 0xfbff8f00;
+ newval |= (newimm & 0x800) << 15;
+ newval |= (newimm & 0x700) << 4;
+ newval |= (newimm & 0x0ff);
+
+ md_number_to_chars (buf, (valueT) ((newval >> 16) & 0xffff), THUMB_SIZE);
+ md_number_to_chars (buf+2, (valueT) (newval & 0xffff), THUMB_SIZE);
+ break;
+
case BFD_RELOC_ARM_SMI:
if (((unsigned long) value) > 0xffff)
as_bad_where (fixP->fx_file, fixP->fx_line,
@@ -8673,7 +10269,7 @@
#endif
/* We are going to store value (shifted right by two) in the
- instruction, in a 24 bit, signed field. Thus we need to check
+ instruction, in a 24 bit, signed field Thus we need to check
that none of the top 8 bits of the shifted value (top 7 bits of
the unshifted, unsigned value) are set, or that they are all set. */
if ((value & ~ ((offsetT) 0x1ffffff)) != 0
@@ -8767,24 +10363,23 @@
newval = md_chars_to_number (buf, THUMB_SIZE);
{
addressT diff = ((newval & 0x00f8) >> 2) | (newval & 0x0200) >> 3;
- fprintf (stderr, "%lx %lx\n", value, diff);
- value = value + diff;
+ /* This one does not have the offset encoded in the pattern. */
+ value = value + diff - 4;
/* CZB can only branch forward. */
- if (value & ~0x3f)
+ if (value & ~0x7e)
as_bad_where (fixP->fx_file, fixP->fx_line,
_("branch out of range"));
+
+ newval &= 0xfd07;
if (seg->use_rela_p && !fixP->fx_done)
{
#ifdef OBJ_ELF
fixP->fx_offset = value;
#endif
fixP->fx_addnumber = value;
- newval = newval & 0xfd07;
}
else
- newval = ((newval & 0xfd07)
- | ((value & 0x1e) << 2)
- | ((value & 0x20) << 3));
+ newval |= ((value & 0x2e) << 2) | ((value & 0x40) << 3);
}
md_number_to_chars (buf, newval, THUMB_SIZE);
break;
@@ -8839,6 +10434,54 @@
md_number_to_chars (buf, newval, THUMB_SIZE);
break;
+ case BFD_RELOC_THUMB_PCREL_BRANCH20:
+ {
+ offsetT newval2;
+ addressT diff, S, J1, J2, lo, hi;
+
+ newval = md_chars_to_number (buf, THUMB_SIZE);
+ newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
+
+ S = !(newval & 0x0400); /* flipped - 0=negative */
+ hi = (newval & 0x003f);
+ J1 = (newval2 & 0x2000) >> 13;
+ J2 = (newval2 & 0x0800) >> 11;
+ lo = (newval2 & 0x07ff);
+
+ diff = ((S << 20) | (J2 << 19) | (J1 << 18) | (hi << 12) | (lo << 1));
+ diff -= (1 << 20); /* sign extend */
+ value += diff;
+
+ if ((value & ~0x1fffff) && ((value & ~0x1fffff) != ~0x1fffff))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("conditional branch out of range"));
+
+ newval = newval & 0xfbc0;
+ newval2 = newval2 & 0xd000;
+ if (seg->use_rela_p && !fixP->fx_done)
+ {
+#ifdef OBJ_ELF
+ fixP->fx_offset = value;
+#endif
+ fixP->fx_addnumber = value;
+ }
+ else
+ {
+ S = (value & 0x00100000) >> 20;
+ J2 = (value & 0x00080000) >> 19;
+ J1 = (value & 0x00040000) >> 18;
+ hi = (value & 0x0003f000) >> 12;
+ lo = (value & 0x00000ffe) >> 1;
+
+ newval = newval | (S << 10) | hi;
+ newval2 = newval2 | (J1 << 13) | (J2 << 11) | lo;
+ }
+
+ md_number_to_chars (buf, newval, THUMB_SIZE);
+ md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
+ }
+ break;
+
case BFD_RELOC_THUMB_PCREL_BLX:
case BFD_RELOC_THUMB_PCREL_BRANCH23:
{
@@ -8899,6 +10542,60 @@
#endif
break;
+ case BFD_RELOC_THUMB_PCREL_BRANCH25:
+ {
+ offsetT newval2;
+ addressT diff, S, I1, I2, lo, hi;
+
+ newval = md_chars_to_number (buf, THUMB_SIZE);
+ newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
+
+ S = (newval & 0x0400) >> 10;
+ hi = (newval & 0x03ff);
+ I1 = (newval2 & 0x2000) >> 13;
+ I2 = (newval2 & 0x0800) >> 11;
+ lo = (newval2 & 0x07ff);
+
+ I1 = !(I1 ^ S);
+ I2 = !(I2 ^ S);
+ S = !S;
+
+ diff = ((S << 24) | (I1 << 23) | (I2 << 22) | (hi << 12) | (lo << 1));
+ diff -= (1 << 24); /* sign extend */
+ value += diff;
+
+ if ((value & ~0x1ffffff) && ((value & ~0x1ffffff) != ~0x1ffffff))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("branch out of range"));
+
+ newval = newval & 0xf800;
+ newval2 = newval2 & 0xd000;
+ if (seg->use_rela_p && !fixP->fx_done)
+ {
+#ifdef OBJ_ELF
+ fixP->fx_offset = value;
+#endif
+ fixP->fx_addnumber = value;
+ }
+ else
+ {
+ S = (value & 0x01000000) >> 24;
+ I1 = (value & 0x00800000) >> 23;
+ I2 = (value & 0x00400000) >> 22;
+ hi = (value & 0x003ff000) >> 12;
+ lo = (value & 0x00000ffe) >> 1;
+
+ I1 = !(I1 ^ S);
+ I2 = !(I2 ^ S);
+
+ newval = newval | (S << 10) | hi;
+ newval2 = newval2 | (I1 << 13) | (I2 << 11) | lo;
+ }
+ md_number_to_chars (buf, newval, THUMB_SIZE);
+ md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
+ }
+ break;
+
case BFD_RELOC_16:
if (seg->use_rela_p && !fixP->fx_done)
break;
@@ -8921,7 +10618,7 @@
case BFD_RELOC_ARM_TLS_LDO32:
S_SET_THREAD_LOCAL (fixP->fx_addsy);
/* fall through */
-
+
case BFD_RELOC_ARM_GOT32:
case BFD_RELOC_ARM_GOTOFF:
case BFD_RELOC_ARM_TARGET2:
===================================================================
Index: bfd/bfd-in2.h
--- bfd/bfd-in2.h (revision 78)
+++ bfd/bfd-in2.h (revision 79)
@@ -2728,6 +2728,7 @@
(at present) written to any object files. */
BFD_RELOC_ARM_IMMEDIATE,
BFD_RELOC_ARM_ADRL_IMMEDIATE,
+ BFD_RELOC_ARM_T32_IMMEDIATE,
BFD_RELOC_ARM_SHIFT_IMM,
BFD_RELOC_ARM_SMI,
BFD_RELOC_ARM_SWI,
@@ -2739,6 +2740,8 @@
BFD_RELOC_ARM_LITERAL,
BFD_RELOC_ARM_IN_POOL,
BFD_RELOC_ARM_OFFSET_IMM8,
+ BFD_RELOC_ARM_T32_OFFSET_U8,
+ BFD_RELOC_ARM_T32_OFFSET_IMM,
BFD_RELOC_ARM_HWLITERAL,
BFD_RELOC_ARM_THUMB_ADD,
BFD_RELOC_ARM_THUMB_IMM,
===================================================================
Index: bfd/reloc.c
--- bfd/reloc.c (revision 78)
+++ bfd/reloc.c (revision 79)
@@ -2711,12 +2711,14 @@
BFD_RELOC_ARM_TLS_LE32
ENUMDOC
ARM thread-local storage relocations.
-
+
ENUM
BFD_RELOC_ARM_IMMEDIATE
ENUMX
BFD_RELOC_ARM_ADRL_IMMEDIATE
ENUMX
+ BFD_RELOC_ARM_T32_IMMEDIATE
+ENUMX
BFD_RELOC_ARM_SHIFT_IMM
ENUMX
BFD_RELOC_ARM_SMI
@@ -2739,6 +2741,10 @@
ENUMX
BFD_RELOC_ARM_OFFSET_IMM8
ENUMX
+ BFD_RELOC_ARM_T32_OFFSET_U8
+ENUMX
+ BFD_RELOC_ARM_T32_OFFSET_IMM
+ENUMX
BFD_RELOC_ARM_HWLITERAL
ENUMX
BFD_RELOC_ARM_THUMB_ADD
===================================================================
Index: bfd/libbfd.h
--- bfd/libbfd.h (revision 78)
+++ bfd/libbfd.h (revision 79)
@@ -1179,6 +1179,7 @@
"BFD_RELOC_ARM_TLS_LE32",
"BFD_RELOC_ARM_IMMEDIATE",
"BFD_RELOC_ARM_ADRL_IMMEDIATE",
+ "BFD_RELOC_ARM_T32_IMMEDIATE",
"BFD_RELOC_ARM_SHIFT_IMM",
"BFD_RELOC_ARM_SMI",
"BFD_RELOC_ARM_SWI",
@@ -1190,6 +1191,8 @@
"BFD_RELOC_ARM_LITERAL",
"BFD_RELOC_ARM_IN_POOL",
"BFD_RELOC_ARM_OFFSET_IMM8",
+ "BFD_RELOC_ARM_T32_OFFSET_U8",
+ "BFD_RELOC_ARM_T32_OFFSET_IMM",
"BFD_RELOC_ARM_HWLITERAL",
"BFD_RELOC_ARM_THUMB_ADD",
"BFD_RELOC_ARM_THUMB_IMM",
===================================================================
Index: bfd/elf32-arm.c
--- bfd/elf32-arm.c (revision 78)
+++ bfd/elf32-arm.c (revision 79)
@@ -3328,19 +3328,18 @@
two pieces together. */
if (globals->use_rel)
{
- bfd_vma S = (upper_insn & 0x0400) >> 10;
- bfd_vma upper = (upper_insn & 0x03ff);
- bfd_vma I1 = (lower_insn & 0x2000) >> 13;
- bfd_vma I2 = (lower_insn & 0x0800) >> 11;
- bfd_vma lower = (lower_insn & 0x07ff);
+ bfd_vma S = (upper_insn & 0x0400) >> 10;
+ bfd_vma hi = (upper_insn & 0x03ff);
+ bfd_vma I1 = (lower_insn & 0x2000) >> 13;
+ bfd_vma I2 = (lower_insn & 0x0800) >> 11;
+ bfd_vma lo = (lower_insn & 0x07ff);
- upper |= ~(I2 ^ S) << 10;
- upper |= ~(I1 ^ S) << 11;
- upper |= ~S << 12;
- upper -= 0x1000; /* Sign extend. */
+ I1 = !(I1 ^ S);
+ I2 = !(I2 ^ S);
+ S = !S;
- addend = (upper << 12) | (lower << 1);
- signed_addend = addend;
+ signed_addend = (S << 24) | (I1 << 23) | (I2 << 22) | (hi << 12) | (lo << 1);
+ signed_addend -= (1 << 24); /* Sign extend. */
}
/* ??? Should handle interworking? GCC might someday try to
@@ -3366,14 +3365,17 @@
/* Put RELOCATION back into the insn. */
{
- bfd_vma S = (relocation & 0x00100000) >> 20;
- bfd_vma J2 = (relocation & 0x00080000) >> 19;
- bfd_vma J1 = (relocation & 0x00040000) >> 18;
- bfd_vma hi = (relocation & 0x0003f000) >> 12;
+ bfd_vma S = (relocation & 0x01000000) >> 24;
+ bfd_vma I1 = (relocation & 0x00800000) >> 23;
+ bfd_vma I2 = (relocation & 0x00400000) >> 22;
+ bfd_vma hi = (relocation & 0x003ff000) >> 12;
bfd_vma lo = (relocation & 0x00000ffe) >> 1;
- upper_insn = (upper_insn & ~(bfd_vma) 0x043f) | (S << 10) | hi;
- lower_insn = (lower_insn & ~(bfd_vma) 0x2fff) | (J1 << 13) | (J2 << 11) | lo;
+ I1 = !(I1 ^ S);
+ I2 = !(I2 ^ S);
+
+ upper_insn = (upper_insn & (bfd_vma) 0xf800) | (S << 10) | hi;
+ lower_insn = (lower_insn & (bfd_vma) 0xd000) | (I1 << 13) | (I2 << 11) | lo;
}
/* Put the relocated value back in the object file: */
@@ -3437,17 +3439,14 @@
/* Put RELOCATION back into the insn. */
{
- bfd_vma S = (relocation & 0x01000000) >> 24;
- bfd_vma I1 = (relocation & 0x00800000) >> 23;
- bfd_vma I2 = (relocation & 0x00400000) >> 22;
- bfd_vma hi = (relocation & 0x003ff000) >> 12;
+ bfd_vma S = (relocation & 0x00100000) >> 20;
+ bfd_vma J2 = (relocation & 0x00080000) >> 19;
+ bfd_vma J1 = (relocation & 0x00040000) >> 18;
+ bfd_vma hi = (relocation & 0x0003f000) >> 12;
bfd_vma lo = (relocation & 0x00000ffe) >> 1;
- I1 ^= S;
- I2 ^= S;
-
- upper_insn = (upper_insn & ~(bfd_vma) 0x07ff) | (S << 10) | hi;
- lower_insn = (lower_insn & ~(bfd_vma) 0x2fff) | (I1 << 13) | (I2 << 11) | lo;
+ upper_insn = (upper_insn & 0xfb30) | (S << 10) | hi;
+ lower_insn = (lower_insn & 0xd000) | (J1 << 13) | (J2 << 11) | lo;
}
/* Put the relocated value back in the object file: */
===================================================================
Index: opcodes/arm-dis.c
--- opcodes/arm-dis.c (revision 78)
+++ opcodes/arm-dis.c (revision 79)
@@ -642,6 +642,7 @@
{ARM_EXT_V6K, 0xbf20, 0xffff, "wfe"},
{ARM_EXT_V6K, 0xbf30, 0xffff, "wfi"},
{ARM_EXT_V6K, 0xbf40, 0xffff, "sev"},
+ {ARM_EXT_V6K, 0xbf00, 0xff0f, "nop\t{%4-7d}"},
/* ARM V6T2 instructions. */
{ARM_EXT_V6T2, 0xb900, 0xfd00, "czbne\t%0-2r, %b"},
@@ -683,7 +684,7 @@
{ARM_EXT_V4T, 0x4180, 0xFFC0, "sbcs\t%0-2r, %3-5r"},
{ARM_EXT_V4T, 0x41C0, 0xFFC0, "rors\t%0-2r, %3-5r"},
{ARM_EXT_V4T, 0x4200, 0xFFC0, "tst\t%0-2r, %3-5r"},
- {ARM_EXT_V4T, 0x4240, 0xFFC0, "rsbs\t%0-2r, %3-5r, #0"}, /* formerly neg */
+ {ARM_EXT_V4T, 0x4240, 0xFFC0, "negs\t%0-2r, %3-5r"},
{ARM_EXT_V4T, 0x4280, 0xFFC0, "cmp\t%0-2r, %3-5r"},
{ARM_EXT_V4T, 0x42C0, 0xFFC0, "cmn\t%0-2r, %3-5r"},
{ARM_EXT_V4T, 0x4300, 0xFFC0, "orrs\t%0-2r, %3-5r"},
@@ -739,8 +740,8 @@
{ARM_EXT_V4T, 0xA000, 0xF800, "add\t%8-10r, pc, #%0-7W\t(adr %8-10r,%0-7a)"},
{ARM_EXT_V4T, 0xA800, 0xF800, "add\t%8-10r, sp, #%0-7W"},
/* format 15 */
- {ARM_EXT_V4T, 0xC000, 0xF800, "stmia\t%8-10r!,%M"},
- {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia\t%8-10r!,%M"},
+ {ARM_EXT_V4T, 0xC000, 0xF800, "stmia\t%8-10r!, %M"},
+ {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia\t%8-10r!, %M"},
/* format 17 */
{ARM_EXT_V4T, 0xDF00, 0xFF00, "swi\t%0-7d"},
/* format 16 */
@@ -764,6 +765,7 @@
%% %
%<bitfield>d print bitfield in decimal
+ %<bitfield>W print bitfield*4 in decimal
%<bitfield>r print bitfield as an ARM register
%<bitfield>c print bitfield as a condition code
@@ -805,6 +807,8 @@
{ARM_EXT_V6T2, 0xf3af8002, 0xffffffff, "wfe.w"},
{ARM_EXT_V6T2, 0xf3af8003, 0xffffffff, "wfi.w"},
{ARM_EXT_V6T2, 0xf3af9004, 0xffffffff, "sev.w"},
+ {ARM_EXT_V6T2, 0xf3af8000, 0xffffff00, "nop.w\t{%0-7d}"},
+
{ARM_EXT_V6T2, 0xf3bf8f2f, 0xffffffff, "clrex"},
{ARM_EXT_V6T2, 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f"},
{ARM_EXT_V6T2, 0xf3af8600, 0xffffff1f, "cpsid.w\t%7'a%6'i%5'f"},
@@ -819,6 +823,7 @@
{ARM_EXT_V6T2, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d"},
{ARM_EXT_V6T2, 0xf3de8f00, 0xffffff00, "subs\tpc, lr, #%0-7d"},
{ARM_EXT_V6T2, 0xf3808000, 0xffe0f0ff, "msr\t%20?CSPSR_%8'c%9'x%10's%11'f, %16-19r"},
+ {ARM_EXT_V6T2, 0xe8500f00, 0xfff00fff, "ldrex\t%12-15r, [%16-19r]"},
{ARM_EXT_V6T2, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb\t%12-15r, [%16-19r]"},
{ARM_EXT_V6T2, 0xe800c000, 0xffd0ffe0, "srsdb\t#%0-4d%21'!"},
{ARM_EXT_V6T2, 0xe980c000, 0xffd0ffe0, "srsia\t#%0-4d%21'!"},
@@ -828,6 +833,7 @@
{ARM_EXT_V6T2, 0xfa3ff080, 0xfffff0c0, "uxtb16\t%8-11r, %0-3r%R"},
{ARM_EXT_V6T2, 0xfa4ff080, 0xfffff0c0, "sxtb.w\t%8-11r, %0-3r%R"},
{ARM_EXT_V6T2, 0xfa5ff080, 0xfffff0c0, "uxtb.w\t%8-11r, %0-3r%R"},
+ {ARM_EXT_V6T2, 0xe8400000, 0xfff000ff, "strex\t%8-11r, %12-15r, [%16-19r]"},
{ARM_EXT_V6T2, 0xe8d0007f, 0xfff000ff, "ldrexd\t%12-15r, %8-11r, [%16-19r]"},
{ARM_EXT_V6T2, 0xfa80f000, 0xfff0f0f0, "sadd8\t%8-11r, %16-19r, %0-3r"},
{ARM_EXT_V6T2, 0xfa80f010, 0xfff0f0f0, "qadd8\t%8-11r, %16-19r, %0-3r"},
@@ -884,10 +890,10 @@
{ARM_EXT_V6T2, 0xe8c00f40, 0xfff00fe0, "strex%4?hb\t%0-3r, %12-15r, [%16-19r]"},
{ARM_EXT_V6T2, 0xf3200000, 0xfff0f0e0, "ssat16\t%8-11r, #%0-4d, %16-19r"},
{ARM_EXT_V6T2, 0xf3a00000, 0xfff0f0e0, "usat16\t%8-11r, #%0-4d, %16-19r"},
- {ARM_EXT_V6T2, 0xfb20f000, 0xfff0f0e0, "smuad%4?x\t%8-11r, %16-19r, %0-3r"},
+ {ARM_EXT_V6T2, 0xfb20f000, 0xfff0f0e0, "smuad%4'x\t%8-11r, %16-19r, %0-3r"},
{ARM_EXT_V6T2, 0xfb30f000, 0xfff0f0e0, "smulw%4?tb\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfb40f000, 0xfff0f0e0, "smusd%4?x\t%8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfb50f000, 0xfff0f0e0, "smmul%4?r\t%8-11r, %16-19r, %0-3r"},
+ {ARM_EXT_V6T2, 0xfb40f000, 0xfff0f0e0, "smusd%4'x\t%8-11r, %16-19r, %0-3r"},
+ {ARM_EXT_V6T2, 0xfb50f000, 0xfff0f0e0, "smmul%4'r\t%8-11r, %16-19r, %0-3r"},
{ARM_EXT_V6T2, 0xfa00f080, 0xfff0f0c0, "sxtah\t%8-11r, %16-19r, %0-3r%R"},
{ARM_EXT_V6T2, 0xfa10f080, 0xfff0f0c0, "uxtah\t%8-11r, %16-19r, %0-3r%R"},
{ARM_EXT_V6T2, 0xfa20f080, 0xfff0f0c0, "sxtab16\t%8-11r, %16-19r, %0-3r%R"},
@@ -898,12 +904,12 @@
{ARM_EXT_V6T2, 0xf36f0000, 0xffff8020, "bfc\t%8-11r, %E"},
{ARM_EXT_V6T2, 0xea100f00, 0xfff08f00, "tst.w\t%16-19r, %S"},
{ARM_EXT_V6T2, 0xea900f00, 0xfff08f00, "teq\t%16-19r, %S"},
- {ARM_EXT_V6T2, 0xeb100f00, 0xfff08f00, "cmn.w\t%8-11r, %S"},
- {ARM_EXT_V6T2, 0xebb00f00, 0xfff08f00, "cmp.w\t%8-11r, %S"},
+ {ARM_EXT_V6T2, 0xeb100f00, 0xfff08f00, "cmn.w\t%16-19r, %S"},
+ {ARM_EXT_V6T2, 0xebb00f00, 0xfff08f00, "cmp.w\t%16-19r, %S"},
{ARM_EXT_V6T2, 0xf0100f00, 0xfbf08f00, "tst.w\t%16-19r, %M"},
{ARM_EXT_V6T2, 0xf0900f00, 0xfbf08f00, "teq\t%16-19r, %M"},
- {ARM_EXT_V6T2, 0xf1100f00, 0xfbf08f00, "cmn.w\t%8-11r, %M"},
- {ARM_EXT_V6T2, 0xf1b00f00, 0xfbf08f00, "cmp.w\t%8-11r, %M"},
+ {ARM_EXT_V6T2, 0xf1100f00, 0xfbf08f00, "cmn.w\t%16-19r, %M"},
+ {ARM_EXT_V6T2, 0xf1b00f00, 0xfbf08f00, "cmp.w\t%16-19r, %M"},
{ARM_EXT_V6T2, 0xea4f0000, 0xffef8000, "mov%20's.w\t%8-11r, %S"},
{ARM_EXT_V6T2, 0xea6f0000, 0xffef8000, "mvn%20's.w\t%8-11r, %S"},
{ARM_EXT_V6T2, 0xe8c00070, 0xfff000f0, "strexd\t%0-3r, %12-15r, %8-11r, [%16-19r]"},
@@ -915,22 +921,22 @@
{ARM_EXT_V6T2, 0xfbc00000, 0xfff000f0, "smlal\t%12-15r, %8-11r, %16-19r, %0-3r"},
{ARM_EXT_V6T2, 0xfbe00000, 0xfff000f0, "umlal\t%12-15r, %8-11r, %16-19r, %0-3r"},
{ARM_EXT_V6T2, 0xfbe00060, 0xfff000f0, "umaal\t%12-15r, %8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xe8500f00, 0xfff00f00, "ldrex\t%12-15r, %a"},
+ {ARM_EXT_V6T2, 0xe8500f00, 0xfff00f00, "ldrex\t%12-15r, [%16-19r, #%0-7W]"},
{ARM_EXT_V6T2, 0xf7f08000, 0xfff0f000, "smi\t%K"},
{ARM_EXT_V6T2, 0xf04f0000, 0xfbef8000, "mov%20's.w\t%8-11r, %M"},
{ARM_EXT_V6T2, 0xf06f0000, 0xfbef8000, "mvn%20's.w\t%8-11r, %M"},
{ARM_EXT_V6T2, 0xf810f000, 0xff70f000, "pld\t%a"},
- {ARM_EXT_V6T2, 0xfb200000, 0xfff000e0, "smlad%4?x\t%8-11r, %16-19r, %0-3r, %12-15r"},
+ {ARM_EXT_V6T2, 0xfb200000, 0xfff000e0, "smlad%4'x\t%8-11r, %16-19r, %0-3r, %12-15r"},
{ARM_EXT_V6T2, 0xfb300000, 0xfff000e0, "smlaw%4?tb\t%8-11r, %16-19r, %0-3r, %12-15r"},
- {ARM_EXT_V6T2, 0xfb400000, 0xfff000e0, "smlsd%4?x\t%8-11r, %16-19r, %0-3r, %12-15r"},
- {ARM_EXT_V6T2, 0xfb500000, 0xfff000e0, "smmla%4?r\t%8-11r, %16-19r, %0-3r, %12-15r"},
- {ARM_EXT_V6T2, 0xfb600000, 0xfff000e0, "smmls%4?r\t%8-11r, %16-19r, %0-3r, %12-15r"},
- {ARM_EXT_V6T2, 0xfbc000c0, 0xfff000e0, "smlald%4?x\t%12-15r, %8-11r, %16-19r, %0-3r"},
- {ARM_EXT_V6T2, 0xfbd000c0, 0xfff000e0, "smlsld%4?x\t%12-15r, %8-11r, %16-19r, %0-3r"},
+ {ARM_EXT_V6T2, 0xfb400000, 0xfff000e0, "smlsd%4'x\t%8-11r, %16-19r, %0-3r, %12-15r"},
+ {ARM_EXT_V6T2, 0xfb500000, 0xfff000e0, "smmla%4'r\t%8-11r, %16-19r, %0-3r, %12-15r"},
+ {ARM_EXT_V6T2, 0xfb600000, 0xfff000e0, "smmls%4'r\t%8-11r, %16-19r, %0-3r, %12-15r"},
+ {ARM_EXT_V6T2, 0xfbc000c0, 0xfff000e0, "smlald%4'x\t%12-15r, %8-11r, %16-19r, %0-3r"},
+ {ARM_EXT_V6T2, 0xfbd000c0, 0xfff000e0, "smlsld%4'x\t%12-15r, %8-11r, %16-19r, %0-3r"},
{ARM_EXT_V6T2, 0xeac00000, 0xfff08030, "pkhbt\t%8-11r, %16-19r, %S"},
{ARM_EXT_V6T2, 0xeac00020, 0xfff08030, "pkhtb\t%8-11r, %16-19r, %S"},
- {ARM_EXT_V6T2, 0xf3400000, 0xfff08030, "sbfx\t%8-11r, %16-19r, %F"},
- {ARM_EXT_V6T2, 0xf3c00000, 0xfff08030, "ubfx\t%8-11r, %16-19r, %F"},
+ {ARM_EXT_V6T2, 0xf3400000, 0xfff08020, "sbfx\t%8-11r, %16-19r, %F"},
+ {ARM_EXT_V6T2, 0xf3c00000, 0xfff08020, "ubfx\t%8-11r, %16-19r, %F"},
{ARM_EXT_V6T2, 0xf8000e00, 0xff900f00, "str%wt\t%12-15r, %a"},
{ARM_EXT_V6T2, 0xfb100000, 0xfff000c0, "smla%5?tb%4?tb\t%8-11r, %16-19r, %0-3r, %12-15r"},
{ARM_EXT_V6T2, 0xfbc00080, 0xfff000c0, "smlal%5?tb%4?tb\t%12-15r, %8-11r, %16-19r, %0-3r"},
@@ -952,9 +958,9 @@
{ARM_EXT_V6T2, 0xeb000000, 0xffe08000, "add%20's.w\t%8-11r, %16-19r, %S"},
{ARM_EXT_V6T2, 0xeb400000, 0xffe08000, "adc%20's.w\t%8-11r, %16-19r, %S"},
{ARM_EXT_V6T2, 0xeb600000, 0xffe08000, "sbc%20's.w\t%8-11r, %16-19r, %S"},
- {ARM_EXT_V6T2, 0xeba00000, 0xffe08000, "sub%20's.w\t%8-11r, %12-15r, %S"},
+ {ARM_EXT_V6T2, 0xeba00000, 0xffe08000, "sub%20's.w\t%8-11r, %16-19r, %S"},
{ARM_EXT_V6T2, 0xebc00000, 0xffe08000, "rsb%20's\t%8-11r, %16-19r, %S"},
- {ARM_EXT_V6T2, 0xe8400000, 0xfff00000, "strex\t%8-11r, %12-15r, %a"},
+ {ARM_EXT_V6T2, 0xe8400000, 0xfff00000, "strex\t%8-11r, %12-15r, [%16-19r, #%0-7W]"},
{ARM_EXT_V6T2, 0xee000000, 0xef0000f0, "cdp%28'2\tp%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d"},
{ARM_EXT_V6T2, 0xec400000, 0xeff00000, "mcrr%28'2\tp%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
{ARM_EXT_V6T2, 0xec500000, 0xeff00000, "mrrc%28'2\tp%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
@@ -964,16 +970,18 @@
{ARM_EXT_V6T2, 0xf0600000, 0xfbe08000, "orn%20's\t%8-11r, %16-19r, %M"},
{ARM_EXT_V6T2, 0xf0800000, 0xfbe08000, "eor%20's.w\t%8-11r, %16-19r, %M"},
{ARM_EXT_V6T2, 0xf1000000, 0xfbe08000, "add%20's.w\t%8-11r, %16-19r, %M"},
- {ARM_EXT_V6T2, 0xf1400000, 0xfbe08000, "adc%20's.s\t%8-11r, %16-19r, %M"},
+ {ARM_EXT_V6T2, 0xf1400000, 0xfbe08000, "adc%20's.w\t%8-11r, %16-19r, %M"},
{ARM_EXT_V6T2, 0xf1600000, 0xfbe08000, "sbc%20's.w\t%8-11r, %16-19r, %M"},
- {ARM_EXT_V6T2, 0xf1a00000, 0xfbe08000, "sub%20's.w\t%8-11r, %12-15r, %M"},
+ {ARM_EXT_V6T2, 0xf1a00000, 0xfbe08000, "sub%20's.w\t%8-11r, %16-19r, %M"},
{ARM_EXT_V6T2, 0xf1c00000, 0xfbe08000, "rsb%20's\t%8-11r, %16-19r, %M"},
{ARM_EXT_V6T2, 0xe8800000, 0xffd00000, "stmia.w\t%16-19r%21'!, %m"},
{ARM_EXT_V6T2, 0xe8900000, 0xffd00000, "ldmia.w\t%16-19r%21'!, %m"},
{ARM_EXT_V6T2, 0xe9000000, 0xffd00000, "stmdb\t%16-19r%21'!, %m"},
{ARM_EXT_V6T2, 0xe9100000, 0xffd00000, "ldmdb\t%16-19r%21'!, %m"},
- {ARM_EXT_V6T2, 0xe9400000, 0xff500000, "strd\t%12-15r, %8-11r, %a"},
- {ARM_EXT_V6T2, 0xe9500000, 0xff500000, "ldrd\t%12-15r, %8-11r, %a"},
+ {ARM_EXT_V6T2, 0xe9c00000, 0xffd000ff, "strd\t%12-15r, %8-11r, [%16-19r]"},
+ {ARM_EXT_V6T2, 0xe9d00000, 0xffd000ff, "ldrd\t%12-15r, %8-11r, [%16-19r]"},
+ {ARM_EXT_V6T2, 0xe9400000, 0xff500000, "strd\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]"},
+ {ARM_EXT_V6T2, 0xe9500000, 0xff500000, "ldrd\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]"},
{ARM_EXT_V6T2, 0xee000010, 0xef100010, "mcr%28'2\tp%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, %5-7d"},
{ARM_EXT_V6T2, 0xee100010, 0xef100010, "mrc%28'2\tp%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, %5-7d"},
{ARM_EXT_V6T2, 0xf8000000, 0xff100000, "str%w.w\t%12-15r, %a"},
@@ -981,7 +989,11 @@
{ARM_EXT_V6T2, 0xec000000, 0xee100000, "stc%28'2%22'l\tp%8-11d, cr%12-15d, %A"},
{ARM_EXT_V6T2, 0xec100000, 0xee100000, "ldc%28'2%22'l\tp%8-11d, cr%12-15d, %A"},
{ARM_EXT_V6T2, 0xee000000, 0xef000010, "cdp%28'2\tp%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, %5-7d"},
- {ARM_EXT_V6T2, 0xf0008000, 0xf800d000, "b%22-26c.w\t%b"},
+
+ /* Filter out Bcc with cond=E or F, which are used for other instructions. */
+ {ARM_EXT_V6T2, 0xf3c08000, 0xfbc0d000, "undefined (bcc, cond=0xF)"},
+ {ARM_EXT_V6T2, 0xf3808000, 0xfbc0d000, "undefined (bcc, cond=0xE)"},
+ {ARM_EXT_V6T2, 0xf0008000, 0xf800d000, "b%22-25c.w\t%b"},
{ARM_EXT_V6T2, 0xf0009000, 0xf800d000, "b.w\t%B"},
/* These have been 32-bit since the invention of Thumb. */
@@ -2174,18 +2186,18 @@
imm12 |= (given & 0x000000ffu);
imm12 |= (given & 0x00007000u) >> 4;
imm12 |= (given & 0x04000000u) >> 12;
- func (stream, "#%u", imm12);
+ func (stream, "#%u\t; 0x%x", imm12, imm12);
}
break;
case 'M':
{
- unsigned int imm = 0, imm8, mod;
- imm |= (given & 0x000000ffu);
- imm |= (given & 0x00007000u) >> 4;
- imm |= (given & 0x04000000u) >> 12;
- imm8 = (imm & 0x0ff);
- mod = (imm & 0xf00) >> 8;
+ unsigned int bits = 0, imm, imm8, mod;
+ bits |= (given & 0x000000ffu);
+ bits |= (given & 0x00007000u) >> 4;
+ bits |= (given & 0x04000000u) >> 15;
+ imm8 = (bits & 0x0ff);
+ mod = (bits & 0xf00) >> 8;
switch (mod)
{
case 0: imm = imm8; break;
@@ -2193,11 +2205,11 @@
case 2: imm = ((imm8<<24) | (imm8 << 8)); break;
case 3: imm = ((imm8<<24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
default:
- mod = ((mod << 1) | ((imm8 & 0x80) >> 7));
- imm8 |= 0x80;
- imm = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
+ mod = (bits & 0xf80) >> 7;
+ imm8 = (bits & 0x07f) | 0x80;
+ imm = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
}
- func (stream, "#%u", imm);
+ func (stream, "#%u\t; 0x%x", imm, imm);
}
break;
@@ -2206,9 +2218,9 @@
unsigned int imm = 0;
imm |= (given & 0x000000ffu);
imm |= (given & 0x00007000u) >> 4;
- imm |= (given & 0x04000000u) >> 12;
+ imm |= (given & 0x04000000u) >> 15;
imm |= (given & 0x000f0000u) >> 4;
- func (stream, "#%u", imm);
+ func (stream, "#%u\t; 0x%x", imm, imm);
}
break;
@@ -2218,7 +2230,7 @@
imm |= (given & 0x000f0000u) >> 16;
imm |= (given & 0x00000ff0u) >> 0;
imm |= (given & 0x0000000fu) << 12;
- func (stream, "#%u", imm);
+ func (stream, "#%u\t; 0x%x", imm, imm);
}
break;
@@ -2271,7 +2283,7 @@
if (U) /* 12-bit positive immediate offset */
{
if (i12)
- func (stream, ", #+%u", i12);
+ func (stream, ", #%u", i12);
func (stream, "]");
}
else if (Rn == 15) /* 12-bit negative immediate offset */
@@ -2291,7 +2303,7 @@
case 0xE: /* 8-bit positive immediate offset */
if (i8)
- func (stream, ", #+%u", i8);
+ func (stream, ", #%u", i8);
func (stream, "]");
break;
@@ -2301,7 +2313,7 @@
case 0xB: /* 8-bit + preindex with wb */
if (i8)
- func (stream, ", #+%u", i8);
+ func (stream, ", #%u", i8);
func (stream, "]!");
break;
@@ -2310,7 +2322,7 @@
break;
case 0xF: /* 8-bit + postindex */
- func (stream, "], #+%u", i8);
+ func (stream, "], #%u", i8);
break;
case 0xD: /* 8-bit - postindex */
@@ -2415,12 +2427,13 @@
unsigned int J2 = (given & 0x00000800u) >> 11;
unsigned int offset = 0;
- offset |= (S ? 0xfff : 0) << 20;
- offset |= J1 << 19;
- offset |= J2 << 18;
- offset |= (given & 0x001f0000) >> 4;
+ offset |= !S << 20;
+ offset |= J2 << 19;
+ offset |= J1 << 18;
+ offset |= (given & 0x003f0000) >> 4;
offset |= (given & 0x000007ff) << 1;
-
+ offset -= (1 << 20);
+
info->print_address_func ((bfd_vma)offset + pc + 4, info);
}
break;
@@ -2432,11 +2445,12 @@
unsigned int I2 = (given & 0x00000800u) >> 11;
unsigned int offset = 0;
- offset |= (S ? 0xff : 0) << 24;
+ offset |= !S << 24;
offset |= !(I1 ^ S) << 23;
offset |= !(I2 ^ S) << 22;
offset |= (given & 0x03ff0000u) >> 4;
offset |= (given & 0x000007ffu) << 1;
+ offset -= (1 << 24);
info->print_address_func ((bfd_vma)offset + pc + 4, info);
}
@@ -2447,7 +2461,7 @@
unsigned int shift = 0;
shift |= (given & 0x000000c0u) >> 6;
shift |= (given & 0x00007000u) >> 10;
- if (given & 0x00100000u)
+ if (given & 0x00200000u)
func (stream, ", asr #%u", shift);
else if (shift)
func (stream, ", lsl #%u", shift);
@@ -2489,6 +2503,7 @@
switch (*c)
{
case 'd': func (stream, "%u", val); break;
+ case 'W': func (stream, "%u", val * 4); break;
case 'r': func (stream, "%s", arm_regnames[val]); break;
case 'c':