diff options
author | Laurent Alfonsi <laurent.alfonsi@st.com> | 2015-10-27 13:20:33 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2015-10-27 13:20:33 +0000 |
commit | a504d23a83d115b1b29a5b1fbfaeb2b09bc0e22c (patch) | |
tree | 08cb61808c609c54d47090c2f8226fd649d3eea3 /ld/testsuite | |
parent | c6056a744af028824797e769ddb71927740be88a (diff) | |
download | gdb-a504d23a83d115b1b29a5b1fbfaeb2b09bc0e22c.zip gdb-a504d23a83d115b1b29a5b1fbfaeb2b09bc0e22c.tar.gz gdb-a504d23a83d115b1b29a5b1fbfaeb2b09bc0e22c.tar.bz2 |
Add --fix-stm32l4xx-629360 to the ARM linker to enable a link-time workaround for a bug in the bus matrix / memory controller for some of the STM32 Cortex-M4 based products (STM32L4xx).
bfd * bfd-in2.h: Regenerate.
* bfd-in.h (bfd_arm_stm32l4xx_fix): New enum. Specify how
STM32L4XX instruction scanning should be done.
(bfd_elf32_arm_set_stm32l4xx_fix)
(bfd_elf32_arm_stm32l4xx_erratum_scan)
(bfd_elf32_arm_stm32l4xx_fix_veneer_locations): Add prototypes.
(bfd_elf32_arm_set_target_relocs): Add stm32l4xx fix type argument
to prototype.
* elf32-arm.c (STM32L4XX_ERRATUM_VENEER_SECTION_NAME)
(STM32L4XX_ERRATUM_VENEER_ENTRY_NAME): Define macros.
(elf32_stm32l4xx_erratum_type): New enum.
(elf32_stm32l4xx_erratum_list): New struct. List of veneers or
jumps to veneers.
(_arm_elf_section_data): Add stm32l4xx_erratumcount,
stm32l4xx_erratumlist.
(elf32_arm_link_hash_table): Add stm32l4xx_erratum_glue_size,
stm32l4xx_fix and num_stm32l4xx_fixes fields.
(ctz): New function.
(popcount): New function.
(elf32_arm_link_hash_table_create): Initialize stm32l4xx_fix.
(put_thumb2_insn): New function.
(STM32L4XX_ERRATUM_LDM_VENEER_SIZE): Define. Size of a veneer for
LDM instructions.
(STM32L4XX_ERRATUM_VLDM_VENEER_SIZE): Define. Size of a veneer for
VLDM instructions.
(bfd_elf32_arm_allocate_interworking_sections): Initialise erratum
glue section.
(record_stm32l4xx_erratum_veneer) : New function. Create a single
veneer, and its associated symbols.
(bfd_elf32_arm_add_glue_sections_to_bfd): Add STM32L4XX erratum glue.
(bfd_elf32_arm_set_stm32l4xx_fix): New function. Set the type of
erratum workaround required.
(bfd_elf32_arm_stm32l4xx_fix_veneer_locations): New function. Find
out where veneers and branches to veneers have been placed in
virtual memory after layout.
(is_thumb2_ldmia): New function.
(is_thumb2_ldmdb): Likewise.
(is_thumb2_vldm ): Likewise.
(stm32l4xx_need_create_replacing_stub): New function. Decide if a
veneer must be emitted.
(bfd_elf32_arm_stm32l4xx_erratum_scan): Scan the sections of an
input BFD for potential erratum-triggering insns. Record results.
(bfd_elf32_arm_set_target_relocs): Set stm32l4xx_fix field in
global hash table.
(elf32_arm_size_dynamic_sections): Collect glue information.
(create_instruction_branch_absolute): New function.
(create_instruction_ldmia): Likewise.
(create_instruction_ldmdb): Likewise.
(create_instruction_mov): Likewise.
(create_instruction_sub): Likewise.
(create_instruction_vldmia): Likewise.
(create_instruction_vldmdb): Likewise.
(create_instruction_udf_w): Likewise.
(create_instruction_udf): Likewise.
(push_thumb2_insn32): Likewise.
(push_thumb2_insn16): Likewise.
(stm32l4xx_fill_stub_udf): Likewise.
(stm32l4xx_create_replacing_stub_ldmia): New function. Expands the
replacing stub for ldmia instructions.
(stm32l4xx_create_replacing_stub_ldmdb): Likewise for ldmdb.
(stm32l4xx_create_replacing_stub_vldm): Likewise for vldm.
(stm32l4xx_create_replacing_stub): New function. Dispatches the
stub emission to the appropriate functions.
(elf32_arm_write_section): Output veneers, and branches to veneers.
ld * ld.texinfo: Description of the STM32L4xx erratum workaround.
* emultempl/armelf.em (stm32l4xx_fix): New.
(arm_elf_before_allocation): Choose the type of fix, scan for
erratum.
(gld${EMULATION_NAME}_finish): Fix veneer locations.
(arm_elf_create_output_section_statements): Propagate
stm32l4xx_fix value.
(PARSE_AND_LIST_PROLOGUE): Define OPTION_STM32L4XX_FIX.
(PARSE_AND_LIST_LONGOPTS): Add entry for handling
--fix-stm32l4xx-629360.
(PARSE_AND_LIST_OPTION): Add entry for helping on
--fix-stm32l4xx-629360.
(PARSE_AND_LIST_ARGS_CASES): Treat OPTION_STM32L4XX_FIX.
tests * ld-arm/arm-elf.exp (armelftests_common): Add STM32L4XX
tests.
* ld-arm/stm32l4xx-cannot-fix-far-ldm.d: New.
* ld-arm/stm32l4xx-cannot-fix-far-ldm.s: Likewise.
* ld-arm/stm32l4xx-cannot-fix-it-block.d: Likewise.
* ld-arm/stm32l4xx-cannot-fix-it-block.s: Likewise.
* ld-arm/stm32l4xx-fix-all.d: Likewise.
* ld-arm/stm32l4xx-fix-all.s: Likewise.
* ld-arm/stm32l4xx-fix-it-block.d: Likewise.
* ld-arm/stm32l4xx-fix-it-block.s: Likewise.
* ld-arm/stm32l4xx-fix-ldm.d: Likewise.
* ld-arm/stm32l4xx-fix-ldm.s: Likewise.
* ld-arm/stm32l4xx-fix-vldm.d: Likewise.
* ld-arm/stm32l4xx-fix-vldm.s: Likewise.
Diffstat (limited to 'ld/testsuite')
-rw-r--r-- | ld/testsuite/ChangeLog | 18 | ||||
-rw-r--r-- | ld/testsuite/ld-arm/arm-elf.exp | 18 | ||||
-rw-r--r-- | ld/testsuite/ld-arm/stm32l4xx-cannot-fix-far-ldm.d | 25 | ||||
-rw-r--r-- | ld/testsuite/ld-arm/stm32l4xx-cannot-fix-far-ldm.s | 27 | ||||
-rw-r--r-- | ld/testsuite/ld-arm/stm32l4xx-cannot-fix-it-block.d | 16 | ||||
-rw-r--r-- | ld/testsuite/ld-arm/stm32l4xx-cannot-fix-it-block.s | 16 | ||||
-rw-r--r-- | ld/testsuite/ld-arm/stm32l4xx-fix-all.d | 83 | ||||
-rw-r--r-- | ld/testsuite/ld-arm/stm32l4xx-fix-all.s | 22 | ||||
-rw-r--r-- | ld/testsuite/ld-arm/stm32l4xx-fix-it-block.d | 189 | ||||
-rw-r--r-- | ld/testsuite/ld-arm/stm32l4xx-fix-it-block.s | 92 | ||||
-rw-r--r-- | ld/testsuite/ld-arm/stm32l4xx-fix-ldm.d | 174 | ||||
-rw-r--r-- | ld/testsuite/ld-arm/stm32l4xx-fix-ldm.s | 147 | ||||
-rw-r--r-- | ld/testsuite/ld-arm/stm32l4xx-fix-vldm.d | 49 | ||||
-rw-r--r-- | ld/testsuite/ld-arm/stm32l4xx-fix-vldm.s | 26 |
14 files changed, 902 insertions, 0 deletions
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 4e412d6..6981d70 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,21 @@ +2015-10-27 Laurent Alfonsi <laurent.alfonsi@st.com> + Christophe Monat <christophe.monat@st.com> + + * ld-arm/arm-elf.exp (armelftests_common): Add STM32L4XX + tests. + * ld-arm/stm32l4xx-cannot-fix-far-ldm.d: New. + * ld-arm/stm32l4xx-cannot-fix-far-ldm.s: Likewise. + * ld-arm/stm32l4xx-cannot-fix-it-block.d: Likewise. + * ld-arm/stm32l4xx-cannot-fix-it-block.s: Likewise. + * ld-arm/stm32l4xx-fix-all.d: Likewise. + * ld-arm/stm32l4xx-fix-all.s: Likewise. + * ld-arm/stm32l4xx-fix-it-block.d: Likewise. + * ld-arm/stm32l4xx-fix-it-block.s: Likewise. + * ld-arm/stm32l4xx-fix-ldm.d: Likewise. + * ld-arm/stm32l4xx-fix-ldm.s: Likewise. + * ld-arm/stm32l4xx-fix-vldm.d: Likewise. + * ld-arm/stm32l4xx-fix-vldm.s: Likewise. + 2015-10-27 Alan Modra <amodra@gmail.com> * ld-gc/pr19161.d: xfail hppa-*-*. diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp index 882f5cb..1d9b1c8 100644 --- a/ld/testsuite/ld-arm/arm-elf.exp +++ b/ld/testsuite/ld-arm/arm-elf.exp @@ -159,6 +159,22 @@ set armelftests_common { "-EL --vfp11-denorm-fix=scalar -Ttext=0x8000" "" "-EL -mfpu=vfpxd" {vfp11-fix-none.s} {{objdump -dr vfp11-fix-none.d}} "vfp11-fix-none"} + {"STM32L4XX erratum fix LDM" + "-EL --fix-stm32l4xx-629360 -Ttext=0x8000" "" "-EL -mcpu=cortex-m4 -mfpu=fpv4-sp-d16" {stm32l4xx-fix-ldm.s} + {{objdump -dr stm32l4xx-fix-ldm.d}} + "stm32l4xx-fix-ldm"} + {"STM32L4XX erratum fix VLDM" + "-EL --fix-stm32l4xx-629360 -Ttext=0x8000" "" "-EL -mcpu=cortex-m4 -mfpu=fpv4-sp-d16" {stm32l4xx-fix-vldm.s} + {{objdump -dr stm32l4xx-fix-vldm.d}} + "stm32l4xx-fix-vldm"} + {"STM32L4XX erratum fix ALL" + "-EL --fix-stm32l4xx-629360=all -Ttext=0x8000" "" "-EL -mcpu=cortex-m4 -mfpu=fpv4-sp-d16" {stm32l4xx-fix-all.s} + {{objdump -dr stm32l4xx-fix-all.d}} + "stm32l4xx-fix-vldm-all"} + {"STM32L4XX erratum fix in IT context" + "-EL --fix-stm32l4xx-629360 -Ttext=0x8000" "" "-EL -mcpu=cortex-m4 -mfpu=fpv4-sp-d16" {stm32l4xx-fix-it-block.s} + {{objdump -dr stm32l4xx-fix-it-block.d}} + "stm32l4xx-fix-it-block"} {"Unwinding and -gc-sections" "-gc-sections" "" "" {gc-unwind.s} {{objdump -sj.data gc-unwind.d}} "gc-unwind"} @@ -905,3 +921,5 @@ if { ![istarget "arm*-*-nacl*"] } { run_dump_test "unresolved-2" run_dump_test "gc-hidden-1" run_dump_test "protected-data" +run_dump_test "stm32l4xx-cannot-fix-it-block" +run_dump_test "stm32l4xx-cannot-fix-far-ldm" diff --git a/ld/testsuite/ld-arm/stm32l4xx-cannot-fix-far-ldm.d b/ld/testsuite/ld-arm/stm32l4xx-cannot-fix-far-ldm.d new file mode 100644 index 0000000..a7674d5 --- /dev/null +++ b/ld/testsuite/ld-arm/stm32l4xx-cannot-fix-far-ldm.d @@ -0,0 +1,25 @@ +#source: stm32l4xx-cannot-fix-far-ldm.s +#as:-EL -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 +#ld:-EL --fix-stm32l4xx-629360 -Ttext=0x80000 +#objdump: -dr --prefix-addresses --show-raw-insn +#name: STM32L4XX erratum : LDM cannot be patched when LDM is too far from veneer section +#warning: .*Cannot create STM32L4XX veneer. Jump out of range by 24 bytes. Cannot encode branch instruction.* + +# Test the `LDM*' instructions when too far from the veneer section +# They cannot, thus should not, be patched + +.*: +file format .*arm.* + +Disassembly of section \.text: +00080000 <__stm32l4xx_veneer_0> 4607[[:space:]]+mov[[:space:]]+r7, r0 +00080002 <__stm32l4xx_veneer_0\+0x2> e8b7 007e[[:space:]]+ldmia\.w[[:space:]]+r7\!, {r1, r2, r3, r4, r5, r6} +00080006 <__stm32l4xx_veneer_0\+0x6> e897 0380[[:space:]]+ldmia\.w[[:space:]]+r7, {r7, r8, r9} +0008000a <__stm32l4xx_veneer_0\+0xa> f3ff 978b[[:space:]]+b\.w[[:space:]]+0107ff24 <__stm32l4xx_veneer_0_r> +0008000e <__stm32l4xx_veneer_0\+0xe> de00[[:space:]]+udf[[:space:]]+#0 + \.\.\. + \.\.\. +0107ff20 <_start\+0xffff00> f400 906e[[:space:]]+b\.w[[:space:]]+00080000 <__stm32l4xx_veneer_0> + \.\.\. +01080024 <__stm32l4xx_veneer_0_r\+0x100> e899 03fe[[:space:]]+ldmia\.w[[:space:]]+r9, {r1, r2, r3, r4, r5, r6, r7, r8, r9} +01080028 <__stm32l4xx_veneer_1_r> bf00[[:space:]]+nop + diff --git a/ld/testsuite/ld-arm/stm32l4xx-cannot-fix-far-ldm.s b/ld/testsuite/ld-arm/stm32l4xx-cannot-fix-far-ldm.s new file mode 100644 index 0000000..7ba9a16 --- /dev/null +++ b/ld/testsuite/ld-arm/stm32l4xx-cannot-fix-far-ldm.s @@ -0,0 +1,27 @@ + .syntax unified + .cpu cortex-m4 + .fpu fpv4-sp-d16 + .text + .align 1 + .thumb + .thumb_func + .global _start +_start: + .space 0xFFFF00 + + @ Multiple load, case #2 + @ ldm rx, {...} -> + @ mov ry, rx where ry is the lowest register from upper_list + @ ldm ry!, { lower_list } + @ ldm ry, { upper_list } + ldm.w r0, {r1-r9} + + .space 0x100 + + @ Check that the linker never generates a wrong branch + @ ldm rx, {...} -> ldm rx, {...} + @ Emit a warning during the link phase and keep the same instruction + + ldm.w r9, {r1-r9} + + nop diff --git a/ld/testsuite/ld-arm/stm32l4xx-cannot-fix-it-block.d b/ld/testsuite/ld-arm/stm32l4xx-cannot-fix-it-block.d new file mode 100644 index 0000000..9b689f1 --- /dev/null +++ b/ld/testsuite/ld-arm/stm32l4xx-cannot-fix-it-block.d @@ -0,0 +1,16 @@ +#source: stm32l4xx-cannot-fix-it-block.s +#as:-EL -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 +#ld:-EL --fix-stm32l4xx-629360 -Ttext=0x8000 +#objdump: -dr --prefix-addresses --show-raw-insn +#name: STM32L4XX erratum : LDM cannot be patched when not last in IT block +#warning: .*multiple load detected in non-last IT block instruction.* + +# Test the `LDM*' instructions when non-last in IT block +# They cannot, thus should not, be patched + +.*: +file format .*arm.* + +Disassembly of section \.text: +00008000 \<_start\> bf04[[:space:]]+itt[[:space:]]+eq +00008002 \<_start\+0x2\> e899 03fe[[:space:]]+ldmiaeq\.w[[:space:]]+r9, {r1, r2, r3, r4, r5, r6, r7, r8, r9} +00008006 \<_start\+0x6\> f3af 8000[[:space:]]+nopeq\.w diff --git a/ld/testsuite/ld-arm/stm32l4xx-cannot-fix-it-block.s b/ld/testsuite/ld-arm/stm32l4xx-cannot-fix-it-block.s new file mode 100644 index 0000000..9c16388 --- /dev/null +++ b/ld/testsuite/ld-arm/stm32l4xx-cannot-fix-it-block.s @@ -0,0 +1,16 @@ + .syntax unified + .cpu cortex-m4 + .fpu fpv4-sp-d16 + .text + .align 1 + .thumb + .thumb_func + .global _start +_start: + @ Create a situation where a multiple-load that should be + @ patched cannot be, due to its belonging to an IT block + @ but not in last position, which is the only position + @ when a branch is valid in a IT block + itt eq + ldmeq.w r9, {r1-r9} + nop.w diff --git a/ld/testsuite/ld-arm/stm32l4xx-fix-all.d b/ld/testsuite/ld-arm/stm32l4xx-fix-all.d new file mode 100644 index 0000000..59f3ed1 --- /dev/null +++ b/ld/testsuite/ld-arm/stm32l4xx-fix-all.d @@ -0,0 +1,83 @@ + +.*: file format elf32-littlearm.* + + +Disassembly of section \.text: + +00008000 <__stm32l4xx_veneer_0>: + 8000: e899 01fe ldmia\.w r9, {r1, r2, r3, r4, r5, r6, r7, r8} + 8004: f000 b84a b\.w 809c <__stm32l4xx_veneer_0_r> + 8008: f7f0 a000 udf\.w #0 + 800c: f7f0 a000 udf\.w #0 + +00008010 <__stm32l4xx_veneer_1>: + 8010: e8b9 01fe ldmia\.w r9!, {r1, r2, r3, r4, r5, r6, r7, r8} + 8014: f000 b844 b\.w 80a0 <__stm32l4xx_veneer_1_r> + 8018: f7f0 a000 udf\.w #0 + 801c: f7f0 a000 udf\.w #0 + +00008020 <__stm32l4xx_veneer_2>: + 8020: e919 01fe ldmdb r9, {r1, r2, r3, r4, r5, r6, r7, r8} + 8024: f000 b83e b\.w 80a4 <__stm32l4xx_veneer_2_r> + 8028: f7f0 a000 udf\.w #0 + 802c: f7f0 a000 udf\.w #0 + +00008030 <__stm32l4xx_veneer_3>: + 8030: e939 01fe ldmdb r9!, {r1, r2, r3, r4, r5, r6, r7, r8} + 8034: f000 b838 b\.w 80a8 <__stm32l4xx_veneer_3_r> + 8038: f7f0 a000 udf\.w #0 + 803c: f7f0 a000 udf\.w #0 + +00008040 <__stm32l4xx_veneer_4>: + 8040: e8bd 01fe ldmia\.w sp!, {r1, r2, r3, r4, r5, r6, r7, r8} + 8044: f000 b832 b\.w 80ac <__stm32l4xx_veneer_4_r> + 8048: f7f0 a000 udf\.w #0 + 804c: f7f0 a000 udf\.w #0 + +00008050 <__stm32l4xx_veneer_5>: + 8050: ecd9 0a08 vldmia r9, {s1-s8} + 8054: f000 b82c b\.w 80b0 <__stm32l4xx_veneer_5_r> + 8058: f7f0 a000 udf\.w #0 + 805c: f7f0 a000 udf\.w #0 + 8060: f7f0 a000 udf\.w #0 + 8064: f7f0 a000 udf\.w #0 + +00008068 <__stm32l4xx_veneer_6>: + 8068: ecf6 4a08 vldmia r6!, {s9-s16} + 806c: f000 b822 b\.w 80b4 <__stm32l4xx_veneer_6_r> + 8070: f7f0 a000 udf\.w #0 + 8074: f7f0 a000 udf\.w #0 + 8078: f7f0 a000 udf\.w #0 + 807c: f7f0 a000 udf\.w #0 + +00008080 <__stm32l4xx_veneer_7>: + 8080: ecfd 0a08 vpop {s1-s8} + 8084: f000 b818 b\.w 80b8 <__stm32l4xx_veneer_7_r> + 8088: f7f0 a000 udf\.w #0 + 808c: f7f0 a000 udf\.w #0 + 8090: f7f0 a000 udf\.w #0 + 8094: f7f0 a000 udf\.w #0 + +00008098 <_start>: + 8098: f7ff bfb2 b\.w 8000 <__stm32l4xx_veneer_0> + +0000809c <__stm32l4xx_veneer_0_r>: + 809c: f7ff bfb8 b\.w 8010 <__stm32l4xx_veneer_1> + +000080a0 <__stm32l4xx_veneer_1_r>: + 80a0: f7ff bfbe b\.w 8020 <__stm32l4xx_veneer_2> + +000080a4 <__stm32l4xx_veneer_2_r>: + 80a4: f7ff bfc4 b\.w 8030 <__stm32l4xx_veneer_3> + +000080a8 <__stm32l4xx_veneer_3_r>: + 80a8: f7ff bfca b\.w 8040 <__stm32l4xx_veneer_4> + +000080ac <__stm32l4xx_veneer_4_r>: + 80ac: f7ff bfd0 b\.w 8050 <__stm32l4xx_veneer_5> + +000080b0 <__stm32l4xx_veneer_5_r>: + 80b0: f7ff bfda b\.w 8068 <__stm32l4xx_veneer_6> + +000080b4 <__stm32l4xx_veneer_6_r>: + 80b4: f7ff bfe4 b\.w 8080 <__stm32l4xx_veneer_7> diff --git a/ld/testsuite/ld-arm/stm32l4xx-fix-all.s b/ld/testsuite/ld-arm/stm32l4xx-fix-all.s new file mode 100644 index 0000000..0c18266 --- /dev/null +++ b/ld/testsuite/ld-arm/stm32l4xx-fix-all.s @@ -0,0 +1,22 @@ + .syntax unified + .cpu cortex-m4 + .fpu fpv4-sp-d16 + .text + .align 1 + .thumb + .thumb_func + .global _start +_start: + @ All LDM treatments for word acces <= 8 go through the same + @ replication code, but decoding may vary + ldm.w r9, {r1-r8} + ldm.w r9!, {r1-r8} + ldmdb.w r9, {r1-r8} + ldmdb.w r9!, {r1-r8} + pop {r1-r8} + + @ All VLDM treatments for word acces <= 8 go through the same + @ replication code, but decoding may vary + vldm r9, {s1-s8} + vldm r6!, {s9-s16} + vpop {s1-s8} diff --git a/ld/testsuite/ld-arm/stm32l4xx-fix-it-block.d b/ld/testsuite/ld-arm/stm32l4xx-fix-it-block.d new file mode 100644 index 0000000..97bb34d --- /dev/null +++ b/ld/testsuite/ld-arm/stm32l4xx-fix-it-block.d @@ -0,0 +1,189 @@ + +.*: file format elf32-littlearm.* + + +Disassembly of section \.text: + +00008000 <__stm32l4xx_veneer_0>: + 8000: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6} + 8004: e899 0380 ldmia\.w r9, {r7, r8, r9} + 8008: f000 b875 b\.w 80f6 <__stm32l4xx_veneer_0_r> + 800c: f7f0 a000 udf\.w #0 + +00008010 <__stm32l4xx_veneer_1>: + 8010: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6} + 8014: e899 0380 ldmia\.w r9, {r7, r8, r9} + 8018: f000 b872 b\.w 8100 <__stm32l4xx_veneer_1_r> + 801c: f7f0 a000 udf\.w #0 + +00008020 <__stm32l4xx_veneer_2>: + 8020: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6} + 8024: e899 0380 ldmia\.w r9, {r7, r8, r9} + 8028: f000 b86f b\.w 810a <__stm32l4xx_veneer_2_r> + 802c: f7f0 a000 udf\.w #0 + +00008030 <__stm32l4xx_veneer_3>: + 8030: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6} + 8034: e899 0380 ldmia\.w r9, {r7, r8, r9} + 8038: f000 b86e b\.w 8118 <__stm32l4xx_veneer_3_r> + 803c: f7f0 a000 udf\.w #0 + +00008040 <__stm32l4xx_veneer_4>: + 8040: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6} + 8044: e899 0380 ldmia\.w r9, {r7, r8, r9} + 8048: f000 b86d b\.w 8126 <__stm32l4xx_veneer_4_r> + 804c: f7f0 a000 udf\.w #0 + +00008050 <__stm32l4xx_veneer_5>: + 8050: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6} + 8054: e899 0380 ldmia\.w r9, {r7, r8, r9} + 8058: f000 b86c b\.w 8134 <__stm32l4xx_veneer_5_r> + 805c: f7f0 a000 udf\.w #0 + +00008060 <__stm32l4xx_veneer_6>: + 8060: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6} + 8064: e899 0380 ldmia\.w r9, {r7, r8, r9} + 8068: f000 b86b b\.w 8142 <__stm32l4xx_veneer_6_r> + 806c: f7f0 a000 udf\.w #0 + +00008070 <__stm32l4xx_veneer_7>: + 8070: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6} + 8074: e899 0380 ldmia\.w r9, {r7, r8, r9} + 8078: f000 b86c b\.w 8154 <__stm32l4xx_veneer_7_r> + 807c: f7f0 a000 udf\.w #0 + +00008080 <__stm32l4xx_veneer_8>: + 8080: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6} + 8084: e899 0380 ldmia\.w r9, {r7, r8, r9} + 8088: f000 b86d b\.w 8166 <__stm32l4xx_veneer_8_r> + 808c: f7f0 a000 udf\.w #0 + +00008090 <__stm32l4xx_veneer_9>: + 8090: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6} + 8094: e899 0380 ldmia\.w r9, {r7, r8, r9} + 8098: f000 b86e b\.w 8178 <__stm32l4xx_veneer_9_r> + 809c: f7f0 a000 udf\.w #0 + +000080a0 <__stm32l4xx_veneer_a>: + 80a0: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6} + 80a4: e899 0380 ldmia\.w r9, {r7, r8, r9} + 80a8: f000 b86f b\.w 818a <__stm32l4xx_veneer_a_r> + 80ac: f7f0 a000 udf\.w #0 + +000080b0 <__stm32l4xx_veneer_b>: + 80b0: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6} + 80b4: e899 0380 ldmia\.w r9, {r7, r8, r9} + 80b8: f000 b870 b\.w 819c <__stm32l4xx_veneer_b_r> + 80bc: f7f0 a000 udf\.w #0 + +000080c0 <__stm32l4xx_veneer_c>: + 80c0: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6} + 80c4: e899 0380 ldmia\.w r9, {r7, r8, r9} + 80c8: f000 b871 b\.w 81ae <__stm32l4xx_veneer_c_r> + 80cc: f7f0 a000 udf\.w #0 + +000080d0 <__stm32l4xx_veneer_d>: + 80d0: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6} + 80d4: e899 0380 ldmia\.w r9, {r7, r8, r9} + 80d8: f000 b872 b\.w 81c0 <__stm32l4xx_veneer_d_r> + 80dc: f7f0 a000 udf\.w #0 + +000080e0 <__stm32l4xx_veneer_e>: + 80e0: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6} + 80e4: e899 0380 ldmia\.w r9, {r7, r8, r9} + 80e8: f000 b873 b\.w 81d2 <__stm32l4xx_veneer_e_r> + 80ec: f7f0 a000 udf\.w #0 + +000080f0 <_start>: + 80f0: bf08 it eq + 80f2: f7ff bf85 beq\.w 8000 <__stm32l4xx_veneer_0> + +000080f6 <__stm32l4xx_veneer_0_r>: + 80f6: bf04 itt eq + 80f8: f3af 8000 nopeq\.w + 80fc: f7ff bf88 beq\.w 8010 <__stm32l4xx_veneer_1> + +00008100 <__stm32l4xx_veneer_1_r>: + 8100: bf0c ite eq + 8102: f3af 8000 nopeq\.w + 8106: f7ff bf8b bne\.w 8020 <__stm32l4xx_veneer_2> + +0000810a <__stm32l4xx_veneer_2_r>: + 810a: bf02 ittt eq + 810c: f3af 8000 nopeq\.w + 8110: f3af 8000 nopeq\.w + 8114: f7ff bf8c beq\.w 8030 <__stm32l4xx_veneer_3> + +00008118 <__stm32l4xx_veneer_3_r>: + 8118: bf0a itet eq + 811a: f3af 8000 nopeq\.w + 811e: f3af 8000 nopne\.w + 8122: f7ff bf8d beq\.w 8040 <__stm32l4xx_veneer_4> + +00008126 <__stm32l4xx_veneer_4_r>: + 8126: bf06 itte eq + 8128: f3af 8000 nopeq\.w + 812c: f3af 8000 nopeq\.w + 8130: f7ff bf8e bne\.w 8050 <__stm32l4xx_veneer_5> + +00008134 <__stm32l4xx_veneer_5_r>: + 8134: bf0e itee eq + 8136: f3af 8000 nopeq\.w + 813a: f3af 8000 nopne\.w + 813e: f7ff bf8f bne\.w 8060 <__stm32l4xx_veneer_6> + +00008142 <__stm32l4xx_veneer_6_r>: + 8142: bf01 itttt eq + 8144: f3af 8000 nopeq\.w + 8148: f3af 8000 nopeq\.w + 814c: f3af 8000 nopeq\.w + 8150: f7ff bf8e beq\.w 8070 <__stm32l4xx_veneer_7> + +00008154 <__stm32l4xx_veneer_7_r>: + 8154: bf03 ittte eq + 8156: f3af 8000 nopeq\.w + 815a: f3af 8000 nopeq\.w + 815e: f3af 8000 nopeq\.w + 8162: f7ff bf8d bne\.w 8080 <__stm32l4xx_veneer_8> + +00008166 <__stm32l4xx_veneer_8_r>: + 8166: bf05 ittet eq + 8168: f3af 8000 nopeq\.w + 816c: f3af 8000 nopeq\.w + 8170: f3af 8000 nopne\.w + 8174: f7ff bf8c beq\.w 8090 <__stm32l4xx_veneer_9> + +00008178 <__stm32l4xx_veneer_9_r>: + 8178: bf07 ittee eq + 817a: f3af 8000 nopeq\.w + 817e: f3af 8000 nopeq\.w + 8182: f3af 8000 nopne\.w + 8186: f7ff bf8b bne\.w 80a0 <__stm32l4xx_veneer_a> + +0000818a <__stm32l4xx_veneer_a_r>: + 818a: bf09 itett eq + 818c: f3af 8000 nopeq\.w + 8190: f3af 8000 nopne\.w + 8194: f3af 8000 nopeq\.w + 8198: f7ff bf8a beq\.w 80b0 <__stm32l4xx_veneer_b> + +0000819c <__stm32l4xx_veneer_b_r>: + 819c: bf0b itete eq + 819e: f3af 8000 nopeq\.w + 81a2: f3af 8000 nopne\.w + 81a6: f3af 8000 nopeq\.w + 81aa: f7ff bf89 bne\.w 80c0 <__stm32l4xx_veneer_c> + +000081ae <__stm32l4xx_veneer_c_r>: + 81ae: bf0d iteet eq + 81b0: f3af 8000 nopeq\.w + 81b4: f3af 8000 nopne\.w + 81b8: f3af 8000 nopne\.w + 81bc: f7ff bf88 beq\.w 80d0 <__stm32l4xx_veneer_d> + +000081c0 <__stm32l4xx_veneer_d_r>: + 81c0: bf0f iteee eq + 81c2: f3af 8000 nopeq\.w + 81c6: f3af 8000 nopne\.w + 81ca: f3af 8000 nopne\.w + 81ce: f7ff bf87 bne\.w 80e0 <__stm32l4xx_veneer_e> diff --git a/ld/testsuite/ld-arm/stm32l4xx-fix-it-block.s b/ld/testsuite/ld-arm/stm32l4xx-fix-it-block.s new file mode 100644 index 0000000..567c0b6 --- /dev/null +++ b/ld/testsuite/ld-arm/stm32l4xx-fix-it-block.s @@ -0,0 +1,92 @@ + .syntax unified + .cpu cortex-m4 + .fpu fpv4-sp-d16 + .text + .align 1 + .thumb + .thumb_func + .global _start +_start: + @ Create a situation where a multiple-load that should be + @ patched belongs to an IT block in the position where it can + @ be, that is the last position in the IT block. + @ Mostly to cover the IT detection logic. + @ Tests correspond to LDM CASE #1. + it eq + ldmeq.w r9, {r1-r9} + + itt eq + nop.w + ldmeq.w r9, {r1-r9} + + ite eq + nop.w + ldmne.w r9, {r1-r9} + + ittt eq + nop.w + nop.w + ldmeq.w r9, {r1-r9} + + itet eq + nop.w + nop.w + ldmeq.w r9, {r1-r9} + + itte eq + nop.w + nop.w + ldmne.w r9, {r1-r9} + + itee eq + nop.w + nop.w + ldmne.w r9, {r1-r9} + + itttt eq + nop.w + nop.w + nop.w + ldmeq.w r9, {r1-r9} + + ittte eq + nop.w + nop.w + nop.w + ldmne.w r9, {r1-r9} + + ittet eq + nop.w + nop.w + nop.w + ldmeq.w r9, {r1-r9} + + ittee eq + nop.w + nop.w + nop.w + ldmne.w r9, {r1-r9} + + itett eq + nop.w + nop.w + nop.w + ldmeq.w r9, {r1-r9} + + itete eq + nop.w + nop.w + nop.w + ldmne.w r9, {r1-r9} + + iteet eq + nop.w + nop.w + nop.w + ldmeq.w r9, {r1-r9} + + iteee eq + nop.w + nop.w + nop.w + ldmne.w r9, {r1-r9} diff --git a/ld/testsuite/ld-arm/stm32l4xx-fix-ldm.d b/ld/testsuite/ld-arm/stm32l4xx-fix-ldm.d new file mode 100644 index 0000000..260415d --- /dev/null +++ b/ld/testsuite/ld-arm/stm32l4xx-fix-ldm.d @@ -0,0 +1,174 @@ + +.*: file format elf32-littlearm.* + + +Disassembly of section \.text: + +00008000 <__stm32l4xx_veneer_0>: + 8000: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6} + 8004: e899 0380 ldmia\.w r9, {r7, r8, r9} + 8008: f000 b88c b\.w 8124 <__stm32l4xx_veneer_0_r> + 800c: f7f0 a000 udf\.w #0 + +00008010 <__stm32l4xx_veneer_1>: + 8010: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6} + 8014: e899 8380 ldmia\.w r9, {r7, r8, r9, pc} + 8018: f7f0 a000 udf\.w #0 + 801c: f7f0 a000 udf\.w #0 + +00008020 <__stm32l4xx_veneer_2>: + 8020: 4607 mov r7, r0 + 8022: e8b7 007e ldmia\.w r7!, {r1, r2, r3, r4, r5, r6} + 8026: e897 0380 ldmia\.w r7, {r7, r8, r9} + 802a: f000 b87f b\.w 812c <__stm32l4xx_veneer_2_r> + 802e: de00 udf #0 + +00008030 <__stm32l4xx_veneer_3>: + 8030: 460f mov r7, r1 + 8032: e8b7 007e ldmia\.w r7!, {r1, r2, r3, r4, r5, r6} + 8036: e897 0380 ldmia\.w r7, {r7, r8, r9} + 803a: f000 b879 b\.w 8130 <__stm32l4xx_veneer_3_r> + 803e: de00 udf #0 + +00008040 <__stm32l4xx_veneer_4>: + 8040: 4607 mov r7, r0 + 8042: e8b7 007e ldmia\.w r7!, {r1, r2, r3, r4, r5, r6} + 8046: e897 8380 ldmia\.w r7, {r7, r8, r9, pc} + 804a: de00 udf #0 + 804c: f7f0 a000 udf\.w #0 + +00008050 <__stm32l4xx_veneer_5>: + 8050: 460f mov r7, r1 + 8052: e8b7 007e ldmia\.w r7!, {r1, r2, r3, r4, r5, r6} + 8056: e897 8380 ldmia\.w r7, {r7, r8, r9, pc} + 805a: de00 udf #0 + 805c: f7f0 a000 udf\.w #0 + +00008060 <__stm32l4xx_veneer_6>: + 8060: e8b0 007e ldmia\.w r0!, {r1, r2, r3, r4, r5, r6} + 8064: e8b0 0380 ldmia\.w r0!, {r7, r8, r9} + 8068: f000 b868 b\.w 813c <__stm32l4xx_veneer_6_r> + 806c: f7f0 a000 udf\.w #0 + +00008070 <__stm32l4xx_veneer_7>: + 8070: e8b0 007e ldmia\.w r0!, {r1, r2, r3, r4, r5, r6} + 8074: e8b0 8380 ldmia\.w r0!, {r7, r8, r9, pc} + 8078: f7f0 a000 udf\.w #0 + 807c: f7f0 a000 udf\.w #0 + +00008080 <__stm32l4xx_veneer_8>: + 8080: e931 0380 ldmdb r1!, {r7, r8, r9} + 8084: e911 007e ldmdb r1, {r1, r2, r3, r4, r5, r6} + 8088: f000 b85c b\.w 8144 <__stm32l4xx_veneer_8_r> + 808c: f7f0 a000 udf\.w #0 + +00008090 <__stm32l4xx_veneer_9>: + 8090: 4651 mov r1, sl + 8092: e931 0380 ldmdb r1!, {r7, r8, r9} + 8096: e911 007e ldmdb r1, {r1, r2, r3, r4, r5, r6} + 809a: f000 b855 b\.w 8148 <__stm32l4xx_veneer_9_r> + 809e: de00 udf #0 + +000080a0 <__stm32l4xx_veneer_a>: + 80a0: 4649 mov r1, r9 + 80a2: e931 0380 ldmdb r1!, {r7, r8, r9} + 80a6: e911 007e ldmdb r1, {r1, r2, r3, r4, r5, r6} + 80aa: f000 b84f b\.w 814c <__stm32l4xx_veneer_a_r> + 80ae: de00 udf #0 + +000080b0 <__stm32l4xx_veneer_b>: + 80b0: f1a9 0928 sub\.w r9, r9, #40 ; 0x28 + 80b4: e8b9 007e ldmia\.w r9!, {r1, r2, r3, r4, r5, r6} + 80b8: e899 8380 ldmia\.w r9, {r7, r8, r9, pc} + 80bc: f7f0 a000 udf\.w #0 + +000080c0 <__stm32l4xx_veneer_c>: + 80c0: f1a1 0728 sub\.w r7, r1, #40 ; 0x28 + 80c4: e8b7 007e ldmia\.w r7!, {r1, r2, r3, r4, r5, r6} + 80c8: e897 8380 ldmia\.w r7, {r7, r8, r9, pc} + 80cc: f7f0 a000 udf\.w #0 + +000080d0 <__stm32l4xx_veneer_d>: + 80d0: f1a0 0728 sub\.w r7, r0, #40 ; 0x28 + 80d4: e8b7 007e ldmia\.w r7!, {r1, r2, r3, r4, r5, r6} + 80d8: e897 8380 ldmia\.w r7, {r7, r8, r9, pc} + 80dc: f7f0 a000 udf\.w #0 + +000080e0 <__stm32l4xx_veneer_e>: + 80e0: e930 0380 ldmdb r0!, {r7, r8, r9} + 80e4: e930 007e ldmdb r0!, {r1, r2, r3, r4, r5, r6} + 80e8: f000 b838 b\.w 815c <__stm32l4xx_veneer_e_r> + 80ec: f7f0 a000 udf\.w #0 + +000080f0 <__stm32l4xx_veneer_f>: + 80f0: f1a0 0028 sub\.w r0, r0, #40 ; 0x28 + 80f4: 4607 mov r7, r0 + 80f6: e8b7 007e ldmia\.w r7!, {r1, r2, r3, r4, r5, r6} + 80fa: e897 8380 ldmia\.w r7, {r7, r8, r9, pc} + 80fe: de00 udf #0 + +00008100 <__stm32l4xx_veneer_10>: + 8100: e8bd 007f ldmia\.w sp!, {r0, r1, r2, r3, r4, r5, r6} + 8104: e8bd 0380 ldmia\.w sp!, {r7, r8, r9} + 8108: f000 b82c b\.w 8164 <__stm32l4xx_veneer_10_r> + 810c: f7f0 a000 udf\.w #0 + +00008110 <__stm32l4xx_veneer_11>: + 8110: e8bd 007f ldmia\.w sp!, {r0, r1, r2, r3, r4, r5, r6} + 8114: e8bd 8380 ldmia\.w sp!, {r7, r8, r9, pc} + 8118: f7f0 a000 udf\.w #0 + 811c: f7f0 a000 udf\.w #0 + +00008120 <_start>: + 8120: f7ff bf6e b\.w 8000 <__stm32l4xx_veneer_0> + +00008124 <__stm32l4xx_veneer_0_r>: + 8124: f7ff bf74 b\.w 8010 <__stm32l4xx_veneer_1> + +00008128 <__stm32l4xx_veneer_1_r>: + 8128: f7ff bf7a b\.w 8020 <__stm32l4xx_veneer_2> + +0000812c <__stm32l4xx_veneer_2_r>: + 812c: f7ff bf80 b\.w 8030 <__stm32l4xx_veneer_3> + +00008130 <__stm32l4xx_veneer_3_r>: + 8130: f7ff bf86 b\.w 8040 <__stm32l4xx_veneer_4> + +00008134 <__stm32l4xx_veneer_4_r>: + 8134: f7ff bf8c b\.w 8050 <__stm32l4xx_veneer_5> + +00008138 <__stm32l4xx_veneer_5_r>: + 8138: f7ff bf92 b\.w 8060 <__stm32l4xx_veneer_6> + +0000813c <__stm32l4xx_veneer_6_r>: + 813c: f7ff bf98 b\.w 8070 <__stm32l4xx_veneer_7> + +00008140 <__stm32l4xx_veneer_7_r>: + 8140: f7ff bf9e b\.w 8080 <__stm32l4xx_veneer_8> + +00008144 <__stm32l4xx_veneer_8_r>: + 8144: f7ff bfa4 b\.w 8090 <__stm32l4xx_veneer_9> + +00008148 <__stm32l4xx_veneer_9_r>: + 8148: f7ff bfaa b\.w 80a0 <__stm32l4xx_veneer_a> + +0000814c <__stm32l4xx_veneer_a_r>: + 814c: f7ff bfb0 b\.w 80b0 <__stm32l4xx_veneer_b> + +00008150 <__stm32l4xx_veneer_b_r>: + 8150: f7ff bfb6 b\.w 80c0 <__stm32l4xx_veneer_c> + +00008154 <__stm32l4xx_veneer_c_r>: + 8154: f7ff bfbc b\.w 80d0 <__stm32l4xx_veneer_d> + +00008158 <__stm32l4xx_veneer_d_r>: + 8158: f7ff bfc2 b\.w 80e0 <__stm32l4xx_veneer_e> + +0000815c <__stm32l4xx_veneer_e_r>: + 815c: f7ff bfc8 b\.w 80f0 <__stm32l4xx_veneer_f> + +00008160 <__stm32l4xx_veneer_f_r>: + 8160: f7ff bfce b\.w 8100 <__stm32l4xx_veneer_10> + +00008164 <__stm32l4xx_veneer_10_r>: + 8164: f7ff bfd4 b\.w 8110 <__stm32l4xx_veneer_11> diff --git a/ld/testsuite/ld-arm/stm32l4xx-fix-ldm.s b/ld/testsuite/ld-arm/stm32l4xx-fix-ldm.s new file mode 100644 index 0000000..2f36c3e --- /dev/null +++ b/ld/testsuite/ld-arm/stm32l4xx-fix-ldm.s @@ -0,0 +1,147 @@ + .syntax unified + .cpu cortex-m4 + .fpu fpv4-sp-d16 + .text + .align 1 + .thumb + .thumb_func + .global _start +_start: + @ LDM CASE #1 (used when rx is in upper_list) + @ ldm rx, {...} -> + @ ldm rx!, {lower_list} + @ ldm rx, {upper_list} + @ b.w + ldm.w r9, {r1-r9} + + @ LDM CASE #1 bis (used when rx is in upper_list and pc is + @ in reglist) + @ ldm rx, {...} -> + @ ldm rx!, {lower_list} + @ ldm rx, {upper_list} + ldm.w r9, {r1-r9, pc} + + @ LDM CASE #2 (used when rx is not in upper_list) + @ ldm rx, {...} -> + @ mov ry, rx where ry is the lowest register from upper_list + @ ldm ry!, {lower_list} + @ ldm ry, {upper_list} + @ b.w + ldm.w r0, {r1-r9} + + @ LDM CASE #2 bis (used when rx is in lower_list) + @ ldm rx, {...} -> + @ mov ry, rx where ry is the lowest register from upper_list + @ ldm ry!, {lower_list} + @ ldm ry, {upper_list} + @ b.w + ldm.w r1, {r1-r9} + + @ LDM CASE #2 ter (used when rx is not in upper_list and pc is + @ in reglist) + @ ldm rx, {...} -> + @ mov ry, rx where ry is the lowest register from upper_list + @ ldm ry!, {lower_list} + @ ldm ry, {upper_list} + ldm.w r0, {r1-r9, pc} + + @ LDM CASE #2 quater (used when rx is in lower_list and pc is + @ in reglist) + @ ldm rx, {...} -> + @ mov ry, rx where ry is the lowest register from upper_list + @ ldm ry!, {lower_list} + @ ldm ry, {upper_list} + ldm.w r1, {r1-r9, pc} + + @ LDM CASE #3 (used when rx is not in upper_list) + @ ldm rx, {...} -> + @ ldm rx!, {lower_list} + @ ldm rx!, {upper_list} + @ b.w + @ Write-back variant are unpredictable when rx appears also in + @ the loaded registers + ldm.w r0!, {r1-r9} + + @ LDM CASE #3 bis (used when rx is not in upper_list and pc is + @ in reglist) + @ ldm rx, {...} -> + @ ldm rx!, {lower_list} + @ ldm rx!, {upper_list} + ldm.w r0!, {r1-r9, pc} + + @ LDM CASE #4 (used when pc is not in reglist and rx is in + @ lower_list) + @ ldmb rx, {...} -> + @ ldmb rx!, {upper_list} + @ ldmb rx, {lower_list} + ldmdb.w r1, {r1-r9} + + @ LDM CASE #5 (used when pc is not in reglist and rx is not in + @ lower_list) + @ It looks like it this mean that it could be in upper_list or not + @ ldmdb rx, {...} -> + @ mov ry, rx where ry is the lowest register from lower_list + @ ldmdb ry!, {upper_list} + @ ldmdb ry , {lower_list} + @ b.w + ldmdb.w sl, {r1-r9} + + @ LDM CASE #5 bis (used when pc is not in reglist and rx is in + @ upper_list) + @ ldmdb rx, {...} -> + @ mov ry, rx where ry is the lowest register from lower_list + @ ldmdb ry!, {upper_list} + @ ldmdb ry , {lower_list} + @ b.w + ldmdb.w r9, {r1-r9} + + @ LDM CASE #6 (used when pc is in reglist and rx is in + @ upper_list) + @ ldmdb rx, {...} -> + @ sub rx, rx, #size (lower_list + upper_list) + @ ldm rx!, {lower_list} + @ ldm rx, {upper_list} + @ This case reverses the load order + ldmdb.w r9, {r1-r9, pc} + + @ LDM CASE #6 bis (used when pc is in reglist and rx is in + @ lower_list) + @ ldmdb rx, {...} -> + @ sub rx, rx, #size (lower_list + upper_list) + @ ldm rx!, {lower_list} + @ ldm rx, {upper_list} + ldmdb.w r1, {r1-r9, pc} + + @ LDM CASE #7 (used when pc is in reglist and rx is not in + @ upper_list) + @ ldmdb rx, {...} -> + @ sub ry, rx, #size (lower_list + upper_list) where ry is the lowest + @ register of the upper list + @ ldm ry!, {lower_list} + @ ldm ry , {upper_list} + @ This case reverses the load order + ldmdb.w r0, {r1-r9, pc} + + @ LDM CASE #8 (used when pc is in not in reglist) + @ ldmdb rx!, {...} -> + @ ldm rx!, {upper_list} + @ ldm rx!, {lower_list} + @ b.w + ldmdb.w r0!, {r1-r9} + + @ LDM CASE #9 (Used when pc is in reglist) + @ ldmdb rx!, {...} -> + @ sub rx, rx, #size (lower_list + upper_list) + @ mov ry, rx where ry is the lowest register from upper_list + @ ldm ry!, {lower_list} + @ ldm ry , {upper_list} + ldmdb.w r0!, {r1-r9, pc} + + @ POP CASE #1 (list does not include pc) + @ pop {...} -> pop {lower_list} pop {upper_list} + @ b.w + pop {r0-r9} + + @ POP CASE #2 (list includes PC) + @ pop {...} -> pop {lower_list} pop {upper_list} + pop {r0-r9, pc} diff --git a/ld/testsuite/ld-arm/stm32l4xx-fix-vldm.d b/ld/testsuite/ld-arm/stm32l4xx-fix-vldm.d new file mode 100644 index 0000000..49d7bee --- /dev/null +++ b/ld/testsuite/ld-arm/stm32l4xx-fix-vldm.d @@ -0,0 +1,49 @@ + +.*: file format elf32-littlearm.* + + +Disassembly of section \.text: + +00008000 <__stm32l4xx_veneer_0>: + 8000: ecf9 0a08 vldmia r9!, {s1-s8} + 8004: ecf9 4a08 vldmia r9!, {s9-s16} + 8008: ecf9 8a08 vldmia r9!, {s17-s24} + 800c: ecf9 ca07 vldmia r9!, {s25-s31} + 8010: f1a9 097c sub\.w r9, r9, #124 ; 0x7c + 8014: f000 b826 b\.w 8064 <__stm32l4xx_veneer_0_r> + +00008018 <__stm32l4xx_veneer_1>: + 8018: ecf6 4a08 vldmia r6!, {s9-s16} + 801c: ecf6 8a08 vldmia r6!, {s17-s24} + 8020: ecf6 ca05 vldmia r6!, {s25-s29} + 8024: f000 b820 b\.w 8068 <__stm32l4xx_veneer_1_r> + 8028: f7f0 a000 udf\.w #0 + 802c: f7f0 a000 udf\.w #0 + +00008030 <__stm32l4xx_veneer_2>: + 8030: ecfd 0a08 vpop {s1-s8} + 8034: ecfd 4a01 vpop {s9} + 8038: f000 b818 b\.w 806c <__stm32l4xx_veneer_2_r> + 803c: f7f0 a000 udf\.w #0 + 8040: f7f0 a000 udf\.w #0 + 8044: f7f0 a000 udf\.w #0 + +00008048 <__stm32l4xx_veneer_3>: + 8048: ed7b 0a08 vldmdb fp!, {s1-s8} + 804c: ed7b 4a08 vldmdb fp!, {s9-s16} + 8050: ed7b 8a08 vldmdb fp!, {s17-s24} + 8054: ed7b ca07 vldmdb fp!, {s25-s31} + 8058: f000 b80a b\.w 8070 <__stm32l4xx_veneer_3_r> + 805c: f7f0 a000 udf\.w #0 + +00008060 <_start>: + 8060: f7ff bfce b\.w 8000 <__stm32l4xx_veneer_0> + +00008064 <__stm32l4xx_veneer_0_r>: + 8064: f7ff bfd8 b\.w 8018 <__stm32l4xx_veneer_1> + +00008068 <__stm32l4xx_veneer_1_r>: + 8068: f7ff bfe2 b\.w 8030 <__stm32l4xx_veneer_2> + +0000806c <__stm32l4xx_veneer_2_r>: + 806c: f7ff bfec b\.w 8048 <__stm32l4xx_veneer_3> diff --git a/ld/testsuite/ld-arm/stm32l4xx-fix-vldm.s b/ld/testsuite/ld-arm/stm32l4xx-fix-vldm.s new file mode 100644 index 0000000..94aa66e --- /dev/null +++ b/ld/testsuite/ld-arm/stm32l4xx-fix-vldm.s @@ -0,0 +1,26 @@ + .syntax unified + .cpu cortex-m4 + .fpu fpv4-sp-d16 + .text + .align 1 + .thumb + .thumb_func + .global _start +_start: + @ VLDM CASE #1 + @ vldm rx, {...} + @ -> vldm rx!, {8_words_or_less} for each + @ -> sub rx, rx, #size (list) + vldm r9, {s1-s31} + + @ VLDM CASE #2 + @ vldm rx!, {...} + @ -> vldm rx!, {8_words_or_less} for each needed 8_word + @ This also handles vpop instruction (when rx is sp) + vldm r6!, {s9-s29} + @ Explicit VPOP test + vpop {s1-s9} + + @ vldmd rx!, {...} + @ -> vldmb rx!, {8_words_or_less} for each needed 8_word + vldmdb r11!, {s1-s31} |