
// ****************************************************************************
//
//                           Test instruction timings
//
// ****************************************************************************

// configuration
#include "config.h"

	.syntax unified
	.cpu cortex-m0plus
	.thumb			// use 16-bit instructions

	.section .data

.global TestData
	.lcomm	TestData,2048

	.section .text		// code section

.global TestMove1
TestMove1:
	.rept	REPT
	movs	r0,#243		// [1]
	.endr
	bx	lr		// [2]

.global TestMove2
TestMove2:
	.rept	REPT
	movs	r2,r3		// [1]
	.endr
	bx	lr		// [2]

.global TestMove3
TestMove3:
	.rept	REPT
	mov	r2,r3		// [1]
	.endr
	bx	lr		// [2]

	.align	2		// align to 4 bytes
.global TestMove4
TestMove4:
	adr	r0,TestMove4_1	// [1]
	mov	pc,r0		// [2]	
TestMove4_1:
	adr	r0,TestMove4_2	// [1]
	mov	pc,r0		// [2]	
TestMove4_2:
	adr	r0,TestMove4_3	// [1]
	mov	pc,r0		// [2]	
TestMove4_3:
	adr	r0,TestMove4_4	// [1]
	mov	pc,r0		// [2]	
TestMove4_4:
	adr	r0,TestMove4_5	// [1]
	mov	pc,r0		// [2]	
TestMove4_5:
	adr	r0,TestMove4_6	// [1]
	mov	pc,r0		// [2]	
TestMove4_6:
	adr	r0,TestMove4_7	// [1]
	mov	pc,r0		// [2]	
TestMove4_7:
	adr	r0,TestMove4_8	// [1]
	mov	pc,r0		// [2]	
TestMove4_8:
	adr	r0,TestMove4_9	// [1]
	mov	pc,r0		// [2]	
TestMove4_9:
	adr	r0,TestMove4_10	// [1]
	mov	pc,r0		// [2]	
TestMove4_10:
	bx	lr		// [2]

.global TestAdd1
TestAdd1:
	.rept	REPT
	adds	r0,r1,#6	// [1]
	.endr
	bx	lr		// [2]

.global TestAdd2
TestAdd2:
	.rept	REPT
	adds	r0,r1,r2	// [1]
	.endr
	bx	lr		// [2]

.global TestAdd3
TestAdd3:
	.rept	REPT
	add	r0,r1		// [1]
	.endr
	bx	lr		// [2]

	.align	2		// align to 4 bytes
.global TestAdd4
TestAdd4:
	movs	r0,#0		// [1]
	.rept	10
	add	pc,r0		// [2]
	nop			// [1]
	nop			// [1] - jump here
	.endr
	bx	lr		// [2]

.global TestAdd5
TestAdd5:
	.rept	REPT
	adds	r0,#255		// [1]
	.endr
	bx	lr		// [2]

.global TestAdd6
TestAdd6:
	.rept	REPT
	adcs	r0,r1		// [1]
	.endr
	bx	lr		// [2]

.global TestAdd7
TestAdd7:
	.rept	REPT
	add	sp,#0		// [1]
	.endr
	bx	lr		// [2]

.global TestAdd8
TestAdd8:
	.rept	REPT
	add	r0,sp,#1020	// [1]
	.endr
	bx	lr		// [2]

.global TestAdd9
TestAdd9:
	.rept	REPT
	adr	r0,TestAdd9_Test // [1]
	.endr
	bx	lr		// [2]

	.align 2
TestAdd9_Test:

.global TestSub1
TestSub1:
	.rept	REPT
	subs	r0,r1,r2	// [1]
	.endr
	bx	lr		// [2]

.global TestSub2
TestSub2:
	.rept	REPT
	subs	r0,r1,#6	// [1]
	.endr
	bx	lr		// [2]

.global TestSub3
TestSub3:
	.rept	REPT
	subs	r0,#255		// [1]
	.endr
	bx	lr		// [2]

.global TestSub4
TestSub4:
	.rept	REPT
	sbcs	r0,r1		// [1]
	.endr
	bx	lr		// [2]

.global TestSub5
TestSub5:
	.rept	REPT
	sub	sp,#0		// [1]
	.endr
	bx	lr		// [2]

.global TestSub6
TestSub6:
	.rept	REPT
	negs	r0,r1		// [1]
	.endr
	bx	lr		// [2]

.global TestMul
TestMul:
	.rept	REPT
	muls	r0,r1		// [1]
	.endr
	bx	lr		// [2]

.global TestCmp1
TestCmp1:
	.rept	REPT
	cmp	r0,r1		// [1]
	.endr
	bx	lr		// [2]

.global TestCmp2
TestCmp2:
	.rept	REPT
	cmn	r0,r1		// [1]
	.endr
	bx	lr		// [2]

.global TestCmp3
TestCmp3:
	.rept	REPT
	cmp	r0,#245		// [1]
	.endr
	bx	lr		// [2]

.global TestAnd
TestAnd:
	.rept	REPT
	ands	r0,r1		// [1]
	.endr
	bx	lr		// [2]

.global TestEor
TestEor:
	.rept	REPT
	eors	r0,r1		// [1]
	.endr
	bx	lr		// [2]

.global TestOrr
TestOrr:
	.rept	REPT
	orrs	r0,r1		// [1]
	.endr
	bx	lr		// [2]

.global TestBic
TestBic:
	.rept	REPT
	ands	r0,r1		// [1]
	.endr
	bx	lr		// [2]

.global TestMvn
TestMvn:
	.rept	REPT
	mvns	r0,r1		// [1]
	.endr
	bx	lr		// [2]

.global TestTst
TestTst:
	.rept	REPT
	tst	r0,r1		// [1]
	.endr
	bx	lr		// [2]

.global TestLsls1
TestLsls1:
	.rept	REPT
	lsls	r0,r1,#31	// [1]
	.endr
	bx	lr		// [2]

.global TestLsls2
TestLsls2:
	.rept	REPT
	lsls	r0,r2		// [1]
	.endr
	bx	lr		// [2]

.global TestLsrs1
TestLsrs1:
	.rept	REPT
	lsrs	r0,r1,#31	// [1]
	.endr
	bx	lr		// [2]

.global TestLsrs2
TestLsrs2:
	.rept	REPT
	lsrs	r0,r2		// [1]
	.endr
	bx	lr		// [2]

.global TestAsrs1
TestAsrs1:
	.rept	REPT
	asrs	r0,r1,#31	// [1]
	.endr
	bx	lr		// [2]

.global TestAsrs2
TestAsrs2:
	.rept	REPT
	asrs	r0,r2		// [1]
	.endr
	bx	lr		// [2]

.global TestRors
TestRors:
	.rept	REPT
	rors	r0,r2		// [1]
	.endr
	bx	lr		// [2]

.global TestLdr1
TestLdr1:
	ldr	r2,TestDataAddr	// [2]
	.rept	REPT
	ldr	r0,[r2,#4]	// [2]
	.endr
	bx	lr		// [2]

.global TestLdr1B
TestLdr1B:
	ldr	r2,TestDataAddr	// [2]
	ldr	r2,[r2,#0]	// [2]
	.rept	REPT
	ldr	r0,[r2,#0]	// [2]
	.endr
	bx	lr		// [2]

	.align 2
TestDataAddr:
	.word	TestData

.global TestLdr2
TestLdr2:
	ldr	r2,TestDataAddr2 // [2]
	.rept	REPT
	ldrh	r0,[r2,#4]	// [2]
	.endr
	bx	lr		// [2]

.global TestLdr2B
TestLdr2B:
	ldr	r2,TestDataAddr2 // [2]
	ldr	r2,[r2,#0]	// [2]
	.rept	REPT
	ldrh	r0,[r2,#0]	// [2]
	.endr
	bx	lr		// [2]

	.align 2
TestDataAddr2:
	.word	TestData

.global TestLdr3
TestLdr3:
	ldr	r2,TestDataAddr3 // [2]
	.rept	REPT
	ldrb	r0,[r2,#4]	// [1]
	.endr
	bx	lr		// [2]

.global TestLdr3B
TestLdr3B:
	ldr	r2,TestDataAddr3 // [2]
	ldr	r2,[r2,#0]	// [2]
	.rept	REPT
	ldrb	r0,[r2,#0]	// [2]
	.endr
	bx	lr		// [2]

	.align 2
TestDataAddr3:
	.word	TestData

.global TestLdr4
TestLdr4:
	ldr	r2,TestDataAddr4 // [2]
	movs	r3,#4		// [1]
	.rept	REPT
	ldr	r0,[r2,r3]	// [2]
	.endr
	bx	lr		// [2]

.global TestLdr4B
TestLdr4B:
	ldr	r2,TestDataAddr4 // [2]
	movs	r3,#0		// [1]
	ldr	r2,[r2,#0]	// [2]
	.rept	REPT
	ldr	r0,[r2,r3]	// [2]
	.endr
	bx	lr		// [2]

	.align 2
TestDataAddr4:
	.word	TestData

.global TestLdr5
TestLdr5:
	ldr	r2,TestDataAddr5 // [2]
	movs	r3,#4		// [1]
	.rept	REPT
	ldrh	r0,[r2,r3]	// [2]
	.endr
	bx	lr		// [2]

.global TestLdr5B
TestLdr5B:
	ldr	r2,TestDataAddr5 // [2]
	movs	r3,#0		// [1]
	ldr	r2,[r2,#0]	// [2]
	.rept	REPT
	ldrh	r0,[r2,r3]	// [2]
	.endr
	bx	lr		// [2]

	.align 2
TestDataAddr5:
	.word	TestData

.global TestLdr6
TestLdr6:
	ldr	r2,TestDataAddr6 // [2]
	movs	r3,#4		// [1]
	.rept	REPT
	ldrsh	r0,[r2,r3]	// [2]
	.endr
	bx	lr		// [2]

.global TestLdr6B
TestLdr6B:
	ldr	r2,TestDataAddr6 // [2]
	movs	r3,#0		// [1]
	ldr	r2,[r2,#0]	// [2]
	.rept	REPT
	ldrsh	r0,[r2,r3]	// [2]
	.endr
	bx	lr		// [2]

	.align 2
TestDataAddr6:
	.word	TestData

.global TestLdr7
TestLdr7:
	ldr	r2,TestDataAddr7 // [2]
	movs	r3,#4		// [1]
	.rept	REPT
	ldrb	r0,[r2,r3]	// [2]
	.endr
	bx	lr		// [2]

.global TestLdr7B
TestLdr7B:
	ldr	r2,TestDataAddr7 // [2]
	movs	r3,#0		// [1]
	ldr	r2,[r2,#0]	// [2]
	.rept	REPT
	ldrb	r0,[r2,r3]	// [2]
	.endr
	bx	lr		// [2]

	.align 2
TestDataAddr7:
	.word	TestData

.global TestLdr8
TestLdr8:
	ldr	r2,TestDataAddr8 // [2]
	movs	r3,#4		// [1]
	.rept	REPT
	ldrsb	r0,[r2,r3]	// [2]
	.endr
	bx	lr		// [2]

.global TestLdr8B
TestLdr8B:
	ldr	r2,TestDataAddr8 // [2]
	movs	r3,#0		// [1]
	ldr	r2,[r2,#0]	// [2]
	.rept	REPT
	ldrsb	r0,[r2,r3]	// [2]
	.endr
	bx	lr		// [2]

	.align 2
TestDataAddr8:
	.word	TestData

.global TestLdr9
TestLdr9:
	.rept	REPT
	ldr	r2,TestDataAddr9 // [2]
	.endr
	bx	lr		// [2]

	.align 2
TestDataAddr9:
	.word	TestData

.global TestLdr10
TestLdr10:
	.rept	REPT
	ldr	r2,[sp, #4]	// [2]
	.endr
	bx	lr		// [2]

.global TestLdr11
TestLdr11:
	ldr	r0,TestDataAddr11 // [2]
	.rept	REPT
	ldm	r0!,{r1,r2,r3}	// [4]
	.endr
	bx	lr		// [2]

.global TestLdr12
TestLdr12:
	.rept	REPT
	ldr	r0,TestDataAddr11 // [2]
	ldm	r0,{r0,r1,r2,r3} // [5]
	.endr
	bx	lr		// [2]

	.align 2
TestDataAddr11:
	.word	TestData

.global TestStr1
TestStr1:
	ldr	r2,TestWriteAddr // [2]
	.rept	REPT
	str	r0,[r2,#12]	// [2]
	.endr
	bx	lr		// [2]

.global TestStr1B
TestStr1B:
	ldr	r2,TestWriteAddr // [2]
	ldr	r2,[r2,#8]	// [2]
	.rept	REPT
	str	r0,[r2,#0]	// [2]
	.endr
	bx	lr		// [2]

	.align 2
TestWriteAddr:
	.word	TestData

.global TestStr2
TestStr2:
	ldr	r2,TestWriteAddr2 // [2]
	.rept	REPT
	strh	r0,[r2,#14]	// [2]
	.endr
	bx	lr		// [2]

.global TestStr2B
TestStr2B:
	ldr	r2,TestWriteAddr2 // [2]
	ldr	r2,[r2,#8]	// [2]
	.rept	REPT
	strh	r0,[r2,#2]	// [2]
	.endr
	bx	lr		// [2]

	.align 2
TestWriteAddr2:
	.word	TestData

.global TestStr3
TestStr3:
	ldr	r2,TestWriteAddr3 // [2]
	.rept	REPT
	strb	r0,[r2,#15]	// [2]
	.endr
	bx	lr		// [2]

.global TestStr3B
TestStr3B:
	ldr	r2,TestWriteAddr3 // [2]
	ldr	r2,[r2,#8]	// [2]
	.rept	REPT
	strb	r0,[r2,#3]	// [2]
	.endr
	bx	lr		// [2]

	.align 2
TestWriteAddr3:
	.word	TestData

.global TestStr4
TestStr4:
	ldr	r2,TestWriteAddr4 // [2]
	movs	r1,#12		// [1]
	.rept	REPT
	str	r0,[r2,r1]	// [2]
	.endr
	bx	lr		// [2]

.global TestStr4B
TestStr4B:
	ldr	r2,TestWriteAddr4 // [2]
	ldr	r2,[r2,#8]	// [2]
	movs	r1,#0
	.rept	REPT
	str	r0,[r2,r1]	// [2]
	.endr
	bx	lr		// [2]

	.align 2
TestWriteAddr4:
	.word	TestData

.global TestStr5
TestStr5:
	ldr	r2,TestWriteAddr5 // [2]
	movs	r1,#12		// [1]
	.rept	REPT
	strh	r0,[r2,r1]	// [2]
	.endr
	bx	lr		// [2]

.global TestStr5B
TestStr5B:
	ldr	r2,TestWriteAddr5 // [2]
	ldr	r2,[r2,#8]	// [2]
	movs	r1,#0
	.rept	REPT
	strh	r0,[r2,r1]	// [2]
	.endr
	bx	lr		// [2]

	.align 2
TestWriteAddr5:
	.word	TestData

.global TestStr6
TestStr6:
	ldr	r2,TestWriteAddr6 // [2]
	movs	r1,#12		// [1]
	.rept	REPT
	strb	r0,[r2,r1]	// [2]
	.endr
	bx	lr		// [2]

.global TestStr6B
TestStr6B:
	ldr	r2,TestWriteAddr6 // [2]
	ldr	r2,[r2,#8]	// [2]
	movs	r1,#0
	.rept	REPT
	strb	r0,[r2,r1]	// [2]
	.endr
	bx	lr		// [2]

	.align 2
TestWriteAddr6:
	.word	TestData

.global TestStr7
TestStr7:
	ldr	r2,[sp,#12]
	.rept	REPT
	str	r2,[sp, #12]	// [2]
	.endr
	bx	lr		// [2]

.global TestStr8
TestStr8:
	ldr	r0,TestWriteAddr8 // [2]
	.rept	REPT
	stm	r0!,{r1,r2,r3}	// [4]
	.endr
	bx	lr		// [2]

	.align 2
TestWriteAddr8:
	.word	TestData+12

.global TestPush1
TestPush1:
	.rept	REPT
	push	{r0}		// [2]
	.endr
	add	sp,#4*REPT	// [1]
	bx	lr		// [2]

.global TestPush2
TestPush2:
	.rept	REPT
	push	{lr}		// [2]
	.endr
	add	sp,#4*REPT	// [1]
	bx	lr		// [2]

.global TestPop1
TestPop1:
	sub	sp,#4*REPT	// [1]
	.rept	REPT
	pop	{r0}		// [2]
	.endr
	bx	lr		// [2]

	.align	2		// align to 4 bytes
.global TestPop2
TestPop2:
	adr	r0,TestPop2_1	// [1]
	adds	r0,#1		// [1]
	push	{r0}		// [2]
	pop	{pc}		// [4]
TestPop2_1:
	adr	r0,TestPop2_2	// [1]
	adds	r0,#1		// [1]
	push	{r0}		// [2]
	pop	{pc}		// [4]
TestPop2_2:
	adr	r0,TestPop2_3	// [1]
	adds	r0,#1		// [1]
	push	{r0}		// [2]
	pop	{pc}		// [4]
TestPop2_3:
	adr	r0,TestPop2_4	// [1]
	adds	r0,#1		// [1]
	push	{r0}		// [2]
	pop	{pc}		// [4]
TestPop2_4:
	adr	r0,TestPop2_5	// [1]
	adds	r0,#1		// [1]
	push	{r0}		// [2]
	pop	{pc}		// [4]
TestPop2_5:
	adr	r0,TestPop2_6	// [1]
	adds	r0,#1		// [1]
	push	{r0}		// [2]
	pop	{pc}		// [4]
TestPop2_6:
	adr	r0,TestPop2_7	// [1]
	adds	r0,#1		// [1]
	push	{r0}		// [2]
	pop	{pc}		// [4]
TestPop2_7:
	adr	r0,TestPop2_8	// [1]
	adds	r0,#1		// [1]
	push	{r0}		// [2]
	pop	{pc}		// [4]
TestPop2_8:
	adr	r0,TestPop2_9	// [1]
	adds	r0,#1		// [1]
	push	{r0}		// [2]
	pop	{pc}		// [4]
TestPop2_9:
	adr	r0,TestPop2_10	// [1]
	adds	r0,#1		// [1]
	push	{r0}		// [2]
	pop	{pc}		// [4]
TestPop2_10:
	bx	lr		// [2]

.global TestB1
TestB1:
	movs	r0,#0		// [1]
	adds	r0,#1		// [1]
	.rept	REPT
	bcs	2f		// [1,2]
2:
	.endr
	bx	lr		// [2]

.global TestB1B
TestB1B:
	movs	r0,#0		// [1]
	adds	r0,#1		// [1]
	.rept	REPT
	bcc	2f		// [1,2]
2:
	.endr
	bx	lr		// [2]

.global TestB2
TestB2:
	.rept	REPT
	b	2f		// [2]
2:
	.endr
	bx	lr		// [2]

.global TestB3
TestB3:
	mov	r0,lr		// [1]
	.rept	REPT
	bl	2f		// [2]
2:
	.endr
	bx	r0		// [2]

	.align	2		// align to 4 bytes
.global TestB4
TestB4:
	adr	r0,TestB4_1	// [1]
	adds	r0,#1		// [1]
	bx	r0		// [2]
	nop			// align
TestB4_1:
	adr	r0,TestB4_2	// [1]
	adds	r0,#1		// [1]
	bx	r0		// [2]
	nop			// align
TestB4_2:
	adr	r0,TestB4_3	// [1]
	adds	r0,#1		// [1]
	bx	r0		// [2]
	nop			// align
TestB4_3:
	adr	r0,TestB4_4	// [1]
	adds	r0,#1		// [1]
	bx	r0		// [2]
	nop			// align
TestB4_4:
	adr	r0,TestB4_5	// [1]
	adds	r0,#1		// [1]
	bx	r0		// [2]
	nop			// align
TestB4_5:
	adr	r0,TestB4_6	// [1]
	adds	r0,#1		// [1]
	bx	r0		// [2]
	nop			// align
TestB4_6:
	adr	r0,TestB4_7	// [1]
	adds	r0,#1		// [1]
	bx	r0		// [2]
	nop			// align
TestB4_7:
	adr	r0,TestB4_8	// [1]
	adds	r0,#1		// [1]
	bx	r0		// [2]
	nop			// align
TestB4_8:
	adr	r0,TestB4_9	// [1]
	adds	r0,#1		// [1]
	bx	r0		// [2]
	nop			// align
TestB4_9:
	adr	r0,TestB4_10	// [1]
	adds	r0,#1		// [1]
	bx	r0		// [2]
	nop			// align
TestB4_10:
	bx	lr		// [2]

	.align	2		// align to 4 bytes
	nop			// [1]
.global TestB5
TestB5:
	mov	r1,lr		// [1]
	adr	r0,TestB5_1	// [1]
	adds	r0,#1		// [1]
	blx	r0		// [2]
	nop			// align
TestB5_1:
	adr	r0,TestB5_2	// [1]
	adds	r0,#1		// [1]
	blx	r0		// [2]
	nop			// align
TestB5_2:
	adr	r0,TestB5_3	// [1]
	adds	r0,#1		// [1]
	blx	r0		// [2]
	nop			// align
TestB5_3:
	adr	r0,TestB5_4	// [1]
	adds	r0,#1		// [1]
	blx	r0		// [2]
	nop			// align
TestB5_4:
	adr	r0,TestB5_5	// [1]
	adds	r0,#1		// [1]
	blx	r0		// [2]
	nop			// align
TestB5_5:
	adr	r0,TestB5_6	// [1]
	adds	r0,#1		// [1]
	blx	r0		// [2]
	nop			// align
TestB5_6:
	adr	r0,TestB5_7	// [1]
	adds	r0,#1		// [1]
	blx	r0		// [2]
	nop			// align
TestB5_7:
	adr	r0,TestB5_8	// [1]
	adds	r0,#1		// [1]
	blx	r0		// [2]
	nop			// align
TestB5_8:
	adr	r0,TestB5_9	// [1]
	adds	r0,#1		// [1]
	blx	r0		// [2]
	nop			// align
TestB5_9:
	adr	r0,TestB5_10	// [1]
	adds	r0,#1		// [1]
	blx	r0		// [2]
	nop			// align
TestB5_10:
	bx	r1		// [2]

.global TestExt1
TestExt1:
	.rept	REPT
	sxth	r0,r1		// [1]
	.endr
	bx	lr		// [2]

.global TestExt2
TestExt2:
	.rept	REPT
	sxtb	r0,r1		// [1]
	.endr
	bx	lr		// [2]

.global TestExt3
TestExt3:
	.rept	REPT
	uxth	r0,r1		// [1]
	.endr
	bx	lr		// [2]

.global TestExt4
TestExt4:
	.rept	REPT
	uxtb	r0,r1		// [1]
	.endr
	bx	lr		// [2]

.global TestRev1
TestRev1:
	.rept	REPT
	rev	r0,r1		// [1]
	.endr
	bx	lr		// [2]

.global TestRev2
TestRev2:
	.rept	REPT
	rev16	r0,r1		// [1]
	.endr
	bx	lr		// [2]

.global TestRev3
TestRev3:
	.rept	REPT
	revsh	r0,r1		// [1]
	.endr
	bx	lr		// [2]

.global TestStat1
TestStat1:
	.rept	REPT
	cpsid	i		// [1]
	.endr
	cpsie	i		// [1]
	bx	lr		// [2]

.global TestStat2
TestStat2:
	.rept	REPT
	cpsie	i		// [1]
	.endr
	bx	lr		// [2]

.global TestStat3
TestStat3:
	.rept	REPT
	mrs	r0,ipsr		// [3]
	.endr
	bx	lr		// [2]

.global TestStat4
TestStat4:
	mrs	r0,msp		// [3]
	.rept	REPT
	msr	msp,r0		// [3]
	.endr
	bx	lr		// [2]

.global TestHint1
TestHint1:
	.rept	REPT
	sev			// [1]
	.endr
	bx	lr		// [2]

.global TestHint2
TestHint2:
	.rept	REPT
	sev			// [1]
	wfe			// [2]
	.endr
	bx	lr		// [2]

.global TestHint3
TestHint3:
	.rept	REPT
	yield			// [1]
	.endr
	bx	lr		// [2]

.global TestHint4
TestHint4:
	.rept	REPT
	nop		// [1]
	.endr
	bx	lr	// [2]

.global TestBar1
TestBar1:
	.rept	REPT
	isb		// [3]
	.endr
	bx	lr	// [2]

.global TestBar2
TestBar2:
	.rept	REPT
	dmb		// [3]
	.endr
	bx	lr	// [2]

.global TestBar3
TestBar3:
	.rept	REPT
	dsb		// [3]
	.endr
	bx	lr	// [2]
