OpenCores
URL https://opencores.org/ocsvn/arm4u/arm4u/trunk

Subversion Repositories arm4u

[/] [arm4u/] [trunk/] [test_program/] [arm_test.s] - Rev 2

Compare with Previous | Blame | View Log

@ This file is part of ARM4U CPU
@ 
@ This is a creation of the Laboratory of Processor Architecture
@ of Ecole Polytechnique Fédérale de Lausanne ( http://lap.epfl.ch )
@
@ asm_test.s ---  Test program which uses all the instruction set
@                 to be assembled with GCC assembler
@
@ Written By -  Jonathan Masur and Xavier Jimenez (2013)
@
@ This program is free software; you can redistribute it and/or modify it
@ under the terms of the GNU General Public License as published by the
@ Free Software Foundation; either version 2, or (at your option) any
@ later version.
@
@ This program is distributed in the hope that it will be useful,
@ but WITHOUT ANY WARRANTY; without even the implied warranty of
@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
@ GNU General Public License for more details.
@
@ In other words, you are welcome to use, share and improve this program.
@ You are forbidden to forbid anyone else to use, share and improve2
@ what you give them.   Help stamp out software-hoarding!
 
	.text
	.global test_cond, test_fwd, test_bshift, test_logic, test_adder, test_bshift_reg, test_load
	.global test_store, test_byte, test_cpsr, test_mul, test_ldmstm, test_r15jumps, test_rti
 
_start:
	bl test_cond
fail1:
	teq r0, #0
	bne fail1
 
	bl test_fwd
fail2:
	teq r0, #0
	bne fail2
 
	bl test_bshift
fail3:
	teq r0, #0
	bne fail3
 
	bl test_logic
fail4:
	teq r0, #0
	bne fail4
 
	bl test_adder
fail5:
	teq r0, #0
	bne fail5
 
	bl test_bshift_reg
fail6:
	teq r0, #0
	bne fail6
 
	bl test_load
fail7:
	teq r0, #0
	bne fail7
 
	bl test_store
fail8:
	teq r0, #0
	bne fail8
 
	bl test_byte
fail9:
	teq r0, #0
	bne fail9
 
	bl test_cpsr
fail10:
	teq r0, #0
	bne fail10
 
	bl test_mul
fail11:
	teq r0, #0
	bne fail11
 
	bl test_ldmstm
fail12:
	teq r0, #0
	bne fail12
 
	bl test_r15jumps
fail13:
	teq r0, #0
	bne fail13
 
	bl test_rti
passed:
	b passed
 
	@test N and Z flags conditional execution
test_cond:
	mov r0, #1
 
	@ test 1 - test that the Z flag is set properly, and N flag clear properly
	movs r5, #0
	bne fail
	bmi fail
	add r0, #1
 
	@test 2 - test that an instruction without 'S' does not affect the flags
	movs r5, #1
	mov r5, #0
	beq fail
	bmi fail
	add r0, #1
 
	@test 3 - test that the N flag is set properly
	movs r5, #-2
	mov r5, #0
	beq fail
	bpl fail
	add r0, #1
 
	@test4 - make sure conditional MOV are skipped, and that flags are not updated on a skipped instruction
	movs r5, #1
	movpls r5, #0	@valid
	movnes r5, #1	@invalid
	movmis r5, #2	@invalid
	bne fail
	cmp r5, #0
	bne fail
	add r0, #1
 
	@ test 5 - make sure instructions after a branch are skipped completely
	b .dummy
	movs r5, #-1
	movs r5, #-2
	movs r5, #-3
.dummy:
	bne fail
	bmi fail
 
	@condition test passed
	mov r0, #0
fail:
	bx lr
 
test_fwd:
	mov r0, #1
 
	@test forwarding and register file for OPA
	mov r1, #1
	add r1, r1, #1
	add r1, r1, #1
	add r1, r1, #1
	add r1, r1, #1
	add r1, r1, #1
	cmp r1, #6
	bne fail
	add r0, #1
 
	@test forwarding priority for opb
	mov r1, #1
	mov r1, #2
	mov r1, #3
	mov r1, #4
	mov r1, #5
	cmp r1, #5
	bne fail
	add r0, #1
 
	@forwarding test passed
	mov r0, #0
	bx lr
 
test_bshift:
	@test barrel shifter all modes (shift by literal const. only for now)
	mov r0, #1
 
	@test 1 - test LSL output
	movs r5, #0xf0000000
	mov r1, #0x0f
	mov r2, r1, lsl #28
	cmp r5, r2
	bne fail
	add r0, #1
 
	@test 2 - test ROR output
	mov r3, r1, ror #4
	cmp r5, r3
	bne fail
	add r0, #1
 
	@test 3 - test LSR output
	mov r4, r5, lsr #28
	cmp r4, r1
	bne fail
	add r0, #1
 
	@test 4 - test ASR output
	mov r1, #0x80000000
	mov r2, r1, asr #3
	cmp r5 ,r2
	bne fail
	add r0, #1
 
	@test 5 - test RRX output and carry
	mov r1, #1
	movs r1, r1, rrx
	bcc fail
	movs r1, r1, rrx
	beq fail
	bcs fail
	add r0, #1
 
	@test 6 - test carry output from rotated constant
	movs r5, #0xf0000000
	bcc fail
	movs r5, #0xf
	bcc fail
	movs r5, #0x100
	bcs fail
	add r0, #1
 
	@test 7 - test carry output from LSL
	mov r5, #0x1
	movs r5, r5, lsl #1
	bcs fail
	mov r5, #0x80000000
	movs r5, r5, lsl #1
	bcc fail
	add r0, #1
 
	@test 8 - test carry output from LSR
	mov r5, #2
	movs r5, r5, lsr #1
	bcs fail
	movs r5, r5, lsr #1
	bcc fail
	bne fail
	add r0, #1
 
	@test 9 - test carry output from ASR
	mvn r5, #0x01
	movs r5, r5, asr #1
	bcs fail
	movs r5, r5, asr #1
	bcc fail
	add r0, #1
 
	@test 10 - check for LSR #32 to behave correctly
	mov r1, #0xa5000000
	mvn r2, r1
	lsrs r3, r1, #32
	bcc fail
	lsrs r3, r2, #32
	bcs fail
	add r0, #1
 
	@test 11 - check for ASR #32 to behave correctly
	asrs r3, r1, #32
	bcc fail
	cmp r3, #-1
	bne fail
	asrs r3, r2, #32
	bcs fail
	bne fail
 
	@barrelshift test passed
	mov r0, #0
	bx lr
 
	@test logical operations
test_logic:
	mov r0, #1
 
	@test 1 - NOT operation
	mov r5, #-1
	mvns r5, r5
	bne fail
	add r0, #1
 
	@test 2 - AND operation
	mov r5, #0xa0
	mov r1, #0x0b
	mov r2, #0xab
	mov r3, #0xba
 
	ands r4, r5, r1
	bne fail
	ands r4, r5, r2
	cmp r4, r5
	bne fail
	add r0, #1
 
	@test 3 - ORR and EOR operations
	orr r4, r5, r1
	eors r4, r2, r4
	bne fail
	orr r4, r1, r5
	teq	r4, r2
	bne fail
	add r0, #1
 
	@test 4 - TST opcode
	tst r1, r5
	bne fail
	tst r4, r2
	beq fail
	add r0, #1
 
	@test 5 - BIC opcode
	bics r4, r2, r3
	cmp r4, #1
	bne fail
 
	@logical test passed
	mov r0, #0
	bx lr
 
	@test adder, substracter, C and V flags
test_adder:
	mov r0, #1
 
	@test 1 - check for carry when adding
	mov r5, #0xf0000000
	mvn r1, r5			@0x0fffffff
	adds r2, r1, r5
	bcs fail
	bvs fail
 
	adds r2, #1
	bcc fail
	bvs fail
 
	adc r2, #120
	cmp r2, #121
	bne fail
	bvs fail
	add r0, #1
 
	@test 2 - check for overflow when adding
	mov r3, #0x8fffffff		@two large negative numbers become positive
	adds r3, r5
	bvc fail
	bcc fail
	bmi fail
 
	mov r3, #0x10000000
	adds r3, r1				@r3 = 0x1fffffff
	bvs fail
	bcs fail
 
	adds r3, #0x60000001	@two large positive numbers become negative
	bvc fail
	bpl fail
 
	add r0, #1
 
	@test 3 - check for carry when substracting
	mov r5, #0x10000000
	subs r2, r5, r1
	bcc fail
	bvs fail
 
	subs r2, #1
	bcc fail
	bvs fail
 
	subs r2, #1
	bcs fail
	bvs fail
 
	add r0, #1
 
	@test 4 - check for overflow when substracting
	mov r3, #0x90000000
	subs r3, r5
	bvs fail
	bcc fail
 
	subs r3, #1		@substract a positive num from a large negative make the result positive
	bvc fail
	bcc fail
 
	@test 5 - check for carry when reverse substracting
	mov r3, #1
	rsbs r2, r1, r5
	bcc fail
	bvs fail
	rsbs r2, r3, r2
	bcc fail
	bvs fail
	rscs r2, r3, r2
	bcs fail
	bvs fail
 
	add r0, #1
 
	@test 6 - check for overflow when reverse substracting
	mov r2, #0x80000000
	mov r1, #-1
	rsbs r2, r1
	bvs fail
	bmi fail
	bcc fail
 
	mov r0, #0
	bx lr
 
@test barrelshift with register controler rotates
test_bshift_reg:
	mov r0, #1
 
	mov r1, #0
	mov r2, #7
	mov r3, #32
	mov r4, #33
	mov r5, #127
	mov r6, #256
	add r7, r6, #7
	mov r8, #0xff000000
 
	@test 1 LSL mode with register shift
	movs r9, r8, lsl r2
	bpl fail
	bcc fail
	@make sure lsl #0 does not affect carry
	movs r9, r2, lsl r1
	bcc fail
	@test using the same register twice
	mov r9, r2, lsl r2
	cmp r9, #0x380
	bne fail
 
	add r0, #1
 
	@test 2 - LSL mode with barrelshift > 31
	movs r9, r2, lsl r3
	bcc fail
	bne fail
	movs r9, r2, lsl r4
	bcs fail
	bne fail
	add r0, #1
 
	@test 3 - LSL mode with barrelshift >= 256 (only 8 bits used)
	movs r9, r2, lsl r6
	bcs fail
	cmp r9, #7
	bne fail
 
	mov r9, r2, lsl r7
	cmp r9, #0x380
	bne fail
 
	movs r9, r8, lsl r7
	bpl fail
	bcc fail
 
	add r0, #1
 
	@test 4 - LSR mode with register shift
	mov r2, #4
	add r7, r6, #4
 
	movs r9, r8, lsr r2
	bmi fail
	bcs fail
	@make sure lsr #0 does not affect carry
	movs r9, r2, lsr r1
	bcs fail
	cmp r9, #4
	bne fail
 
	movs r9, r8, lsr r2
	bcs fail
	cmp r9, #0xff00000
	bne fail
 
	add r0, #1
 
	@test 5 - LSR mode with barrelshift > 31
	movs r9, r8, lsr r3
	bcc fail
	bne fail
	movs r9, r8, lsr r4
	bcs fail
	bne fail
	add r0, #1
 
	@test 6 - LSR mode with barrelshift >= 256 (only 8 bits used)
	movs r9, r8, lsr r6
	bcs fail
	cmp r9, #0xff000000
	bne fail
 
	movs r9, r8, lsr r7
	cmp r9, #0xff00000
	bne fail
 
	mov r0, #0
	bx lr
 
array:
	.word 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
array2:
	.word 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
 
test_load:
	mov r0, #1
 
	@ Test1 basic load operations
	ldr r1, .larray1
	ldr r2, .larray2
 
	ldr r3, [r1]
	teq r3, #0
	bne fail
 
	ldr r3, [r2]
	teq r3, #16
	bne fail
	add r0, #1
 
	@ Test 2 load operations with offsets
	ldr r3, [r2, #-60]
	teq r3, #1
	bne fail
 
	ldr r3, [r1, #20]
	teq r3, #5
	bne fail
	add r0, #1
 
	@ Test 3 - test positive register offset addressing
	mov r3, #124
.lloop:
	ldr r4, [r1, r3]
	cmp r4, r3, lsr #2
	bne fail
	subs r3, #4
	bpl .lloop
	add r0, #1
 
	@ Test 4 - test negative register offset addressing
	mov r3, #64
.lloop2:
	ldr r4, [r2, -r3]
	rsb r4, #0x10
	cmp r4, r3, lsr #2
	bne fail
	subs r3, #4
	bne .lloop2
	add r0, #1
 
	@ Test 5 - test positive register offset addressing with shift
	mov r3, #0
.lloop3:
	ldr r4, [r1, r3, lsl #2]
	cmp r4, r3
	bne fail
	add r3, #1
	cmp r3, #32
	bne .lloop3
	add r0, #1
 
	@ Test 6 - test negative register offset addressing with shift
	mov r3, #0
.lloop4:
	ldr r4, [r2, -r3, lsl #2]
	rsb r4, #0x10
	cmp r4, r3
	bne fail
	add r3, #1
	cmp r3, #16
	bne .lloop4
	add r0, #1
 
	@ Test 7 - test offset with pre-increment
	mov r3, #31
	mov r5, r1
.lloop5:
	ldr r4, [r5, #4]!
	rsb r4, #32
	cmp r4, r3
	bne fail
	subs r3, #1
	bne .lloop5
	add r0, #1
 
	@ Test 8 - test offset with pre-degrement
	mov r3, #31
	add r5, r1, #128
.lloop6:
	ldr r4, [r5, #-4]!
	cmp r4, r3
	bne fail
	subs r3, #1
	bpl .lloop6
	add r0, #1
 
	@ Test 9 - test offset with post-increment
	mov r3, #32
	mov r5, r1
.lloop7:
	ldr r4, [r5], #4
	rsb r4, #32
	cmp r4, r3
	bne fail
	subs r3, #1
	bne .lloop7
	add r0, #1
 
	@ Test 10 - test offset with post-decrement
	mov r3, #31
	add r5, r1, #124
.lloop8:
	ldr r4, [r5], #-4
	cmp r3, r4
	bne fail
	subs r3, #1
	bpl .lloop8
	add r0, #1
 
	@ Test 11 - test register post-increment with a negative value
	mov r6, #0xfffffff0
	mov r5, r2
	mov r3, #16
.lloop9:
	ldr r4, [r5], r6, asr #2
	cmp r4, r3
	bne fail
	subs r3, #1
	bpl .lloop9
 
	mov r0, #0
	bx lr
 
.larray1:
	.word array
.larray2:
	.word array2
 
test_store:
	mov r0, #1
 
	@ Test 1 - test basic store opperation
	ldr r1, .larray1
	mov r2, #0x24
	str r2, [r1]
	ldr r2, [r1]
	cmp r2, #0x24
	bne fail
	add r0, #1
 
	@ Test 2 - check for post-increment and pre-decrement writes
	mov r2, #0xab
	mov r3, #0xbc
	str r2, [r1, #4]!		@ array[1] = 0xab
	str r3, [r1], #4		@ array[1] = 0xbc
	ldr r2, [r1, #-4]!		@ read 0xbc
	ldr r3, [r1, #-4]!		@ read 0x24
	cmp r3, #0x24
	bne fail
	cmp r2, #0xbc
	bne fail
	add r0, #1
 
	@ Test 3 - check for register post-increment addressing
	mov r2, #8
	mov r3, #20
	mov r4, r1
	str r2, [r4], r2
	str r3, [r4], r2
	sub r4, #16
	cmp r4, r1
	bne fail
	ldr r2, [r1]
	cmp r2, #8
	bne fail
	ldr r2, [r1, #8]
	cmp r2, #20
	bne fail
 
	mov r0, #0
	bx lr
 
	@ Tests byte loads and store
test_byte:
	mov r0, #1
 
	@ test 1 - test store bytes
	ldr r1, .larray1
	mov r2, #8
.bloop:
	strb r2, [r1], #1
	subs r2, #1
	bne .bloop
 
	ldr r2, .ref_words+4
	ldr r3, [r1, #-4]!
	cmp r2, r3
	bne fail
 
	ldr r2, .ref_words
	ldr r3, [r1, #-4]!
	cmp r2, r3
	bne fail
	add r0, #1
 
	@ test 2 - test load bytes
	mov r2, #8
.bloop2:
	ldrb r3, [r1], #1
	cmp r3, r2
	bne fail
	subs r2, #1
	bne .bloop2
 
	mov r0, #0
	bx lr
 
.ref_words:
	@ Table for ARMs who access bytes in a little-endian order
	.word 0x05060708, 0x01020304
 
	@ Table for ARMs who access bytes in a big-endian order
@	.word 0x08070605, 0x04030201
 
	@ Good source for flags info :
	@ http://blogs.arm.com/software-enablement/206-condition-codes-1-condition-flags-and-codes/
test_cpsr:
	mov r0, #1
 
	@ Test 1 - in depth test for the condition flags
	mrs r1, cpsr
	and r1, #0x000000ff
	msr cpsr_flg, r1
	@ NZCV = {0000}
	bvs fail
	bcs fail
	beq fail
	bmi fail
	bhi fail		@ bhi <-> bls
	blt fail		@ blt <-> bge
	ble fail		@ ble <-> bgt
 
	add r1, #0x10000000
	msr cpsr, r1
	@ NZCV = {0001}
	bvc fail
	bhi fail
	bge fail
	bgt fail
 
	add r1, #0x10000000
	msr cpsr, r1
	@ NZCV = {0010}
	bvs fail
	bcc fail
	bls fail
 
	add r1, #0x10000000
	msr cpsr, r1
	@ NZCV = {0011}
	bls fail
	bge fail
	bgt fail
 
	add r1, #0x10000000
	msr cpsr, r1
	@ NZCV = {0100}
	bne fail
	bhi fail
	bgt fail
 
	add r1, #0x10000000
	msr cpsr, r1
	@ NZCV = {0101}
	bgt fail
 
	add r1, #0x10000000
	msr cpsr, r1
	@ NZCV = {0110}
	bhi fail
 
	add r1, #0x20000000
	msr cpsr, r1
	@ NZCV = {1000}
	bpl fail
	bge fail
	bgt fail
 
	add r1, #0x10000000
	msr cpsr, r1
	@ NZCV = {1001}
	blt fail
 
	add r1, #0x30000000
	msr cpsr, r1
	@ NZCV = {1100}
	bgt fail
 
	add r0, #1
 
	@ Test 2 - test for the FIQ processor mode
	mov r1, r14			@ save our link register and stack pointer
	mov r2, r13
	mov r3, #30
	mov r4, #40
	mov r5, #50
	mov r6, #60
	mov r7, #70
	mov r8, #80
	mov r9, #90
	mov r10, #100
	mov r11, #110
	mov r12, #120
	mov r13, #130
	mov r14, #140
 
	msr cpsr, #0xd1		@ go into FIQ mode, disable all interrupts (F and I bits set)
	cmp r3, #30
	bne .fail
	mov r8, #8			@ overwrite fiq regs...
	mov r9, #9
	mov r10, #10
	mov r11, #11
	mov r12, #12
	mov r13, #13
	mov r14, #14
	mov r3, #3			@ also overwrite some user regs
	mov r4, #4
	mov r5, #5
	mov r6, #6
	mov r7, #7
	msr cpsr, #0x10		@ back to user mode
	cmp r3, #3			@ r3-7 should have been affected, but not r8-r14
	bne .fail
	cmp r4, #4
	bne .fail
	cmp r5, #5
	bne .fail
	cmp r6, #6
	bne .fail
	cmp r7, #7
	bne .fail
	cmp r8, #80
	bne .fail
	cmp r9, #90
	bne .fail
	cmp r10, #100
	bne .fail
	cmp r11, #110
	bne .fail
	cmp r12, #120
	bne .fail
	cmp r13, #130
	bne .fail
	cmp r14, #140
	bne .fail
	add r0, #1
 
 
	@ Test 3 - test for the SUP processor mode
	mov r12, #120
	mov r13, #130
	mov r14, #140
	msr cpsr, #0x13		@ enter SUP mode
	cmp r12, #120
	bne .fail
	mov r12, #12
	mov r13, #13
	mov r14, #14
	msr cpsr, #0x10		@ back into user mode
	cmp r12, #12
	bne .fail
	cmp r13, #130
	bne .fail
	cmp r14, #140
	bne .fail
	add r0, #1
 
	@ Test 4 - test for the UND processor mode
	mov r12, #120
	mov r13, #130
	mov r14, #140
	msr cpsr, #0x1b		@ enter UND mode
	cmp r12, #120
	bne .fail
	mov r12, #12
	mov r13, #13
	mov r14, #14
	msr cpsr, #0x10		@ back into user mode
	cmp r12, #12
	bne .fail
	cmp r13, #130
	bne .fail
	cmp r14, #140
	bne .fail
	add r0, #1
 
	@ Test 5 - test for the IRQ processor mode
	mov r12, #120
	mov r13, #130
	mov r14, #140
	msr cpsr, #0x92		@ enter IRQ mode, IRQ disabled
	cmp r12, #120
	bne .fail
	mov r12, #12
	mov r13, #13
	mov r14, #14
	msr cpsr, #0x10		@ back into user mode
	cmp r12, #12
	bne .fail
	cmp r13, #130
	bne .fail
	cmp r14, #140
	bne .fail
 
	mov r0, #0
 
.fail:
	msr cpsr, #0x10		@ back into user mode
	mov r13, r2
	bx r1				@ return
 
	@ Test multiplier and how it affects the flags
test_mul:
	mov r0, #1
 
	@ Test 1 - MUL instruction
	mov r1, #0
	mov r2, #2
	mov r3, #3
	mul r4, r2, r3
	cmp r4, #6
	bne fail
	bmi fail
 
	muls r5, r1, r2
	bne fail
	bmi fail
 
	muls r4, r2
	cmp r4, #12
	bne fail
	bmi fail
 
@	mul r3, r3, r4		@ no joke, verified to fail on a real ARM !
@	cmp r4, #36
@	bne fail
 
	mov r3, #-3			@ multiply positive * negative
	muls r5, r2, r3
	bpl fail	
	cmp r5, #-6
	bne fail
 
	mov r2, #-2			@ multiply negative * negative
	muls r5, r2, r3
	bmi fail
	cmp r5, #6
	bne fail
	add r0, #1
 
	@ Test 2 - MLA instruction
	mov r1, #10
	mov r2, #2
	mov r3, #5
	mlas r4, r1, r2, r3		@ 2*10 + 5 = 25
	bmi fail
@	bcs fail			@ on a real ARM, C flag after MLA is unpredictable
	bvs fail
	cmp r4, #25
	bne fail
 
	mov r1, #-10
	mlas r4, r1, r2, r3		@ 2*-10 + 5 = -15
	bpl fail
	bvs fail
	cmp r4, #-15
	bne fail
 
	mov r3, #0x80000001		@ causes addition overflow
	mlas r4, r1, r2, r3
	bmi fail
@	bvc fail			@ on a real ARM, V flag is not updated ?
 
	mov r0, #0
	bx lr
 
	@ Test load multiple and store multiple instructions
test_ldmstm:
	mov r0, #1
 
	@ Test 1 - STMIA
	mov r1, #1
	mov r2, #2
	mov r3, #3
	mov r4, #4
	ldr r5, .larray1
	mov r6, r5
 
	stmia r6!, {r1-r4}
	sub r6, r5
	cmp r6, #16
	bne fail
 
	ldr r6, [r5]
	cmp r6, #1
	bne fail
	ldr r6, [r5, #4]
	cmp r6, #2
	bne fail
	ldr r6, [r5, #8]
	cmp r6, #3
	bne fail
	ldr r6, [r5, #12]
	cmp r6, #4
	bne fail
	add r0, #1
 
	@ Test 2 - STMIB
	mov r6, r5
	stmib r6!, {r1-r3}
	sub r6, r5
	cmp r6, #12
	bne fail
 
	ldr r6, [r5, #4]
	cmp r6, #1
	bne fail
	ldr r6, [r5, #8]
	cmp r6, #2
	bne fail
	ldr r6, [r5, #12]
	cmp r6, #3
	bne fail
	add r0, #1
 
	@ Test 3 - STMDB
	add r6, r5, #12
	stmdb r6!, {r1-r3}
	cmp r6, r5
	bne fail
 
	ldr r6, [r5]
	cmp r6, #1
	bne fail
	ldr r6, [r5, #8]
	cmp r6, #3
	bne fail
	add r0, #1
 
	@ Test 4 - STMDA
	add r6, r5, #12
	stmda r6!, {r1-r3}
	cmp r6, r5
	bne fail
	ldr r6, [r5, #4]
	cmp r6, #1
	bne fail
	ldr r6, [r5, #12]
	cmp r6, #3
	bne fail
	add r0, #1
 
	@ Test 5 - LDMIA
	ldr r5, .larray2
	ldmia r5, {r1-r4}
	cmp r1, #16
	bne fail
	cmp r2, #17
	bne fail
	cmp r3, #18
	bne fail
	cmp r4, #19
	bne fail
	add r0, #1
 
	@ Test 6 - LDMIB
	ldmib r5!, {r1-r4}
	cmp r1, #17
	bne fail
	cmp r2, #18
	bne fail
	cmp r3, #19
	bne fail
	cmp r4, #20
	bne fail
	add r0, #1
 
	@ Test 7 - LDMDB
	ldmdb r5!, {r1-r3}
	cmp r3, #19
	bne fail
	cmp r2, #18
	bne fail
	cmp r1, #17
	bne fail
	add r0, #1
 
	@ Test 8 - LDMDA
	ldmda r5, {r1-r2}
	cmp r1, #16
	bne fail
	cmp r2, #17
	bne fail
 
	mov r0, #0
	bx lr
 
	@ Test proper jumping on instructions that affect R15
test_r15jumps:
	mov r0, #1
 
	@ Test 1 - a standard, conditional jump instruction
	ldr r3, .llabels
	mov r1, #0
	movs r2, #0
	moveq r15, r3		 @ jump to label 1
	movs r2, #12
	movs r1, #13		@ make sure fetched/decoded instructions do no execute
.label1:
	bne fail
	cmp r1, #0
	bne fail
	cmp r2, #0
	bne fail
	add r0, #1
 
	@ Test 2 - a jump instruction is not executed
	ldr r3, .llabels+4
	movs r2, #12
	moveq r15, r3
	movs r2, #0
.label2:
	cmp r2, #0
	bne fail
	add r0, #1
 
	@ Test 3 - add instruction to calculate new address
	ldr r3, .llabels+8
	movs r1, #0
	movs r2, #0
	add r15, r3, #8		@go 2 instructions after label 3
.label3:
	movs r1, #12
	movs r2, #13
	bne fail		@ program executions continues here
	bne fail
	add r0, #1
 
	@ Test 4 - use an addition directly from PC+8 (r15)
	movs r2, #0
	movs r1, #0
	add r15, r15, #4	@ Skip 2 instructions This could actually be used for a nice jump table if a register were used instead of #4
	movs r1, #1
	movs r2, #2
	bne fail
	bne fail
	add r0, #1
 
	@ Test 5 - load r15 directly from memory
	movs r1, #1
	movs r2, #2
	ldrne r15, .llabels+12		@ Makes sure code after a ldr r15 is not executed
	movs r1, #0
	movs r2, #0
.label4:
	beq fail
	beq fail
 
	ldreq r15, .llabels+16		@ Makes sure everything is right when a ldr r15 is not taken
	movs r2, #-2
.label5:
	bpl fail
	cmp r2, #-2
	bne fail
	add r0, #1
 
	@ Test 6 - load r15 as the last step of a LDM instruction
	ldr r3, .llabels + 6*4
	movs r1, #0
	movs r2, #0
	ldmia r3, {r4-r8, r15}		@jump to label6
	movs r1, #4
	movs r2, #2
.label6:
	bne fail
	bne fail
 
	mov r0, #0
	bx lr
 
.align 8
.llabels:
	.word .label1, .label2, .label3, .label4, .label5, .label6, .llabels
 
test_rti:
	mov r0, #1
 
	@ Test 1 - test normal RTI
	msr cpsr, #0xd1			@ enter into FIQ mode (interrupt disabled)
	msr spsr, #0x40000010	@ emulate a saved CPSR in user mode, with NZCV = {0100}
 
	movs r8, #-12			@ now the FIQ sets it's CPSR to NZCV = {1000}
	ldr r8, .rtilabels		@ simulate an interrupt return
	movs r15, r8			@ return from interrupt and move SPSR to CPSR
 
.rtilabel1:
	bmi .rtifail			@ ?!? WTF !?!
	bne .rtifail
	add r0, #1
 
	@ Test 2 - test LDM instruction with S flag
	msr cpsr, #0xd1
	ldr r8, .rtilabels + 20
	ldmib r8!, {r9, r10}		@ fiq_r9 = 1, fiq_r10 = 2
	ldmib r8, {r9, r10}^		@ r8 = 3, r9 = 4 ( ^ => load to user registers )
	cmp r9, #1
	bne .rtifail
	cmp r10, #2
	bne .rtifail
	msr cpsr, #0x10
	cmp r9, #3
	bne .rtifail
	cmp r10, #4
	bne .rtifail
	add r0, #1
 
	@ Test 3 - test LDM instruction with S flag for returning from an interrupt
	msr cpsr, #0xd1				@ FIQ mode, NZCV = {0000}
	msr spsr_c, #0x80000010		@ saved is normal mode with NZCV = {1000}
 
	ldr r8, .rtilabels + 20
	add r8, #8
 
	movs r9, #0					@ NZCV = {0100}
	ldmib r8, {r9-r11, r15}^	@ This should return to user mode and restore CPSR to NZCV = {1000}
 
.rtilabel2:
	bpl .rtifail
	beq .rtifail
 
	mov r0, #0
 
.rtifail:
	msr cpsr, #0x10
	bx lr
 
 
.rtilabels:
	.word .rtilabel1, 1, 2, 3, 4, .rtilabels, .rtilabel2

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.