344 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
			
		
		
	
	
			344 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
| @ RUN: llvm-mc %s -triple=armv7-unknown-linux-gnueabi -filetype=obj -o - \
 | |
| @ RUN:   | llvm-readobj -s -sd | FileCheck %s
 | |
| 
 | |
| @ Check the .save directive
 | |
| 
 | |
| @ The .save directive records the GPR registers which are pushed to the
 | |
| @ stack.  There are 4 different unwind opcodes:
 | |
| @
 | |
| @     0xB100: pop r[3:0]
 | |
| @     0xA0:   pop r[(4+x):4]		@ r[4+x]-r[4] must be consecutive.
 | |
| @     0xA8:   pop r14, r[(4+x):4]	@ r[4+x]-r[4] must be consecutive.
 | |
| @     0x8000: pop r[15:4]
 | |
| @
 | |
| @ If register list specifed by .save directive is possible to be encoded
 | |
| @ by 0xA0 or 0xA8, then the assembler should prefer them over 0x8000.
 | |
| 
 | |
| 
 | |
| 	.syntax unified
 | |
| 
 | |
| @-------------------------------------------------------------------------------
 | |
| @ TEST1
 | |
| @-------------------------------------------------------------------------------
 | |
| 	.section	.TEST1
 | |
| 	.globl	func1a
 | |
| 	.align	2
 | |
| 	.type	func1a,%function
 | |
| 	.fnstart
 | |
| func1a:
 | |
| 	.save	{r0}
 | |
| 	push	{r0}
 | |
| 	pop	{r0}
 | |
| 	bx	lr
 | |
| 	.personality __gxx_personality_v0
 | |
| 	.handlerdata
 | |
| 	.fnend
 | |
| 
 | |
| 	.globl	func1b
 | |
| 	.align	2
 | |
| 	.type	func1b,%function
 | |
| 	.fnstart
 | |
| func1b:
 | |
| 	.save	{r0, r1}
 | |
| 	push	{r0, r1}
 | |
| 	pop	{r0, r1}
 | |
| 	bx	lr
 | |
| 	.personality __gxx_personality_v0
 | |
| 	.handlerdata
 | |
| 	.fnend
 | |
| 
 | |
| 	.globl	func1c
 | |
| 	.align	2
 | |
| 	.type	func1c,%function
 | |
| 	.fnstart
 | |
| func1c:
 | |
| 	.save	{r0, r2}
 | |
| 	push	{r0, r2}
 | |
| 	pop	{r0, r2}
 | |
| 	bx	lr
 | |
| 	.personality __gxx_personality_v0
 | |
| 	.handlerdata
 | |
| 	.fnend
 | |
| 
 | |
| 	.globl	func1d
 | |
| 	.align	2
 | |
| 	.type	func1d,%function
 | |
| 	.fnstart
 | |
| func1d:
 | |
| 	.save	{r1, r2}
 | |
| 	push	{r1, r2}
 | |
| 	pop	{r1, r2}
 | |
| 	bx	lr
 | |
| 	.personality __gxx_personality_v0
 | |
| 	.handlerdata
 | |
| 	.fnend
 | |
| 
 | |
| 	.globl	func1e
 | |
| 	.align	2
 | |
| 	.type	func1e,%function
 | |
| 	.fnstart
 | |
| func1e:
 | |
| 	.save	{r0, r1, r2, r3}
 | |
| 	push	{r0, r1, r2, r3}
 | |
| 	pop	{r0, r1, r2, r3}
 | |
| 	bx	lr
 | |
| 	.personality __gxx_personality_v0
 | |
| 	.handlerdata
 | |
| 	.fnend
 | |
| 
 | |
| @-------------------------------------------------------------------------------
 | |
| @ The assembler should emit 0xB000 unwind opcode.
 | |
| @-------------------------------------------------------------------------------
 | |
| @ CHECK: Section {
 | |
| @ CHECK:   Name: .ARM.extab.TEST1
 | |
| @ CHECK:   SectionData (
 | |
| @ CHECK:     0000: 00000000 B001B100 00000000 B003B100  |................|
 | |
| @ CHECK:     0010: 00000000 B005B100 00000000 B006B100  |................|
 | |
| @ CHECK:     0020: 00000000 B00FB100                    |........|
 | |
| @ CHECK:   )
 | |
| @ CHECK: }
 | |
| 
 | |
| 
 | |
| 
 | |
| @-------------------------------------------------------------------------------
 | |
| @ TEST2
 | |
| @-------------------------------------------------------------------------------
 | |
| 	.section	.TEST2
 | |
| 	.globl	func2a
 | |
| 	.align	2
 | |
| 	.type	func2a,%function
 | |
| 	.fnstart
 | |
| func2a:
 | |
| 	.save	{r4}
 | |
| 	push	{r4}
 | |
| 	pop	{r4}
 | |
| 	bx	lr
 | |
| 	.personality __gxx_personality_v0
 | |
| 	.handlerdata
 | |
| 	.fnend
 | |
| 
 | |
| 	.globl	func2b
 | |
| 	.align	2
 | |
| 	.type	func2b,%function
 | |
| 	.fnstart
 | |
| func2b:
 | |
| 	.save	{r4, r5}
 | |
| 	push	{r4, r5}
 | |
| 	pop	{r4, r5}
 | |
| 	bx	lr
 | |
| 	.personality __gxx_personality_v0
 | |
| 	.handlerdata
 | |
| 	.fnend
 | |
| 
 | |
| 	.globl	func2c
 | |
| 	.align	2
 | |
| 	.type	func2c,%function
 | |
| 	.fnstart
 | |
| func2c:
 | |
| 	.save	{r4, r5, r6, r7, r8, r9, r10, r11}
 | |
| 	push	{r4, r5, r6, r7, r8, r9, r10, r11}
 | |
| 	pop	{r4, r5, r6, r7, r8, r9, r10, r11}
 | |
| 	bx	lr
 | |
| 	.personality __gxx_personality_v0
 | |
| 	.handlerdata
 | |
| 	.fnend
 | |
| 
 | |
| @-------------------------------------------------------------------------------
 | |
| @ The assembler should emit 0xA0 unwind opcode.
 | |
| @-------------------------------------------------------------------------------
 | |
| @ CHECK: Section {
 | |
| @ CHECK:   Name: .ARM.extab.TEST2
 | |
| @ CHECK:   SectionData (
 | |
| @ CHECK:     0000: 00000000 B0B0A000 00000000 B0B0A100  |................|
 | |
| @ CHECK:     0010: 00000000 B0B0A700                    |........|
 | |
| @ CHECK:   )
 | |
| @ CHECK: }
 | |
| 
 | |
| 
 | |
| 
 | |
| @-------------------------------------------------------------------------------
 | |
| @ TEST3
 | |
| @-------------------------------------------------------------------------------
 | |
| 	.section	.TEST3
 | |
| 	.globl	func3a
 | |
| 	.align	2
 | |
| 	.type	func3a,%function
 | |
| 	.fnstart
 | |
| func3a:
 | |
| 	.save	{r4, r14}
 | |
| 	push	{r4, r14}
 | |
| 	pop	{r4, r14}
 | |
| 	bx	lr
 | |
| 	.personality __gxx_personality_v0
 | |
| 	.handlerdata
 | |
| 	.fnend
 | |
| 
 | |
| 	.globl	func3b
 | |
| 	.align	2
 | |
| 	.type	func3b,%function
 | |
| 	.fnstart
 | |
| func3b:
 | |
| 	.save	{r4, r5, r14}
 | |
| 	push	{r4, r5, r14}
 | |
| 	pop	{r4, r5, r14}
 | |
| 	bx	lr
 | |
| 	.personality __gxx_personality_v0
 | |
| 	.handlerdata
 | |
| 	.fnend
 | |
| 
 | |
| 	.globl	func3c
 | |
| 	.align	2
 | |
| 	.type	func3c,%function
 | |
| 	.fnstart
 | |
| func3c:
 | |
| 	.save	{r4, r5, r6, r7, r8, r9, r10, r11, r14}
 | |
| 	push	{r4, r5, r6, r7, r8, r9, r10, r11, r14}
 | |
| 	pop	{r4, r5, r6, r7, r8, r9, r10, r11, r14}
 | |
| 	bx	lr
 | |
| 	.personality __gxx_personality_v0
 | |
| 	.handlerdata
 | |
| 	.fnend
 | |
| 
 | |
| @-------------------------------------------------------------------------------
 | |
| @ The assembler should emit 0xA8 unwind opcode.
 | |
| @-------------------------------------------------------------------------------
 | |
| @ CHECK: Section {
 | |
| @ CHECK:   Name: .ARM.extab.TEST3
 | |
| @ CHECK:   SectionData (
 | |
| @ CHECK:     0000: 00000000 B0B0A800 00000000 B0B0A900  |................|
 | |
| @ CHECK:     0010: 00000000 B0B0AF00                    |........|
 | |
| @ CHECK:   )
 | |
| @ CHECK: }
 | |
| 
 | |
| 
 | |
| 
 | |
| @-------------------------------------------------------------------------------
 | |
| @ TEST4
 | |
| @-------------------------------------------------------------------------------
 | |
| 	.section	.TEST4
 | |
| 	.globl	func4a
 | |
| 	.align	2
 | |
| 	.type	func4a,%function
 | |
| 	.fnstart
 | |
| func4a:
 | |
| 	.save	{r4, r5, r6, r7, r8, r9, r10, r11, r12, r14}
 | |
| 	push	{r4, r5, r6, r7, r8, r9, r10, r11, r12, r14}
 | |
| 	pop	{r4, r5, r6, r7, r8, r9, r10, r11, r12, r14}
 | |
| 	bx	lr
 | |
| 	.personality __gxx_personality_v0
 | |
| 	.handlerdata
 | |
| 	.fnend
 | |
| 
 | |
| 	.globl	func4b
 | |
| 	.align	2
 | |
| 	.type	func4b,%function
 | |
| 	.fnstart
 | |
| func4b:
 | |
| 	@ Note: r7 is missing intentionally.
 | |
| 	.save	{r4, r5, r6, r8, r9, r10, r11}
 | |
| 	push	{r4, r5, r6, r8, r9, r10, r11}
 | |
| 	pop	{r4, r5, r6, r8, r9, r10, r11}
 | |
| 	bx	lr
 | |
| 	.personality __gxx_personality_v0
 | |
| 	.handlerdata
 | |
| 	.fnend
 | |
| 
 | |
| 	.globl	func4c
 | |
| 	.align	2
 | |
| 	.type	func4c,%function
 | |
| 	.fnstart
 | |
| func4c:
 | |
| 	@ Note: r7 is missing intentionally.
 | |
| 	.save	{r4, r5, r6, r8, r9, r10, r11, r14}
 | |
| 	push	{r4, r5, r6, r8, r9, r10, r11, r14}
 | |
| 	pop	{r4, r5, r6, r8, r9, r10, r11, r14}
 | |
| 	bx	lr
 | |
| 	.personality __gxx_personality_v0
 | |
| 	.handlerdata
 | |
| 	.fnend
 | |
| 
 | |
| 	.globl	func4d
 | |
| 	.align	2
 | |
| 	.type	func4d,%function
 | |
| 	.fnstart
 | |
| func4d:
 | |
| 	@ Note: The register list is not start with r4.
 | |
| 	.save	{r5, r6, r7}
 | |
| 	push	{r5, r6, r7}
 | |
| 	pop	{r5, r6, r7}
 | |
| 	bx	lr
 | |
| 	.personality __gxx_personality_v0
 | |
| 	.handlerdata
 | |
| 	.fnend
 | |
| 
 | |
| 	.globl	func4e
 | |
| 	.align	2
 | |
| 	.type	func4e,%function
 | |
| 	.fnstart
 | |
| func4e:
 | |
| 	@ Note: The register list is not start with r4.
 | |
| 	.save	{r5, r6, r7, r14}
 | |
| 	push	{r5, r6, r7, r14}
 | |
| 	pop	{r5, r6, r7, r14}
 | |
| 	bx	lr
 | |
| 	.personality __gxx_personality_v0
 | |
| 	.handlerdata
 | |
| 	.fnend
 | |
| 
 | |
| @-------------------------------------------------------------------------------
 | |
| @ The assembler should emit 0x8000 unwind opcode.
 | |
| @-------------------------------------------------------------------------------
 | |
| @ CHECK: Section {
 | |
| @ CHECK:   Name: .ARM.extab.TEST4
 | |
| @ CHECK:   SectionData (
 | |
| @ CHECK:     0000: 00000000 B0FF8500 00000000 B0F78000  |................|
 | |
| @ CHECK:     0010: 00000000 B0F78400 00000000 B00E8000  |................|
 | |
| @ CHECK:     0020: 00000000 B00E8400                    |........|
 | |
| @ CHECK:   )
 | |
| @ CHECK: }
 | |
| 
 | |
| 
 | |
| 
 | |
| @-------------------------------------------------------------------------------
 | |
| @ TEST5
 | |
| @-------------------------------------------------------------------------------
 | |
| 	.section	.TEST5
 | |
| 	.globl	func5a
 | |
| 	.align	2
 | |
| 	.type	func5a,%function
 | |
| 	.fnstart
 | |
| func5a:
 | |
| 	.save	{r0, r1, r2, r3, r4, r5, r6}
 | |
| 	push	{r0, r1, r2, r3, r4, r5, r6}
 | |
| 	pop	{r0, r1, r2, r3, r4, r5, r6}
 | |
| 	bx	lr
 | |
| 	.personality __gxx_personality_v0
 | |
| 	.handlerdata
 | |
| 	.fnend
 | |
| 
 | |
| 	.globl	func5b
 | |
| 	.align	2
 | |
| 	.type	func5b,%function
 | |
| 	.fnstart
 | |
| func5b:
 | |
| 	.save	{r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r14}
 | |
| 	push	{r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r14}
 | |
| 	pop	{r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r14}
 | |
| 	bx	lr
 | |
| 	.personality __gxx_personality_v0
 | |
| 	.handlerdata
 | |
| 	.fnend
 | |
| 
 | |
| @-------------------------------------------------------------------------------
 | |
| @ Check the order of unwind opcode to pop registers.
 | |
| @ 0xB10F "pop {r0-r3}" should be emitted before 0xA2 "pop {r4-r6}".
 | |
| @ 0xB10F "pop {r0-r3}" should be emitted before 0x85FF "pop {r4-r12, r14}".
 | |
| @-------------------------------------------------------------------------------
 | |
| @ CHECK: Section {
 | |
| @ CHECK:   Name: .ARM.extab.TEST5
 | |
| @ CHECK:   SectionData (
 | |
| @ CHECK:     0000: 00000000 A20FB100 00000000 850FB101  |................|
 | |
| @ CHECK:     0010: B0B0B0FF                             |....|
 | |
| @ CHECK:   )
 | |
| @ CHECK: }
 |