This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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':

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]