This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

[csl-arm] Thumb-2 libgcc


The attached patch allows building libgcc as pure Thumb-2 code (ie. no Arm 
mode code). It relies on a newish gas with unified assembler support, so may 
need rethinking for mainline.

Tested on arm-none-eabi.
Applied to branches/csl/arm-4_1

Paul

2006-02-07  Paul Brook  <paul@codesourcery.com>

	* config/arm/lib1funcs.asm: Use unified assembly syntax.  Assemble
	"Arm" code as Thumb-2 where appropriate.
	* config/arm/ieee754-df.S: Use unified assembly syntax for Arm code.
	Add Thumb-2 code.
	* config/arm/ieee754-df.S: Ditto.
	* config/arm/libunwind.S: Ditto.
	* config/arm/bpabi.S: Ditto.
Index: gcc/config/arm/ieee754-df.S
===================================================================
--- gcc/config/arm/ieee754-df.S	(revision 110445)
+++ gcc/config/arm/ieee754-df.S	(working copy)
@@ -88,23 +88,26 @@ ARM_FUNC_ALIAS aeabi_dsub subdf3
 ARM_FUNC_START adddf3
 ARM_FUNC_ALIAS aeabi_dadd adddf3
 
-1:	stmfd	sp!, {r4, r5, lr}
+1:	push	{r4, r5, lr}
 
 	@ Look for zeroes, equal values, INF, or NAN.
-	mov	r4, xh, lsl #1
-	mov	r5, yh, lsl #1
+	lsl	r4, xh, #1
+	lsl	r5, yh, #1
 	teq	r4, r5
+	it	eq
 	teqeq	xl, yl
-	orrnes	ip, r4, xl
-	orrnes	ip, r5, yl
-	mvnnes	ip, r4, asr #21
-	mvnnes	ip, r5, asr #21
+	itttt	ne
+	orrsne	ip, r4, xl
+	orrsne	ip, r5, yl
+	mvnsne	ip, r4, asr #21
+	mvnsne	ip, r5, asr #21
 	beq	LSYM(Lad_s)
 
 	@ Compute exponent difference.  Make largest exponent in r4,
 	@ corresponding arg in xh-xl, and positive exponent difference in r5.
-	mov	r4, r4, lsr #21
+	lsr	r4, r4, #21
 	rsbs	r5, r4, r5, lsr #21
+	it	lt
 	rsblt	r5, r5, #0
 	ble	1f
 	add	r4, r4, r5
@@ -119,6 +122,7 @@ ARM_FUNC_ALIAS aeabi_dadd adddf3
 	@ already in xh-xl.  We need up to 54 bit to handle proper rounding
 	@ of 0x1p54 - 1.1.
 	cmp	r5, #54
+	it	hi
 	RETLDM	"r4, r5" hi
 
 	@ Convert mantissa to signed integer.
@@ -127,15 +131,27 @@ ARM_FUNC_ALIAS aeabi_dadd adddf3
 	mov	ip, #0x00100000
 	orr	xh, ip, xh, lsr #12
 	beq	1f
+#if defined(__thumb2__)
+	mov	lr, #0
+	negs	xl, xl
+	sbc	xh, lr, xh
+#else
 	rsbs	xl, xl, #0
 	rsc	xh, xh, #0
+#endif
 1:
 	tst	yh, #0x80000000
 	mov	yh, yh, lsl #12
 	orr	yh, ip, yh, lsr #12
 	beq	1f
+#if defined(__thumb2__)
+	mov	lr, #0
+	negs	yl, yl
+	sbc	yh, lr, yh
+#else
 	rsbs	yl, yl, #0
 	rsc	yh, yh, #0
+#endif
 1:
 	@ If exponent == difference, one or both args were denormalized.
 	@ Since this is not common case, rescale them off line.
@@ -149,27 +165,35 @@ LSYM(Lad_x):
 	@ Shift yh-yl right per r5, add to xh-xl, keep leftover bits into ip.
 	rsbs	lr, r5, #32
 	blt	1f
-	mov	ip, yl, lsl lr
-	adds	xl, xl, yl, lsr r5
+	lsl	ip, yl, lr
+	shiftop adds xl xl yl lsr r5 yl
 	adc	xh, xh, #0
-	adds	xl, xl, yh, lsl lr
-	adcs	xh, xh, yh, asr r5
+	shiftop adds xl xl yh lsl lr yl
+	shiftop adcs xh xh yh asr r5 yh
 	b	2f
 1:	sub	r5, r5, #32
 	add	lr, lr, #32
 	cmp	yl, #1
-	mov	ip, yh, lsl lr
+	lsl	ip, yh, lr
+	it	cs
 	orrcs	ip, ip, #2		@ 2 not 1, to allow lsr #1 later
-	adds	xl, xl, yh, asr r5
+	shiftop adds xl xl yh asr r5 yh
 	adcs	xh, xh, yh, asr #31
 2:
 	@ We now have a result in xh-xl-ip.
 	@ Keep absolute value in xh-xl-ip, sign in r5 (the n bit was set above)
 	and	r5, xh, #0x80000000
 	bpl	LSYM(Lad_p)
+#if defined(__thumb2__)
+	mov	lr, #0
+	negs	ip, ip
+	sbcs	xl, lr, xl
+	sbc	xh, lr, xh
+#else
 	rsbs	ip, ip, #0
 	rscs	xl, xl, #0
 	rsc	xh, xh, #0
+#endif
 
 	@ Determine how to normalize the result.
 LSYM(Lad_p):
@@ -195,7 +219,8 @@ LSYM(Lad_p):
 	@ Pack final result together.
 LSYM(Lad_e):
 	cmp	ip, #0x80000000
-	moveqs	ip, xl, lsr #1
+	it	eq
+	movseq	ip, xl, lsr #1
 	adcs	xl, xl, #0
 	adc	xh, xh, r4, lsl #20
 	orr	xh, xh, r5
@@ -238,9 +263,11 @@ LSYM(Lad_l):
 #else
 
 	teq	xh, #0
+	itt	eq
 	moveq	xh, xl
 	moveq	xl, #0
 	clz	r3, xh
+	it	eq
 	addeq	r3, r3, #32
 	sub	r3, r3, #11
 
@@ -256,20 +283,28 @@ LSYM(Lad_l):
 	@ since a register switch happened above.
 	add	ip, r2, #20
 	rsb	r2, r2, #12
-	mov	xl, xh, lsl ip
-	mov	xh, xh, lsr r2
+	lsl	xl, xh, ip
+	lsr	xh, xh, r2
 	b	3f
 
 	@ actually shift value left 1 to 20 bits, which might also represent
 	@ 32 to 52 bits if counting the register switch that happened earlier.
 1:	add	r2, r2, #20
-2:	rsble	ip, r2, #32
-	mov	xh, xh, lsl r2
+2:	it	le
+	rsble	ip, r2, #32
+	lsl	xh, xh, r2
+#if defined(__thumb2__)
+	lsr	yl, xl, ip
+	itt	le
+	orrle	xh, xh, yl
+#else
 	orrle	xh, xh, xl, lsr ip
-	movle	xl, xl, lsl r2
+#endif
+	lslle	xl, xl, r2
 
 	@ adjust exponent accordingly.
 3:	subs	r4, r4, r3
+	ittt	ge
 	addge	xh, xh, r4, lsl #20
 	orrge	xh, xh, r5
 	RETLDM	"r4, r5" ge
@@ -285,23 +320,23 @@ LSYM(Lad_l):
 	@ shift result right of 1 to 20 bits, sign is in r5.
 	add	r4, r4, #20
 	rsb	r2, r4, #32
-	mov	xl, xl, lsr r4
-	orr	xl, xl, xh, lsl r2
-	orr	xh, r5, xh, lsr r4
+	lsr	xl, xl, r4
+	shiftop orr xl xl xh lsl r2 yh
+	shiftop orr xh r5 xh lsr r4 yh
 	RETLDM	"r4, r5"
 
 	@ shift result right of 21 to 31 bits, or left 11 to 1 bits after
 	@ a register switch from xh to xl.
 1:	rsb	r4, r4, #12
 	rsb	r2, r4, #32
-	mov	xl, xl, lsr r2
-	orr	xl, xl, xh, lsl r4
+	lsr	xl, xl, r2
+	shiftop orr xl xl xh lsl r4 yh
 	mov	xh, r5
 	RETLDM	"r4, r5"
 
 	@ Shift value right of 32 to 64 bits, or 0 to 32 bits after a switch
 	@ from xh to xl.
-2:	mov	xl, xh, lsr r4
+2:	lsr	xl, xh, r4
 	mov	xh, r5
 	RETLDM	"r4, r5"
 
@@ -310,6 +345,7 @@ LSYM(Lad_l):
 LSYM(Lad_d):
 	teq	r4, #0
 	eor	yh, yh, #0x00100000
+	itte	eq
 	eoreq	xh, xh, #0x00100000
 	addeq	r4, r4, #1
 	subne	r5, r5, #1
@@ -318,15 +354,18 @@ LSYM(Lad_d):
 
 LSYM(Lad_s):
 	mvns	ip, r4, asr #21
-	mvnnes	ip, r5, asr #21
+	it	ne
+	mvnsne	ip, r5, asr #21
 	beq	LSYM(Lad_i)
 
 	teq	r4, r5
+	it	eq
 	teqeq	xl, yl
 	beq	1f
 
 	@ Result is x + 0.0 = x or 0.0 + y = y.
 	teq	r4, #0
+	itt	eq
 	moveq	xh, yh
 	moveq	xl, yl
 	RETLDM	"r4, r5"
@@ -334,6 +373,7 @@ LSYM(Lad_s):
 1:	teq	xh, yh
 
 	@ Result is x - x = 0.
+	ittt	ne
 	movne	xh, #0
 	movne	xl, #0
 	RETLDM	"r4, r5" ne
@@ -343,9 +383,11 @@ LSYM(Lad_s):
 	bne	2f
 	movs	xl, xl, lsl #1
 	adcs	xh, xh, xh
+	it	cs
 	orrcs	xh, xh, #0x80000000
 	RETLDM	"r4, r5"
 2:	adds	r4, r4, #(2 << 21)
+	itt	cc
 	addcc	xh, xh, #(1 << 20)
 	RETLDM	"r4, r5" cc
 	and	r5, xh, #0x80000000
@@ -365,13 +407,16 @@ LSYM(Lad_o):
 	@   otherwise return xh-xl (which is INF or -INF)
 LSYM(Lad_i):
 	mvns	ip, r4, asr #21
+	itte	ne
 	movne	xh, yh
 	movne	xl, yl
-	mvneqs	ip, r5, asr #21
+	mvnseq	ip, r5, asr #21
+	itt	ne
 	movne	yh, xh
 	movne	yl, xl
 	orrs	r4, xl, xh, lsl #12
-	orreqs	r5, yl, yh, lsl #12
+	itte	eq
+	orrseq	r5, yl, yh, lsl #12
 	teqeq	xh, yh
 	orrne	xh, xh, #0x00080000	@ quiet NAN
 	RETLDM	"r4, r5"
@@ -385,9 +430,10 @@ ARM_FUNC_START floatunsidf
 ARM_FUNC_ALIAS aeabi_ui2d floatunsidf
 
 	teq	r0, #0
+	itt	eq
 	moveq	r1, #0
 	RETc(eq)
-	stmfd	sp!, {r4, r5, lr}
+	push	{r4, r5, lr}
 	mov	r4, #0x400		@ initial exponent
 	add	r4, r4, #(52-1 - 1)
 	mov	r5, #0			@ sign bit is 0
@@ -404,12 +450,14 @@ ARM_FUNC_START floatsidf
 ARM_FUNC_ALIAS aeabi_i2d floatsidf
 
 	teq	r0, #0
+	itt	eq
 	moveq	r1, #0
 	RETc(eq)
-	stmfd	sp!, {r4, r5, lr}
+	push	{r4, r5, lr}
 	mov	r4, #0x400		@ initial exponent
 	add	r4, r4, #(52-1 - 1)
 	ands	r5, r0, #0x80000000	@ sign bit in r5
+	it	mi
 	rsbmi	r0, r0, #0		@ absolute value
 	.ifnc	xl, r0
 	mov	xl, r0
@@ -427,17 +475,19 @@ ARM_FUNC_ALIAS aeabi_f2d extendsfdf2
 	mov	xh, r2, asr #3		@ stretch exponent
 	mov	xh, xh, rrx		@ retrieve sign bit
 	mov	xl, r2, lsl #28		@ retrieve remaining bits
-	andnes	r3, r2, #0xff000000	@ isolate exponent
+	itttt	ne
+	andsne	r3, r2, #0xff000000	@ isolate exponent
 	teqne	r3, #0xff000000		@ if not 0, check if INF or NAN
 	eorne	xh, xh, #0x38000000	@ fixup exponent otherwise.
 	RETc(ne)			@ and return it.
 
 	teq	r2, #0			@ if actually 0
+	ite	ne
 	teqne	r3, #0xff000000		@ or INF or NAN
 	RETc(eq)			@ we are done already.
 
 	@ value was denormalized.  We can normalize it now.
-	stmfd	sp!, {r4, r5, lr}
+	push	{r4, r5, lr}
 	mov	r4, #0x380		@ setup corresponding exponent
 	and	r5, xh, #0x80000000	@ move sign bit in r5
 	bic	xh, xh, #0x80000000
@@ -451,7 +501,10 @@ ARM_FUNC_ALIAS aeabi_ul2d floatundidf
 
 	orrs	r2, r0, r1
 #if !defined (__VFP_FP__) && !defined(__SOFTFP__)
+	itt	eq
 	mvfeqd	f0, #0.0
+#else
+	it	eq
 #endif
 	RETc(eq)
 
@@ -460,9 +513,9 @@ ARM_FUNC_ALIAS aeabi_ul2d floatundidf
 	@ we can return the result in f0 as well as in r0/r1 for backwards
 	@ compatibility.
 	adr	ip, LSYM(f0_ret)
-	stmfd	sp!, {r4, r5, ip, lr}
+	push	{r4, r5, ip, lr}
 #else
-	stmfd	sp!, {r4, r5, lr}
+	push	{r4, r5, lr}
 #endif
 
 	mov	r5, #0
@@ -473,7 +526,10 @@ ARM_FUNC_ALIAS aeabi_l2d floatdidf
 
 	orrs	r2, r0, r1
 #if !defined (__VFP_FP__) && !defined(__SOFTFP__)
+	itt	eq
 	mvfeqd	f0, #0.0
+#else
+	it	eq
 #endif
 	RETc(eq)
 
@@ -482,15 +538,21 @@ ARM_FUNC_ALIAS aeabi_l2d floatdidf
 	@ we can return the result in f0 as well as in r0/r1 for backwards
 	@ compatibility.
 	adr	ip, LSYM(f0_ret)
-	stmfd	sp!, {r4, r5, ip, lr}
+	push	{r4, r5, ip, lr}
 #else
-	stmfd	sp!, {r4, r5, lr}
+	push	{r4, r5, lr}
 #endif
 
 	ands	r5, ah, #0x80000000	@ sign bit in r5
 	bpl	2f
+#if defined(__thumb2__)
+	movs	r4, #0
+	negs	al, al
+	sbc	ah, r4, ah
+#else
 	rsbs	al, al, #0
 	rsc	ah, ah, #0
+#endif
 2:
 	mov	r4, #0x400		@ initial exponent
 	add	r4, r4, #(52-1 - 1)
@@ -508,16 +570,18 @@ ARM_FUNC_ALIAS aeabi_l2d floatdidf
 	@ The value is too big.  Scale it down a bit...
 	mov	r2, #3
 	movs	ip, ip, lsr #3
+	it	ne
 	addne	r2, r2, #3
 	movs	ip, ip, lsr #3
+	it	ne
 	addne	r2, r2, #3
 	add	r2, r2, ip, lsr #3
 
 	rsb	r3, r2, #32
-	mov	ip, xl, lsl r3
-	mov	xl, xl, lsr r2
-	orr	xl, xl, xh, lsl r3
-	mov	xh, xh, lsr r2
+	lsl	ip, xl, r3
+	lsr	xl, xl, r2
+	shiftop orr xl xl xh lsl r3 lr
+	lsr	xh, xh, r2
 	add	r4, r4, r2
 	b	LSYM(Lad_p)
 
@@ -526,7 +590,7 @@ ARM_FUNC_ALIAS aeabi_l2d floatdidf
 	@ Legacy code expects the result to be returned in f0.  Copy it
 	@ there as well.
 LSYM(f0_ret):
-	stmfd	sp!, {r0, r1}
+	push	{r0, r1}
 	ldfd	f0, [sp], #8
 	RETLDM
 
@@ -543,13 +607,14 @@ LSYM(f0_ret):
 
 ARM_FUNC_START muldf3
 ARM_FUNC_ALIAS aeabi_dmul muldf3
-	stmfd	sp!, {r4, r5, r6, lr}
+	push	{r4, r5, r6, lr}
 
 	@ Mask out exponents, trap any zero/denormal/INF/NAN.
 	mov	ip, #0xff
 	orr	ip, ip, #0x700
 	ands	r4, ip, xh, lsr #20
-	andnes	r5, ip, yh, lsr #20
+	ittte	ne
+	andsne	r5, ip, yh, lsr #20
 	teqne	r4, ip
 	teqne	r5, ip
 	bleq	LSYM(Lml_s)
@@ -565,7 +630,8 @@ ARM_FUNC_ALIAS aeabi_dmul muldf3
 	bic	xh, xh, ip, lsl #21
 	bic	yh, yh, ip, lsl #21
 	orrs	r5, xl, xh, lsl #12
-	orrnes	r5, yl, yh, lsl #12
+	it	ne
+	orrsne	r5, yl, yh, lsl #12
 	orr	xh, xh, #0x00100000
 	orr	yh, yh, #0x00100000
 	beq	LSYM(Lml_1)
@@ -646,6 +712,7 @@ ARM_FUNC_ALIAS aeabi_dmul muldf3
 	@ The LSBs in ip are only significant for the final rounding.
 	@ Fold them into lr.
 	teq	ip, #0
+	it	ne
 	orrne	lr, lr, #1
 
 	@ Adjust result upon the MSB position.
@@ -666,12 +733,14 @@ ARM_FUNC_ALIAS aeabi_dmul muldf3
 
 	@ Check exponent range for under/overflow.
 	subs	ip, r4, #(254 - 1)
+	it	hi
 	cmphi	ip, #0x700
 	bhi	LSYM(Lml_u)
 
 	@ Round the result, merge final exponent.
 	cmp	lr, #0x80000000
-	moveqs	lr, xl, lsr #1
+	it	eq
+	movseq	lr, xl, lsr #1
 	adcs	xl, xl, #0
 	adc	xh, xh, r4, lsl #20
 	RETLDM	"r4, r5, r6"
@@ -683,7 +752,8 @@ LSYM(Lml_1):
 	orr	xl, xl, yl
 	eor	xh, xh, yh
 	subs	r4, r4, ip, lsr #1
-	rsbgts	r5, r4, ip
+	ittt	gt
+	rsbsgt	r5, r4, ip
 	orrgt	xh, xh, r4, lsl #20
 	RETLDM	"r4, r5, r6" gt
 
@@ -698,6 +768,7 @@ LSYM(Lml_u):
 
 	@ Check if denormalized result is possible, otherwise return signed 0.
 	cmn	r4, #(53 + 1)
+	ittt	le
 	movle	xl, #0
 	bicle	xh, xh, #0x7fffffff
 	RETLDM	"r4, r5, r6" le
@@ -712,14 +783,15 @@ LSYM(Lml_u):
 	@ shift result right of 1 to 20 bits, preserve sign bit, round, etc.
 	add	r4, r4, #20
 	rsb	r5, r4, #32
-	mov	r3, xl, lsl r5
-	mov	xl, xl, lsr r4
-	orr	xl, xl, xh, lsl r5
+	lsl	r3, xl, r5
+	lsr	xl, xl, r4
+	shiftop orr xl xl xh lsl r5 r2
 	and	r2, xh, #0x80000000
 	bic	xh, xh, #0x80000000
 	adds	xl, xl, r3, lsr #31
-	adc	xh, r2, xh, lsr r4
+	shiftop adc xh r2 xh lsr r4 r6
 	orrs	lr, lr, r3, lsl #1
+	it	eq
 	biceq	xl, xl, r3, lsr #31
 	RETLDM	"r4, r5, r6"
 
@@ -727,27 +799,29 @@ LSYM(Lml_u):
 	@ a register switch from xh to xl. Then round.
 1:	rsb	r4, r4, #12
 	rsb	r5, r4, #32
-	mov	r3, xl, lsl r4
-	mov	xl, xl, lsr r5
-	orr	xl, xl, xh, lsl r4
+	lsl	r3, xl, r4
+	lsr	xl, xl, r5
+	shiftop orr xl xl xh lsl r4 r2
 	bic	xh, xh, #0x7fffffff
 	adds	xl, xl, r3, lsr #31
 	adc	xh, xh, #0
 	orrs	lr, lr, r3, lsl #1
+	it	eq
 	biceq	xl, xl, r3, lsr #31
 	RETLDM	"r4, r5, r6"
 
 	@ Shift value right of 32 to 64 bits, or 0 to 32 bits after a switch
 	@ from xh to xl.  Leftover bits are in r3-r6-lr for rounding.
 2:	rsb	r5, r4, #32
-	orr	lr, lr, xl, lsl r5
-	mov	r3, xl, lsr r4
-	orr	r3, r3, xh, lsl r5
-	mov	xl, xh, lsr r4
+	shiftop orr lr lr xl lsl r5 r2
+	lsr	r3, xl, r4
+	shiftop orr r3 r3 xh lsl r5 r2
+	lsr	xl, xh, r4
 	bic	xh, xh, #0x7fffffff
-	bic	xl, xl, xh, lsr r4
+	shiftop bic xl xl xh lsr r4 r2
 	add	xl, xl, r3, lsr #31
 	orrs	lr, lr, r3, lsl #1
+	it	eq
 	biceq	xl, xl, r3, lsr #31
 	RETLDM	"r4, r5, r6"
 
@@ -760,15 +834,18 @@ LSYM(Lml_d):
 1:	movs	xl, xl, lsl #1
 	adc	xh, xh, xh
 	tst	xh, #0x00100000
+	it	eq
 	subeq	r4, r4, #1
 	beq	1b
 	orr	xh, xh, r6
 	teq	r5, #0
+	it	ne
 	movne	pc, lr
 2:	and	r6, yh, #0x80000000
 3:	movs	yl, yl, lsl #1
 	adc	yh, yh, yh
 	tst	yh, #0x00100000
+	it	eq
 	subeq	r5, r5, #1
 	beq	3b
 	orr	yh, yh, r6
@@ -778,26 +855,29 @@ LSYM(Lml_s):
 	@ Isolate the INF and NAN cases away
 	teq	r4, ip
 	and	r5, ip, yh, lsr #20
+	it	ne
 	teqne	r5, ip
 	beq	1f
 
 	@ Here, one or more arguments are either denormalized or zero.
 	orrs	r6, xl, xh, lsl #1
-	orrnes	r6, yl, yh, lsl #1
+	it	ne
+	orrsne	r6, yl, yh, lsl #1
 	bne	LSYM(Lml_d)
 
 	@ Result is 0, but determine sign anyway.
 LSYM(Lml_z):
 	eor	xh, xh, yh
-	bic	xh, xh, #0x7fffffff
+	and	xh, xh, #0x80000000
 	mov	xl, #0
 	RETLDM	"r4, r5, r6"
 
 1:	@ One or both args are INF or NAN.
 	orrs	r6, xl, xh, lsl #1
+	itte	eq
 	moveq	xl, yl
 	moveq	xh, yh
-	orrnes	r6, yl, yh, lsl #1
+	orrsne	r6, yl, yh, lsl #1
 	beq	LSYM(Lml_n)		@ 0 * INF or INF * 0 -> NAN
 	teq	r4, ip
 	bne	1f
@@ -806,6 +886,7 @@ LSYM(Lml_z):
 1:	teq	r5, ip
 	bne	LSYM(Lml_i)
 	orrs	r6, yl, yh, lsl #12
+	itt	ne
 	movne	xl, yl
 	movne	xh, yh
 	bne	LSYM(Lml_n)		@ <anything> * NAN -> NAN
@@ -834,13 +915,14 @@ LSYM(Lml_n):
 ARM_FUNC_START divdf3
 ARM_FUNC_ALIAS aeabi_ddiv divdf3
 	
-	stmfd	sp!, {r4, r5, r6, lr}
+	push	{r4, r5, r6, lr}
 
 	@ Mask out exponents, trap any zero/denormal/INF/NAN.
 	mov	ip, #0xff
 	orr	ip, ip, #0x700
 	ands	r4, ip, xh, lsr #20
-	andnes	r5, ip, yh, lsr #20
+	ittte	ne
+	andsne	r5, ip, yh, lsr #20
 	teqne	r4, ip
 	teqne	r5, ip
 	bleq	LSYM(Ldv_s)
@@ -871,6 +953,7 @@ ARM_FUNC_ALIAS aeabi_ddiv divdf3
 	@ Ensure result will land to known bit position.
 	@ Apply exponent bias accordingly.
 	cmp	r5, yh
+	it	eq
 	cmpeq	r6, yl
 	adc	r4, r4, #(255 - 2)
 	add	r4, r4, #0x300
@@ -889,6 +972,7 @@ ARM_FUNC_ALIAS aeabi_ddiv divdf3
 	@ The actual division loop.
 1:	subs	lr, r6, yl
 	sbcs	lr, r5, yh
+	ittt	cs
 	subcs	r6, r6, yl
 	movcs	r5, lr
 	orrcs	xl, xl, ip
@@ -896,6 +980,7 @@ ARM_FUNC_ALIAS aeabi_ddiv divdf3
 	mov	yl, yl, rrx
 	subs	lr, r6, yl
 	sbcs	lr, r5, yh
+	ittt	cs
 	subcs	r6, r6, yl
 	movcs	r5, lr
 	orrcs	xl, xl, ip, lsr #1
@@ -903,6 +988,7 @@ ARM_FUNC_ALIAS aeabi_ddiv divdf3
 	mov	yl, yl, rrx
 	subs	lr, r6, yl
 	sbcs	lr, r5, yh
+	ittt	cs
 	subcs	r6, r6, yl
 	movcs	r5, lr
 	orrcs	xl, xl, ip, lsr #2
@@ -910,6 +996,7 @@ ARM_FUNC_ALIAS aeabi_ddiv divdf3
 	mov	yl, yl, rrx
 	subs	lr, r6, yl
 	sbcs	lr, r5, yh
+	ittt	cs
 	subcs	r6, r6, yl
 	movcs	r5, lr
 	orrcs	xl, xl, ip, lsr #3
@@ -936,18 +1023,21 @@ ARM_FUNC_ALIAS aeabi_ddiv divdf3
 2:
 	@ Be sure result starts in the high word.
 	tst	xh, #0x00100000
+	itt	eq
 	orreq	xh, xh, xl
 	moveq	xl, #0
 3:
 	@ Check exponent range for under/overflow.
 	subs	ip, r4, #(254 - 1)
+	it	hi
 	cmphi	ip, #0x700
 	bhi	LSYM(Lml_u)
 
 	@ Round the result, merge final exponent.
 	subs	ip, r5, yh
-	subeqs	ip, r6, yl
-	moveqs	ip, xl, lsr #1
+	itt	eq
+	subseq	ip, r6, yl
+	movseq	ip, xl, lsr #1
 	adcs	xl, xl, #0
 	adc	xh, xh, r4, lsl #20
 	RETLDM	"r4, r5, r6"
@@ -957,7 +1047,8 @@ LSYM(Ldv_1):
 	and	lr, lr, #0x80000000
 	orr	xh, lr, xh, lsr #12
 	adds	r4, r4, ip, lsr #1
-	rsbgts	r5, r4, ip
+	ittt	gt
+	rsbsgt	r5, r4, ip
 	orrgt	xh, xh, r4, lsl #20
 	RETLDM	"r4, r5, r6" gt
 
@@ -976,6 +1067,7 @@ LSYM(Ldv_u):
 LSYM(Ldv_s):
 	and	r5, ip, yh, lsr #20
 	teq	r4, ip
+	it	eq
 	teqeq	r5, ip
 	beq	LSYM(Lml_n)		@ INF/NAN / INF/NAN -> NAN
 	teq	r4, ip
@@ -996,7 +1088,8 @@ LSYM(Ldv_s):
 	b	LSYM(Lml_n)		@ <anything> / NAN -> NAN
 2:	@ If both are nonzero, we need to normalize and resume above.
 	orrs	r6, xl, xh, lsl #1
-	orrnes	r6, yl, yh, lsl #1
+	it	ne
+	orrsne	r6, yl, yh, lsl #1
 	bne	LSYM(Lml_d)
 	@ One or both arguments are 0.
 	orrs	r4, xl, xh, lsl #1
@@ -1035,14 +1128,17 @@ ARM_FUNC_ALIAS eqdf2 cmpdf2
 	mov	ip, xh, lsl #1
 	mvns	ip, ip, asr #21
 	mov	ip, yh, lsl #1
-	mvnnes	ip, ip, asr #21
+	it	ne
+	mvnsne	ip, ip, asr #21
 	beq	3f
 
 	@ Test for equality.
 	@ Note that 0.0 is equal to -0.0.
 2:	orrs	ip, xl, xh, lsl #1	@ if x == 0.0 or -0.0
-	orreqs	ip, yl, yh, lsl #1	@ and y == 0.0 or -0.0
+	ite	eq
+	orrseq	ip, yl, yh, lsl #1	@ and y == 0.0 or -0.0
 	teqne	xh, yh			@ or xh == yh
+	ittt	eq
 	teqeq	xl, yl			@ and xl == yl
 	moveq	r0, #0			@ then equal.
 	RETc(eq)
@@ -1054,10 +1150,13 @@ ARM_FUNC_ALIAS eqdf2 cmpdf2
 	teq	xh, yh
 
 	@ Compare values if same sign
+	it	pl
 	cmppl	xh, yh
+	it	eq
 	cmpeq	xl, yl
 
 	@ Result:
+	ite	cs
 	movcs	r0, yh, asr #31
 	mvncc	r0, yh, asr #31
 	orr	r0, r0, #1
@@ -1100,14 +1199,15 @@ ARM_FUNC_ALIAS aeabi_cdcmple aeabi_cdcmp
 
 	@ The status-returning routines are required to preserve all
 	@ registers except ip, lr, and cpsr.
-6:	stmfd	sp!, {r0, lr}
+6:	push	{r0, lr}
 	ARM_CALL cmpdf2
 	@ Set the Z flag correctly, and the C flag unconditionally.
-	cmp	 r0, #0
+	cmp	r0, #0
 	@ Clear the C flag if the return value was -1, indicating
 	@ that the first operand was smaller than the second.
-	cmnmi	 r0, #0
-	RETLDM   "r0"
+	it	mi
+	cmnmi	r0, #0
+	RETLDM	"r0"
 
 	FUNC_END aeabi_cdcmple
 	FUNC_END aeabi_cdcmpeq
@@ -1117,6 +1217,7 @@ ARM_FUNC_START	aeabi_dcmpeq
 
 	str	lr, [sp, #-8]!
 	ARM_CALL aeabi_cdcmple
+	ite	eq
 	moveq	r0, #1	@ Equal to.
 	movne	r0, #0	@ Less than, greater than, or unordered.
 	RETLDM
@@ -1127,6 +1228,7 @@ ARM_FUNC_START	aeabi_dcmplt
 
 	str	lr, [sp, #-8]!
 	ARM_CALL aeabi_cdcmple
+	ite	cc
 	movcc	r0, #1	@ Less than.
 	movcs	r0, #0	@ Equal to, greater than, or unordered.
 	RETLDM
@@ -1137,6 +1239,7 @@ ARM_FUNC_START	aeabi_dcmple
 
 	str	lr, [sp, #-8]!
 	ARM_CALL aeabi_cdcmple
+	ite	ls
 	movls	r0, #1  @ Less than or equal to.
 	movhi	r0, #0	@ Greater than or unordered.
 	RETLDM
@@ -1147,6 +1250,7 @@ ARM_FUNC_START	aeabi_dcmpge
 
 	str	lr, [sp, #-8]!
 	ARM_CALL aeabi_cdrcmple
+	ite	ls
 	movls	r0, #1	@ Operand 2 is less than or equal to operand 1.
 	movhi	r0, #0	@ Operand 2 greater than operand 1, or unordered.
 	RETLDM
@@ -1157,6 +1261,7 @@ ARM_FUNC_START	aeabi_dcmpgt
 
 	str	lr, [sp, #-8]!
 	ARM_CALL aeabi_cdrcmple
+	ite	cc
 	movcc	r0, #1	@ Operand 2 is less than operand 1.
 	movcs	r0, #0  @ Operand 2 is greater than or equal to operand 1,
 			@ or they are unordered.
@@ -1211,7 +1316,8 @@ ARM_FUNC_ALIAS aeabi_d2iz fixdfsi
 	orr	r3, r3, #0x80000000
 	orr	r3, r3, xl, lsr #21
 	tst	xh, #0x80000000		@ the sign bit
-	mov	r0, r3, lsr r2
+	lsr	r0, r3, r2
+	it	ne
 	rsbne	r0, r0, #0
 	RET
 
@@ -1221,6 +1327,7 @@ ARM_FUNC_ALIAS aeabi_d2iz fixdfsi
 2:	orrs	xl, xl, xh, lsl #12
 	bne	4f			@ x is NAN.
 3:	ands	r0, xh, #0x80000000	@ the sign bit
+	it	eq
 	moveq	r0, #0x7fffffff		@ maximum signed positive si
 	RET
 
@@ -1251,7 +1358,7 @@ ARM_FUNC_ALIAS aeabi_d2uiz fixunsdfsi
 	mov	r3, xh, lsl #11
 	orr	r3, r3, #0x80000000
 	orr	r3, r3, xl, lsr #21
-	mov	r0, r3, lsr r2
+	lsr	r0, r3, r2
 	RET
 
 1:	mov	r0, #0
@@ -1278,8 +1385,9 @@ ARM_FUNC_ALIAS aeabi_d2f truncdfsf2
 	@ check exponent range.
 	mov	r2, xh, lsl #1
 	subs	r3, r2, #((1023 - 127) << 21)
-	subcss	ip, r3, #(1 << 21)
-	rsbcss	ip, ip, #(254 << 21)
+	itt	cs
+	subscs	ip, r3, #(1 << 21)
+	rsbscs	ip, ip, #(254 << 21)
 	bls	2f			@ value is out of range
 
 1:	@ shift and round mantissa
@@ -1288,6 +1396,7 @@ ARM_FUNC_ALIAS aeabi_d2f truncdfsf2
 	orr	xl, ip, xl, lsr #29
 	cmp	r2, #0x80000000
 	adc	r0, xl, r3, lsl #2
+	it	eq
 	biceq	r0, r0, #1
 	RET
 
@@ -1297,6 +1406,7 @@ ARM_FUNC_ALIAS aeabi_d2f truncdfsf2
 
 	@ check if denormalized value is possible
 	adds	r2, r3, #(23 << 21)
+	itt	lt
 	andlt	r0, xh, #0x80000000	@ too small, return signed 0.
 	RETc(lt)
 
@@ -1305,13 +1415,14 @@ ARM_FUNC_ALIAS aeabi_d2f truncdfsf2
 	mov	r2, r2, lsr #21
 	rsb	r2, r2, #24
 	rsb	ip, r2, #32
-	movs	r3, xl, lsl ip
-	mov	xl, xl, lsr r2
+	lsls	r3, xl, ip
+	lsr	xl, xl, r2
+	it	ne
 	orrne	xl, xl, #1		@ fold r3 for rounding considerations. 
 	mov	r3, xh, lsl #11
 	mov	r3, r3, lsr #11
-	orr	xl, xl, r3, lsl ip
-	mov	r3, r3, lsr r2
+	shiftop orr xl xl r3 lsl ip ip
+	lsr	r3, r3, r2
 	mov	r3, r3, lsl #1
 	b	1b
 
@@ -1319,6 +1430,7 @@ ARM_FUNC_ALIAS aeabi_d2f truncdfsf2
 	mvns	r3, r2, asr #21
 	bne	5f			@ simple overflow
 	orrs	r3, xl, xh, lsl #12
+	ittt	ne
 	movne	r0, #0x7f000000
 	orrne	r0, r0, #0x00c00000
 	RETc(ne)			@ return NAN
Index: gcc/config/arm/lib1funcs.asm
===================================================================
--- gcc/config/arm/lib1funcs.asm	(revision 110445)
+++ gcc/config/arm/lib1funcs.asm	(working copy)
@@ -29,6 +29,10 @@ the Free Software Foundation, 51 Frankli
 Boston, MA 02110-1301, USA.  */
 /* ------------------------------------------------------------------------ */
 
+#if !defined(__thumb__)
+.syntax unified
+#endif
+
 /* We need to know what prefix to add to function names.  */
 
 #ifndef __USER_LABEL_PREFIX__
@@ -186,7 +189,7 @@ LSYM(Lend_fde):
 	.ifc "\regs",""
 	ldr\cond	lr, [sp], #8
 	.else
-	ldm\cond\dirn	sp!, {\regs, lr}
+	pop\cond	{\regs, lr}
 	.endif
 	.ifnc "\unwind", ""
 	/* Mark LR as restored.  */
@@ -194,14 +197,27 @@ LSYM(Lend_fde):
 	.endif
 	bx\cond	lr
 #else
+	/* Caller is responsible for providing IT instruction.  */
 	.ifc "\regs",""
 	ldr\cond	pc, [sp], #8
 	.else
-	ldm\cond\dirn	sp!, {\regs, pc}
+	pop\cond	{\regs, pc}
 	.endif
 #endif
 .endm
 
+/* Perform an arithmetic operation with a variable shift operand.  This
+   requires two instructions and a scratch register on Thumb-2.  */
+#if defined(__thumb2__)
+.macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp
+	\shiftop \tmp, \src2, \shiftreg
+	\name \dest, \src1, \tmp
+.endm
+#else
+.macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp
+	\name \dest, \src1, \src2, \shiftop \shiftreg
+.endm
+#endif
 
 .macro ARM_LDIV0 name
 	str	lr, [sp, #-8]!
@@ -253,11 +269,13 @@ SYM (\name):
 #ifdef __thumb__
 #define THUMB_FUNC .thumb_func
 #define THUMB_CODE .force_thumb
+#define THUMB_SYNTAX .syntax divided
 #else
 #define THUMB_FUNC
 #define THUMB_CODE
+#define THUMB_SYNTAX
 #endif
-	
+
 .macro FUNC_START name
 	.text
 	.globl SYM (__\name)
@@ -265,17 +283,32 @@ SYM (\name):
 	.align 0
 	THUMB_CODE
 	THUMB_FUNC
+	THUMB_SYNTAX
 SYM (__\name):
 .endm
 
 /* Special function that will always be coded in ARM assembly, even if
    in Thumb-only compilation.  */
 
-#if defined(__INTERWORKING_STUBS__)
+#if defined(__thumb2__)
+
+/* For Thumb-2 we build everything in thumb mode.  */
+.macro ARM_FUNC_START name
+       FUNC_START \name
+       .syntax unified
+.endm
+#define EQUIV .thumb_set
+.macro  ARM_CALL name
+	bl	__\name
+.endm
+
+#elif defined(__INTERWORKING_STUBS__)
+
 .macro	ARM_FUNC_START name
 	FUNC_START \name
 	bx	pc
 	nop
+	.syntax unified
 	.arm
 /* A hook to tell gdb that we've switched to ARM mode.  Also used to call
    directly from other local arm routines.  */
@@ -287,12 +320,15 @@ _L__\name:		
 .macro  ARM_CALL name
 	bl	_L__\name
 .endm
-#else
+
+#else /* !(__INTERWORKING_STUBS__ || __thumb2__) */
+
 .macro	ARM_FUNC_START name
 	.text
 	.globl SYM (__\name)
 	TYPE (__\name)
 	.align 0
+	.syntax unified
 	.arm
 SYM (__\name):
 .endm
@@ -300,6 +336,7 @@ SYM (__\name):
 .macro  ARM_CALL name
 	bl	__\name
 .endm
+
 #endif
 
 .macro	FUNC_ALIAS new old
@@ -1176,6 +1213,10 @@ LSYM(Lover12):
 
 #endif /* L_call_via_rX */
 
+/* Don't bother with the old interworking routines for Thumb-2.  */
+/* ??? Maybe only omit these on v7m.  */
+#ifndef __thumb2__
+
 #if defined L_interwork_call_via_rX
 
 /* These labels & instructions are used by the Arm/Thumb interworking code,
@@ -1300,6 +1341,7 @@ LSYM(Lchange_\register):
 	SIZE	(_interwork_call_via_lr)
 	
 #endif /* L_interwork_call_via_rX */
+#endif /* !__thumb2__ */
 #endif /* Arch supports thumb.  */
 
 #ifndef __symbian__
Index: gcc/config/arm/libunwind.S
===================================================================
--- gcc/config/arm/libunwind.S	(revision 110445)
+++ gcc/config/arm/libunwind.S	(working copy)
@@ -43,7 +43,14 @@ ARM_FUNC_START restore_core_regs
 	   this.  */
 	add r1, r0, #52
 	ldmia r1, {r3, r4, r5}  /* {sp, lr, pc}.  */
-#ifdef __INTERWORKING__
+#if defined(__thumb2__)
+	/* Thumb-2 doesn't allow sp in a load-multiple instruction, so push
+	   the target address onto the target stack.  This is safe as
+	   we're always returning to somewhere further up the call stack.  */
+	mov ip, r3
+	mov lr, r4
+	str r5, [ip, #-4]!
+#elif defined(__INTERWORKING__)
 	/* Restore pc into ip.  */
 	mov r2, r5
 	stmfd sp!, {r2, r3, r4}
@@ -52,8 +59,12 @@ ARM_FUNC_START restore_core_regs
 #endif
 	/* Don't bother restoring ip.  */
 	ldmia r0, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp}
+#if defined(__thumb2__)
+	/* Pop the return address off the target stack.  */
+	mov sp, ip
+	pop {pc}
+#elif defined(__INTERWORKING__)
 	/* Pop the three registers we pushed earlier.  */
-#ifdef __INTERWORKING__
 	ldmfd sp, {ip, sp, lr}
 	bx ip
 #else
@@ -82,7 +93,13 @@ ARM_FUNC_START gnu_Unwind_Save_VFP
 	ARM_FUNC_START \name
 	/* Create a phase2_vrs structure.  */
 	/* Split reg push in two to ensure the correct value for sp.  */
+#if defined(__thumb2__)
+	mov ip, sp
+	push {lr} /* PC is ignored.  */
+	push {ip, lr} /* Push original SP and LR.  */
+#else
 	stmfd sp!, {sp, lr, pc}
+#endif
 	stmfd sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip}
 	
 	/* Demand-save flags, plus an extra word for alignment.  */
@@ -91,7 +108,7 @@ ARM_FUNC_START gnu_Unwind_Save_VFP
 
 	/* Point r1 at the block.  Pass r[0..nargs) unchanged.  */
 	add r\nargs, sp, #4
-#if defined(__thumb__)
+#if defined(__thumb__) && !defined(__thumb2__)
 	/* Switch back to thumb mode to avoid interworking hassle.  */
 	adr ip, .L1_\name
 	orr ip, ip, #1
Index: gcc/config/arm/ieee754-sf.S
===================================================================
--- gcc/config/arm/ieee754-sf.S	(revision 110445)
+++ gcc/config/arm/ieee754-sf.S	(working copy)
@@ -71,36 +71,42 @@ ARM_FUNC_ALIAS aeabi_fadd addsf3
 
 1:	@ Look for zeroes, equal values, INF, or NAN.
 	movs	r2, r0, lsl #1
-	movnes	r3, r1, lsl #1
+	itttt	ne
+	movsne	r3, r1, lsl #1
 	teqne	r2, r3
-	mvnnes	ip, r2, asr #24
-	mvnnes	ip, r3, asr #24
+	mvnsne	ip, r2, asr #24
+	mvnsne	ip, r3, asr #24
 	beq	LSYM(Lad_s)
 
 	@ Compute exponent difference.  Make largest exponent in r2,
 	@ corresponding arg in r0, and positive exponent difference in r3.
 	mov	r2, r2, lsr #24
 	rsbs	r3, r2, r3, lsr #24
+	itttt	gt
 	addgt	r2, r2, r3
 	eorgt	r1, r0, r1
 	eorgt	r0, r1, r0
 	eorgt	r1, r0, r1
+	it	lt
 	rsblt	r3, r3, #0
 
 	@ If exponent difference is too large, return largest argument
 	@ already in r0.  We need up to 25 bit to handle proper rounding
 	@ of 0x1p25 - 1.1.
 	cmp	r3, #25
+	it	hi
 	RETc(hi)
 
 	@ Convert mantissa to signed integer.
 	tst	r0, #0x80000000
 	orr	r0, r0, #0x00800000
 	bic	r0, r0, #0xff000000
+	it	ne
 	rsbne	r0, r0, #0
 	tst	r1, #0x80000000
 	orr	r1, r1, #0x00800000
 	bic	r1, r1, #0xff000000
+	it	ne
 	rsbne	r1, r1, #0
 
 	@ If exponent == difference, one or both args were denormalized.
@@ -114,15 +120,21 @@ LSYM(Lad_x):
 
 	@ Shift and add second arg to first arg in r0.
 	@ Keep leftover bits into r1.
-	adds	r0, r0, r1, asr r3
+	shiftop adds r0 r0 r1 asr r3 ip
 	rsb	r3, r3, #32
-	mov	r1, r1, lsl r3
+	lsl	r1, r1, r3
 
 	@ Keep absolute value in r0-r1, sign in r3 (the n bit was set above)
 	and	r3, r0, #0x80000000
 	bpl	LSYM(Lad_p)
+#if defined(__thumb2__)
+	mov	ip, #0
+	negs	r1, r1
+	sbc	r0, ip, r0
+#else
 	rsbs	r1, r1, #0
 	rsc	r0, r0, #0
+#endif
 
 	@ Determine how to normalize the result.
 LSYM(Lad_p):
@@ -147,6 +159,7 @@ LSYM(Lad_p):
 LSYM(Lad_e):
 	cmp	r1, #0x80000000
 	adc	r0, r0, r2, lsl #23
+	it	eq
 	biceq	r0, r0, #1
 	orr	r0, r0, r3
 	RET
@@ -185,16 +198,23 @@ LSYM(Lad_l):
 	clz	ip, r0
 	sub	ip, ip, #8
 	subs	r2, r2, ip
-	mov	r0, r0, lsl ip
+	lsl	r0, r0, ip
 
 #endif
 
 	@ Final result with sign
 	@ If exponent negative, denormalize result.
+	itet	ge
 	addge	r0, r0, r2, lsl #23
 	rsblt	r2, r2, #0
 	orrge	r0, r0, r3
+#if defined(__thumb2__)
+	itt	lt
+	lsrlt	r0, r0, r2
+	orrlt	r0, r3, r0
+#else
 	orrlt	r0, r3, r0, lsr r2
+#endif
 	RET
 
 	@ Fixup and adjust bit position for denormalized arguments.
@@ -202,6 +222,7 @@ LSYM(Lad_l):
 LSYM(Lad_d):
 	teq	r2, #0
 	eor	r1, r1, #0x00800000
+	itte	eq
 	eoreq	r0, r0, #0x00800000
 	addeq	r2, r2, #1
 	subne	r3, r3, #1
@@ -211,7 +232,8 @@ LSYM(Lad_s):
 	mov	r3, r1, lsl #1
 
 	mvns	ip, r2, asr #24
-	mvnnes	ip, r3, asr #24
+	it	ne
+	mvnsne	ip, r3, asr #24
 	beq	LSYM(Lad_i)
 
 	teq	r2, r3
@@ -219,12 +241,14 @@ LSYM(Lad_s):
 
 	@ Result is x + 0.0 = x or 0.0 + y = y.
 	teq	r2, #0
+	it	eq
 	moveq	r0, r1
 	RET
 
 1:	teq	r0, r1
 
 	@ Result is x - x = 0.
+	itt	ne
 	movne	r0, #0
 	RETc(ne)
 
@@ -232,9 +256,11 @@ LSYM(Lad_s):
 	tst	r2, #0xff000000
 	bne	2f
 	movs	r0, r0, lsl #1
+	it	cs
 	orrcs	r0, r0, #0x80000000
 	RET
 2:	adds	r2, r2, #(2 << 24)
+	itt	cc
 	addcc	r0, r0, #(1 << 23)
 	RETc(cc)
 	and	r3, r0, #0x80000000
@@ -253,11 +279,13 @@ LSYM(Lad_o):
 	@   otherwise return r0 (which is INF or -INF)
 LSYM(Lad_i):
 	mvns	r2, r2, asr #24
+	itet	ne
 	movne	r0, r1
-	mvneqs	r3, r3, asr #24
+	mvnseq	r3, r3, asr #24
 	movne	r1, r0
 	movs	r2, r0, lsl #9
-	moveqs	r3, r1, lsl #9
+	itte	eq
+	movseq	r3, r1, lsl #9
 	teqeq	r0, r1
 	orrne	r0, r0, #0x00400000	@ quiet NAN
 	RET
@@ -278,9 +306,11 @@ ARM_FUNC_START floatsisf
 ARM_FUNC_ALIAS aeabi_i2f floatsisf
 	
 	ands	r3, r0, #0x80000000
+	it	mi
 	rsbmi	r0, r0, #0
 
 1:	movs	ip, r0
+	it	eq
 	RETc(eq)
 
 	@ Add initial exponent to sign
@@ -302,7 +332,10 @@ ARM_FUNC_ALIAS aeabi_ul2f floatundisf
 
 	orrs	r2, r0, r1
 #if !defined (__VFP_FP__) && !defined(__SOFTFP__)
+	itt	eq
 	mvfeqs	f0, #0.0
+#else
+	it	eq
 #endif
 	RETc(eq)
 
@@ -314,14 +347,23 @@ ARM_FUNC_ALIAS aeabi_l2f floatdisf
 
 	orrs	r2, r0, r1
 #if !defined (__VFP_FP__) && !defined(__SOFTFP__)
+	itt	eq
 	mvfeqs	f0, #0.0
+#else
+	it	eq
 #endif
 	RETc(eq)
 
 	ands	r3, ah, #0x80000000	@ sign bit in r3
 	bpl	1f
+#if defined(__thumb2__)
+	movs	r2, #0
+	negs	al, al
+	sbc	ah, r2, ah
+#else
 	rsbs	al, al, #0
 	rsc	ah, ah, #0
+#endif
 1:
 #if !defined (__VFP_FP__) && !defined(__SOFTFP__)
 	@ For hard FPA code we want to return via the tail below so that
@@ -332,12 +374,14 @@ ARM_FUNC_ALIAS aeabi_l2f floatdisf
 #endif
 
 	movs	ip, ah
+	ittt	eq
 	moveq	ip, al
 	moveq	ah, al
 	moveq	al, #0
 
 	@ Add initial exponent to sign
 	orr	r3, r3, #((127 + 23 + 32) << 23)
+	it	eq
 	subeq	r3, r3, #(32 << 23)
 2:	sub	r3, r3, #(1 << 23)
 
@@ -345,15 +389,19 @@ ARM_FUNC_ALIAS aeabi_l2f floatdisf
 
 	mov	r2, #23
 	cmp	ip, #(1 << 16)
+	itt	hs
 	movhs	ip, ip, lsr #16
 	subhs	r2, r2, #16
 	cmp	ip, #(1 << 8)
+	itt	hs
 	movhs	ip, ip, lsr #8
 	subhs	r2, r2, #8
 	cmp	ip, #(1 << 4)
+	itt	hs
 	movhs	ip, ip, lsr #4
 	subhs	r2, r2, #4
 	cmp	ip, #(1 << 2)
+	ite	hs
 	subhs	r2, r2, #2
 	sublo	r2, r2, ip, lsr #1
 	subs	r2, r2, ip, lsr #3
@@ -368,19 +416,21 @@ ARM_FUNC_ALIAS aeabi_l2f floatdisf
 	sub	r3, r3, r2, lsl #23
 	blt	3f
 
-	add	r3, r3, ah, lsl r2
-	mov	ip, al, lsl r2
+	shiftop add r3 r3 ah lsl r2 ip
+	lsl	ip, al, r2
 	rsb	r2, r2, #32
 	cmp	ip, #0x80000000
-	adc	r0, r3, al, lsr r2
+	shiftop adc r0 r3 al lsr r2 r2
+	it	eq
 	biceq	r0, r0, #1
 	RET
 
 3:	add	r2, r2, #32
-	mov	ip, ah, lsl r2
+	lsl	ip, ah, r2
 	rsb	r2, r2, #32
 	orrs	al, al, ip, lsl #1
-	adc	r0, r3, ah, lsr r2
+	shiftop adc r0 r3 ah lsr r2 r2
+	it	eq
 	biceq	r0, r0, ip, lsr #31
 	RET
 
@@ -408,7 +458,8 @@ ARM_FUNC_ALIAS aeabi_fmul mulsf3
 	@ Mask out exponents, trap any zero/denormal/INF/NAN.
 	mov	ip, #0xff
 	ands	r2, ip, r0, lsr #23
-	andnes	r3, ip, r1, lsr #23
+	ittt	ne
+	andsne	r3, ip, r1, lsr #23
 	teqne	r2, ip
 	teqne	r3, ip
 	beq	LSYM(Lml_s)
@@ -424,7 +475,8 @@ LSYM(Lml_x):
 	@ If power of two, branch to a separate path.
 	@ Make up for final alignment.
 	movs	r0, r0, lsl #9
-	movnes	r1, r1, lsl #9
+	it	ne
+	movsne	r1, r1, lsl #9
 	beq	LSYM(Lml_1)
 	mov	r3, #0x08000000
 	orr	r0, r3, r0, lsr #5
@@ -436,7 +488,7 @@ LSYM(Lml_x):
 	and	r3, ip, #0x80000000
 
 	@ Well, no way to make it shorter without the umull instruction.
-	stmfd	sp!, {r3, r4, r5}
+	push	{r3, r4, r5}
 	mov	r4, r0, lsr #16
 	mov	r5, r1, lsr #16
 	bic	r0, r0, r4, lsl #16
@@ -447,7 +499,7 @@ LSYM(Lml_x):
 	mla	r0, r4, r1, r0
 	adds	r3, r3, r0, lsl #16
 	adc	r1, ip, r0, lsr #16
-	ldmfd	sp!, {r0, r4, r5}
+	pop	{r0, r4, r5}
 
 #else
 
@@ -461,6 +513,7 @@ LSYM(Lml_x):
 
 	@ Adjust result upon the MSB position.
 	cmp	r1, #(1 << 23)
+	ittt	cc
 	movcc	r1, r1, lsl #1
 	orrcc	r1, r1, r3, lsr #31
 	movcc	r3, r3, lsl #1
@@ -476,6 +529,7 @@ LSYM(Lml_x):
 	@ Round the result, merge final exponent.
 	cmp	r3, #0x80000000
 	adc	r0, r0, r2, lsl #23
+	it	eq
 	biceq	r0, r0, #1
 	RET
 
@@ -483,11 +537,13 @@ LSYM(Lml_x):
 LSYM(Lml_1):
 	teq	r0, #0
 	and	ip, ip, #0x80000000
+	it	eq
 	moveq	r1, r1, lsl #9
 	orr	r0, ip, r0, lsr #9
 	orr	r0, r0, r1, lsr #9
 	subs	r2, r2, #127
-	rsbgts	r3, r2, #255
+	ittt	gt
+	rsbsgt	r3, r2, #255
 	orrgt	r0, r0, r2, lsl #23
 	RETc(gt)
 
@@ -502,18 +558,20 @@ LSYM(Lml_u):
 
 	@ Check if denormalized result is possible, otherwise return signed 0.
 	cmn	r2, #(24 + 1)
+	itt	le
 	bicle	r0, r0, #0x7fffffff
 	RETc(le)
 
 	@ Shift value right, round, etc.
 	rsb	r2, r2, #0
 	movs	r1, r0, lsl #1
-	mov	r1, r1, lsr r2
+	lsr	r1, r1, r2
 	rsb	r2, r2, #32
-	mov	ip, r0, lsl r2
+	lsl	ip, r0, r2
 	movs	r0, r1, rrx
 	adc	r0, r0, #0
 	orrs	r3, r3, ip, lsl #1
+	it	eq
 	biceq	r0, r0, ip, lsr #31
 	RET
 
@@ -522,14 +580,16 @@ LSYM(Lml_u):
 LSYM(Lml_d):
 	teq	r2, #0
 	and	ip, r0, #0x80000000
-1:	moveq	r0, r0, lsl #1
+1:	ittt	eq
+	moveq	r0, r0, lsl #1
 	tsteq	r0, #0x00800000
 	subeq	r2, r2, #1
 	beq	1b
 	orr	r0, r0, ip
 	teq	r3, #0
 	and	ip, r1, #0x80000000
-2:	moveq	r1, r1, lsl #1
+2:	ittt	eq
+	moveq	r1, r1, lsl #1
 	tsteq	r1, #0x00800000
 	subeq	r3, r3, #1
 	beq	2b
@@ -540,12 +600,14 @@ LSYM(Lml_s):
 	@ Isolate the INF and NAN cases away
 	and	r3, ip, r1, lsr #23
 	teq	r2, ip
+	it	ne
 	teqne	r3, ip
 	beq	1f
 
 	@ Here, one or more arguments are either denormalized or zero.
 	bics	ip, r0, #0x80000000
-	bicnes	ip, r1, #0x80000000
+	it	ne
+	bicsne	ip, r1, #0x80000000
 	bne	LSYM(Lml_d)
 
 	@ Result is 0, but determine sign anyway.
@@ -556,6 +618,7 @@ LSYM(Lml_z):
 
 1:	@ One or both args are INF or NAN.
 	teq	r0, #0x0
+	itett	ne
 	teqne	r0, #0x80000000
 	moveq	r0, r1
 	teqne	r1, #0x0
@@ -568,6 +631,7 @@ LSYM(Lml_z):
 1:	teq	r3, ip
 	bne	LSYM(Lml_i)
 	movs	r3, r1, lsl #9
+	it	ne
 	movne	r0, r1
 	bne	LSYM(Lml_n)		@ <anything> * NAN -> NAN
 
@@ -597,7 +661,8 @@ ARM_FUNC_ALIAS aeabi_fdiv divsf3
 	@ Mask out exponents, trap any zero/denormal/INF/NAN.
 	mov	ip, #0xff
 	ands	r2, ip, r0, lsr #23
-	andnes	r3, ip, r1, lsr #23
+	ittt	ne
+	andsne	r3, ip, r1, lsr #23
 	teqne	r2, ip
 	teqne	r3, ip
 	beq	LSYM(Ldv_s)
@@ -624,25 +689,31 @@ LSYM(Ldv_x):
 	@ Ensure result will land to known bit position.
 	@ Apply exponent bias accordingly.
 	cmp	r3, r1
+	it	cc
 	movcc	r3, r3, lsl #1
 	adc	r2, r2, #(127 - 2)
 
 	@ The actual division loop.
 	mov	ip, #0x00800000
 1:	cmp	r3, r1
+	itt	cs
 	subcs	r3, r3, r1
 	orrcs	r0, r0, ip
 	cmp	r3, r1, lsr #1
+	itt	cs
 	subcs	r3, r3, r1, lsr #1
 	orrcs	r0, r0, ip, lsr #1
 	cmp	r3, r1, lsr #2
+	itt	cs
 	subcs	r3, r3, r1, lsr #2
 	orrcs	r0, r0, ip, lsr #2
 	cmp	r3, r1, lsr #3
+	itt	cs
 	subcs	r3, r3, r1, lsr #3
 	orrcs	r0, r0, ip, lsr #3
 	movs	r3, r3, lsl #4
-	movnes	ip, ip, lsr #4
+	it	ne
+	movsne	ip, ip, lsr #4
 	bne	1b
 
 	@ Check exponent for under/overflow.
@@ -652,6 +723,7 @@ LSYM(Ldv_x):
 	@ Round the result, merge final exponent.
 	cmp	r3, r1
 	adc	r0, r0, r2, lsl #23
+	it	eq
 	biceq	r0, r0, #1
 	RET
 
@@ -660,7 +732,8 @@ LSYM(Ldv_1):
 	and	ip, ip, #0x80000000
 	orr	r0, ip, r0, lsr #9
 	adds	r2, r2, #127
-	rsbgts	r3, r2, #255
+	ittt	gt
+	rsbsgt	r3, r2, #255
 	orrgt	r0, r0, r2, lsl #23
 	RETc(gt)
 
@@ -674,14 +747,16 @@ LSYM(Ldv_1):
 LSYM(Ldv_d):
 	teq	r2, #0
 	and	ip, r0, #0x80000000
-1:	moveq	r0, r0, lsl #1
+1:	ittt	eq
+	moveq	r0, r0, lsl #1
 	tsteq	r0, #0x00800000
 	subeq	r2, r2, #1
 	beq	1b
 	orr	r0, r0, ip
 	teq	r3, #0
 	and	ip, r1, #0x80000000
-2:	moveq	r1, r1, lsl #1
+2:	ittt	eq
+	moveq	r1, r1, lsl #1
 	tsteq	r1, #0x00800000
 	subeq	r3, r3, #1
 	beq	2b
@@ -707,7 +782,8 @@ LSYM(Ldv_s):
 	b	LSYM(Lml_n)		@ <anything> / NAN -> NAN
 2:	@ If both are nonzero, we need to normalize and resume above.
 	bics	ip, r0, #0x80000000
-	bicnes	ip, r1, #0x80000000
+	it	ne
+	bicsne	ip, r1, #0x80000000
 	bne	LSYM(Ldv_d)
 	@ One or both arguments are zero.
 	bics	r2, r0, #0x80000000
@@ -759,18 +835,24 @@ ARM_FUNC_ALIAS eqsf2 cmpsf2
 	mov	r2, r0, lsl #1
 	mov	r3, r1, lsl #1
 	mvns	ip, r2, asr #24
-	mvnnes	ip, r3, asr #24
+	it	ne
+	mvnsne	ip, r3, asr #24
 	beq	3f
 
 	@ Compare values.
 	@ Note that 0.0 is equal to -0.0.
 2:	orrs	ip, r2, r3, lsr #1	@ test if both are 0, clear C flag
+	it	ne
 	teqne	r0, r1			@ if not 0 compare sign
-	subpls	r0, r2, r3		@ if same sign compare values, set r0
+	it	pl
+	subspl	r0, r2, r3		@ if same sign compare values, set r0
 
 	@ Result:
+	it	hi
 	movhi	r0, r1, asr #31
+	it	lo
 	mvnlo	r0, r1, asr #31
+	it	ne
 	orrne	r0, r0, #1
 	RET
 
@@ -806,14 +888,15 @@ ARM_FUNC_ALIAS aeabi_cfcmple aeabi_cfcmp
 
 	@ The status-returning routines are required to preserve all
 	@ registers except ip, lr, and cpsr.
-6:	stmfd	sp!, {r0, r1, r2, r3, lr}
+6:	push	{r0, r1, r2, r3, lr}
 	ARM_CALL cmpsf2
 	@ Set the Z flag correctly, and the C flag unconditionally.
-	cmp	 r0, #0
+	cmp	r0, #0
 	@ Clear the C flag if the return value was -1, indicating
 	@ that the first operand was smaller than the second.
-	cmnmi	 r0, #0
-	RETLDM  "r0, r1, r2, r3"
+	it	mi
+	cmnmi	r0, #0
+	RETLDM	"r0, r1, r2, r3"
 
 	FUNC_END aeabi_cfcmple
 	FUNC_END aeabi_cfcmpeq
@@ -823,6 +906,7 @@ ARM_FUNC_START	aeabi_fcmpeq
 
 	str	lr, [sp, #-8]!
 	ARM_CALL aeabi_cfcmple
+	ite	eq
 	moveq	r0, #1	@ Equal to.
 	movne	r0, #0	@ Less than, greater than, or unordered.
 	RETLDM
@@ -833,6 +917,7 @@ ARM_FUNC_START	aeabi_fcmplt
 
 	str	lr, [sp, #-8]!
 	ARM_CALL aeabi_cfcmple
+	ite	cc
 	movcc	r0, #1	@ Less than.
 	movcs	r0, #0	@ Equal to, greater than, or unordered.
 	RETLDM
@@ -843,6 +928,7 @@ ARM_FUNC_START	aeabi_fcmple
 
 	str	lr, [sp, #-8]!
 	ARM_CALL aeabi_cfcmple
+	ite	ls
 	movls	r0, #1  @ Less than or equal to.
 	movhi	r0, #0	@ Greater than or unordered.
 	RETLDM
@@ -853,6 +939,7 @@ ARM_FUNC_START	aeabi_fcmpge
 
 	str	lr, [sp, #-8]!
 	ARM_CALL aeabi_cfrcmple
+	ite	ls
 	movls	r0, #1	@ Operand 2 is less than or equal to operand 1.
 	movhi	r0, #0	@ Operand 2 greater than operand 1, or unordered.
 	RETLDM
@@ -863,6 +950,7 @@ ARM_FUNC_START	aeabi_fcmpgt
 
 	str	lr, [sp, #-8]!
 	ARM_CALL aeabi_cfrcmple
+	ite	cc
 	movcc	r0, #1	@ Operand 2 is less than operand 1.
 	movcs	r0, #0  @ Operand 2 is greater than or equal to operand 1,
 			@ or they are unordered.
@@ -914,7 +1002,8 @@ ARM_FUNC_ALIAS aeabi_f2iz fixsfsi
 	mov	r3, r0, lsl #8
 	orr	r3, r3, #0x80000000
 	tst	r0, #0x80000000		@ the sign bit
-	mov	r0, r3, lsr r2
+	lsr	r0, r3, r2
+	it	ne
 	rsbne	r0, r0, #0
 	RET
 
@@ -926,6 +1015,7 @@ ARM_FUNC_ALIAS aeabi_f2iz fixsfsi
 	movs	r2, r0, lsl #9
 	bne	4f			@ r0 is NAN.
 3:	ands	r0, r0, #0x80000000	@ the sign bit
+	it	eq
 	moveq	r0, #0x7fffffff		@ the maximum signed positive si
 	RET
 
@@ -954,7 +1044,7 @@ ARM_FUNC_ALIAS aeabi_f2uiz fixunssfsi
 	@ scale the value
 	mov	r3, r0, lsl #8
 	orr	r3, r3, #0x80000000
-	mov	r0, r3, lsr r2
+	lsr	r0, r3, r2
 	RET
 
 1:	mov	r0, #0
Index: gcc/config/arm/bpabi.S
===================================================================
--- gcc/config/arm/bpabi.S	(revision 110445)
+++ gcc/config/arm/bpabi.S	(working copy)
@@ -44,7 +44,8 @@
 ARM_FUNC_START aeabi_lcmp
 	subs	ip, xxl, yyl
 	sbcs	ip, xxh, yyh
-	subeqs  ip, xxl, yyl
+	it	eq
+	subseq  ip, xxl, yyl
 	mov	r0, ip
 	RET
 	FUNC_END aeabi_lcmp
@@ -55,12 +56,18 @@ ARM_FUNC_START aeabi_lcmp
 
 ARM_FUNC_START aeabi_ulcmp
 	cmp	xxh, yyh
+	it	lo
 	movlo	r0, #-1
+	it	hi
 	movhi	r0, #1
+	it	ne
 	RETc(ne)
 	cmp	xxl, yyl
+	it	lo
 	movlo	r0, #-1
+	it	hi
 	movhi	r0, #1
+	it	eq
 	moveq	r0, #0
 	RET
 	FUNC_END aeabi_ulcmp
@@ -71,11 +78,16 @@ ARM_FUNC_START aeabi_ulcmp
 
 ARM_FUNC_START aeabi_ldivmod
 	sub sp, sp, #8
-	stmfd sp!, {sp, lr}
+#if defined(__thumb2__)
+	mov ip, sp
+	push {ip, lr}
+#else
+	push {sp, lr}
+#endif
 	bl SYM(__gnu_ldivmod_helper) __PLT__
 	ldr lr, [sp, #4]
 	add sp, sp, #8
-	ldmfd sp!, {r2, r3}
+	pop {r2, r3}
 	RET
 	
 #endif /* L_aeabi_ldivmod */
@@ -84,11 +96,16 @@ ARM_FUNC_START aeabi_ldivmod
 
 ARM_FUNC_START aeabi_uldivmod
 	sub sp, sp, #8
-	stmfd sp!, {sp, lr}
+#if defined(__thumb2__)
+	mov ip, sp
+	push {ip, lr}
+#else
+	push {sp, lr}
+#endif
 	bl SYM(__gnu_uldivmod_helper) __PLT__
 	ldr lr, [sp, #4]
 	add sp, sp, #8
-	ldmfd sp!, {r2, r3}
+	pop {r2, r3}
 	RET
 	
 #endif /* L_aeabi_divmod */

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