| @ 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: } |