[ARM/STM32L4XX] PR 20030: --fix-stm32l4xx-629360 fails to create vldm/vpop veneers...
authorChristophe Monat <christophe.monat@st.com>
Mon, 9 May 2016 13:10:37 +0000 (15:10 +0200)
committerChristophe Lyon <christophe.lyon@linaro.org>
Mon, 9 May 2016 13:10:37 +0000 (15:10 +0200)
bfd/
PR ld/20030
* elf32-arm.c (is_thumb2_vldm): Account for T1 (DP) encoding.
(stm32l4xx_need_create_replacing_stub): Rename ambiguous nb_regs
to nb_words.
(create_instruction_vldmia): Add is_dp to disambiguate SP/DP
encoding.
(create_instruction_vldmdb): Likewise.
(stm32l4xx_create_replacing_stub_vldm): is_dp detects DP encoding,
uses it to re-encode.

ld/
PR ld/20030
* testsuite/ld-arm/arm-elf.exp: Run new stm32l4xx-fix-vldm-dp
tests. Fix misnamed stm32l4xx-fix-all.
* testsuite/ld-arm/stm32l4xx-fix-vldm-dp.s: New tests for multiple
loads with DP registers.
* testsuite/ld-arm/stm32l4xx-fix-vldm-dp.d: New reference file.
* testsuite/ld-arm/stm32l4xx-fix-vldm.s: Add missing comment.
* testsuite/ld-arm/stm32l4xx-fix-all.s: Add tests for multiple
loads with DP registers.
* testsuite/ld-arm/stm32l4xx-fix-all.d: Update reference.

bfd/ChangeLog
bfd/elf32-arm.c
ld/ChangeLog
ld/testsuite/ld-arm/arm-elf.exp
ld/testsuite/ld-arm/stm32l4xx-fix-all.d
ld/testsuite/ld-arm/stm32l4xx-fix-all.s
ld/testsuite/ld-arm/stm32l4xx-fix-vldm-dp.d [new file with mode: 0644]
ld/testsuite/ld-arm/stm32l4xx-fix-vldm-dp.s [new file with mode: 0644]
ld/testsuite/ld-arm/stm32l4xx-fix-vldm.s

index a6e440168ade9c6e20c309f28726e70daba5f134..d5edec4588541e9a7bad375b5f131e75fae19a2d 100644 (file)
@@ -1,3 +1,15 @@
+2016-05-09  Christophe Monat  <christophe.monat@st.com>
+
+       PR ld/20030
+       * elf32-arm.c (is_thumb2_vldm): Account for T1 (DP) encoding.
+       (stm32l4xx_need_create_replacing_stub): Rename ambiguous nb_regs
+       to nb_words.
+       (create_instruction_vldmia): Add is_dp to disambiguate SP/DP
+       encoding.
+       (create_instruction_vldmdb): Likewise.
+       (stm32l4xx_create_replacing_stub_vldm): is_dp detects DP encoding,
+       uses it to re-encode.
+
 2016-05-09  Nick Clifton  <nickc@redhat.com>
 
        PR 19938
index 61deb9ec817b847f156635e498c6055cd8c99f9e..d65837c1a0372076f2dd38bfd0ac82d3a5a8e92d 100644 (file)
@@ -7442,18 +7442,21 @@ is_thumb2_vldm (const insn32 insn)
 {
   /* A6.5 Extension register load or store instruction
      A7.7.229
-     We look only for the 32-bit registers case since the DP (64-bit
-     registers) are not supported for STM32L4XX
+     We look for SP 32-bit and DP 64-bit registers.
+     Encoding T1 VLDM{mode}<c> <Rn>{!}, <list>
+     <list> is consecutive 64-bit registers
+     1110 - 110P - UDW1 - rrrr - vvvv - 1011 - iiii - iiii
      Encoding T2 VLDM{mode}<c> <Rn>{!}, <list>
      <list> is consecutive 32-bit registers
      1110 - 110P - UDW1 - rrrr - vvvv - 1010 - iiii - iiii
      if P==0 && U==1 && W==1 && Rn=1101 VPOP
      if PUW=010 || PUW=011 || PUW=101 VLDM.  */
   return
-    ((insn & 0xfe100f00) == 0xec100a00)
+    (((insn & 0xfe100f00) == 0xec100b00) ||
+     ((insn & 0xfe100f00) == 0xec100a00))
     && /* (IA without !).  */
     (((((insn << 7) >> 28) & 0xd) == 0x4)
-     /* (IA with !), includes VPOP (when reg number is SP).  */     
+     /* (IA with !), includes VPOP (when reg number is SP).  */
      || ((((insn << 7) >> 28) & 0xd) == 0x5)
      /* (DB with !).  */
      || ((((insn << 7) >> 28) & 0xd) == 0x9));
@@ -7470,19 +7473,19 @@ static bfd_boolean
 stm32l4xx_need_create_replacing_stub (const insn32 insn,
                                      bfd_arm_stm32l4xx_fix stm32l4xx_fix)
 {
-  int nb_regs = 0;
+  int nb_words = 0;
 
   /* The field encoding the register list is the same for both LDMIA
      and LDMDB encodings.  */
   if (is_thumb2_ldmia (insn) || is_thumb2_ldmdb (insn))
-    nb_regs = popcount (insn & 0x0000ffff);
+    nb_words = popcount (insn & 0x0000ffff);
   else if (is_thumb2_vldm (insn))
-   nb_regs = (insn & 0xff);
+   nb_words = (insn & 0xff);
 
   /* DEFAULT mode accounts for the real bug condition situation,
      ALL mode inserts stubs for each LDM/VLDM instruction (testing).  */
   return
-    (stm32l4xx_fix == BFD_ARM_STM32L4XX_FIX_DEFAULT) ? nb_regs > 8 :
+    (stm32l4xx_fix == BFD_ARM_STM32L4XX_FIX_DEFAULT) ? nb_words > 8 :
     (stm32l4xx_fix == BFD_ARM_STM32L4XX_FIX_ALL) ? TRUE : FALSE;
 }
 
@@ -16432,30 +16435,31 @@ create_instruction_sub (int target_reg, int source_reg, int value)
 }
 
 static inline bfd_vma
-create_instruction_vldmia (int base_reg, int wback, int num_regs,
+create_instruction_vldmia (int base_reg, int is_dp, int wback, int num_words,
                           int first_reg)
 {
   /* A8.8.332 VLDM (A8-922)
-     VLMD{MODE} Rn{!}, {list} (Encoding T2).  */
-  bfd_vma patched_inst = 0xec900a00
+     VLMD{MODE} Rn{!}, {list} (Encoding T1 or T2).  */
+  bfd_vma patched_inst = (is_dp ? 0xec900b00 : 0xec900a00)
     | (/*W=*/wback << 21)
     | (base_reg << 16)
-    | (num_regs & 0x000000ff)
-    | (((unsigned)first_reg>>1) & 0x0000000f) << 12
+    | (num_words & 0x000000ff)
+    | (((unsigned)first_reg >> 1) & 0x0000000f) << 12
     | (first_reg & 0x00000001) << 22;
 
   return patched_inst;
 }
 
 static inline bfd_vma
-create_instruction_vldmdb (int base_reg, int num_regs, int first_reg)
+create_instruction_vldmdb (int base_reg, int is_dp, int num_words,
+                          int first_reg)
 {
   /* A8.8.332 VLDM (A8-922)
-     VLMD{MODE} Rn!, {} (Encoding T2).  */
-  bfd_vma patched_inst = 0xed300a00
+     VLMD{MODE} Rn!, {} (Encoding T1 or T2).  */
+  bfd_vma patched_inst = (is_dp ? 0xed300b00 : 0xed300a00)
     | (base_reg << 16)
-    | (num_regs & 0x000000ff)
-    | (((unsigned)first_reg>>1) & 0x0000000f) << 12
+    | (num_words & 0x000000ff)
+    | (((unsigned)first_reg >>1 ) & 0x0000000f) << 12
     | (first_reg & 0x00000001) << 22;
 
   return patched_inst;
@@ -16935,15 +16939,15 @@ stm32l4xx_create_replacing_stub_vldm (struct elf32_arm_link_hash_table * htab,
                                      const bfd_byte *const initial_insn_addr,
                                      bfd_byte *const base_stub_contents)
 {
-  int num_regs = ((unsigned int)initial_insn << 24) >> 24;
+  int num_words = ((unsigned int) initial_insn << 24) >> 24;
   bfd_byte *current_stub_contents = base_stub_contents;
 
   BFD_ASSERT (is_thumb2_vldm (initial_insn));
 
   /* In BFD_ARM_STM32L4XX_FIX_ALL mode we may have to deal with
-     smaller than 8 registers load sequences that do not cause the
+     smaller than 8 words load sequences that do not cause the
      hardware issue.  */
-  if (num_regs <= 8)
+  if (num_words <= 8)
     {
       /* Untouched instruction.  */
       current_stub_contents =
@@ -16958,28 +16962,30 @@ stm32l4xx_create_replacing_stub_vldm (struct elf32_arm_link_hash_table * htab,
     }
   else
     {
+      bfd_boolean is_dp = /* DP encoding. */
+       (initial_insn & 0xfe100f00) == 0xec100b00;
       bfd_boolean is_ia_nobang = /* (IA without !).  */
        (((initial_insn << 7) >> 28) & 0xd) == 0x4;
       bfd_boolean is_ia_bang = /* (IA with !) - includes VPOP.  */
        (((initial_insn << 7) >> 28) & 0xd) == 0x5;
       bfd_boolean is_db_bang = /* (DB with !).  */
        (((initial_insn << 7) >> 28) & 0xd) == 0x9;
-      int base_reg = ((unsigned int)initial_insn << 12) >> 28;
+      int base_reg = ((unsigned int) initial_insn << 12) >> 28;
       /* d = UInt (Vd:D);.  */
-      int first_reg = ((((unsigned int)initial_insn << 16) >> 28) << 1)
+      int first_reg = ((((unsigned int) initial_insn << 16) >> 28) << 1)
        | (((unsigned int)initial_insn << 9) >> 31);
 
-      /* Compute the number of 8-register chunks needed to split.  */
-      int chunks = (num_regs%8) ? (num_regs/8 + 1) : (num_regs/8);
+      /* Compute the number of 8-words chunks needed to split.  */
+      int chunks = (num_words % 8) ? (num_words / 8 + 1) : (num_words / 8);
       int chunk;
 
       /* The test coverage has been done assuming the following
         hypothesis that exactly one of the previous is_ predicates is
         true.  */
-      BFD_ASSERT ((is_ia_nobang ^ is_ia_bang ^ is_db_bang) &&
-                 !(is_ia_nobang & is_ia_bang & is_db_bang));
+      BFD_ASSERT (    (is_ia_nobang ^ is_ia_bang ^ is_db_bang)
+                 && !(is_ia_nobang & is_ia_bang & is_db_bang));
 
-      /* We treat the cutting of the register in one pass for all
+      /* We treat the cutting of the words in one pass for all
         cases, then we emit the adjustments:
 
         vldm rx, {...}
@@ -16992,29 +16998,34 @@ stm32l4xx_create_replacing_stub_vldm (struct elf32_arm_link_hash_table * htab,
 
         vldmd rx!, {...}
         -> vldmb rx!, {8_words_or_less} for each needed 8_word.  */
-      for (chunk = 0; chunk<chunks; ++chunk)
+      for (chunk = 0; chunk < chunks; ++chunk)
        {
+         bfd_vma new_insn = 0;
+
          if (is_ia_nobang || is_ia_bang)
            {
-             current_stub_contents =
-               push_thumb2_insn32 (htab, output_bfd, current_stub_contents,
-                                   create_instruction_vldmia
-                                   (base_reg,
-                                    /*wback= .  */1,
-                                    chunks - (chunk + 1) ?
-                                    8 : num_regs - chunk * 8,
-                                    first_reg + chunk * 8));
+             new_insn = create_instruction_vldmia
+               (base_reg,
+                is_dp,
+                /*wback= .  */1,
+                chunks - (chunk + 1) ?
+                8 : num_words - chunk * 8,
+                first_reg + chunk * 8);
            }
          else if (is_db_bang)
            {
-             current_stub_contents =
-               push_thumb2_insn32 (htab, output_bfd, current_stub_contents,
-                                   create_instruction_vldmdb
-                                   (base_reg,
-                                    chunks - (chunk + 1) ?
-                                    8 : num_regs - chunk * 8,
-                                    first_reg + chunk * 8));
+             new_insn = create_instruction_vldmdb
+               (base_reg,
+                is_dp,
+                chunks - (chunk + 1) ?
+                8 : num_words - chunk * 8,
+                first_reg + chunk * 8);
            }
+
+         if (new_insn)
+           current_stub_contents =
+             push_thumb2_insn32 (htab, output_bfd, current_stub_contents,
+                                 new_insn);
        }
 
       /* Only this case requires the base register compensation
@@ -17024,7 +17035,7 @@ stm32l4xx_create_replacing_stub_vldm (struct elf32_arm_link_hash_table * htab,
          current_stub_contents =
            push_thumb2_insn32 (htab, output_bfd, current_stub_contents,
                                create_instruction_sub
-                               (base_reg, base_reg, 4*num_regs));
+                               (base_reg, base_reg, 4*num_words));
        }
 
       /* B initial_insn_addr+4.  */
index 2e07395c2d261813811e21d8bc0fa7e82e30db1d..3188f29325a58f66744a9ec306571577f9520804 100644 (file)
@@ -1,3 +1,16 @@
+2016-05-09  Christophe Monat  <christophe.monat@st.com>
+
+       PR ld/20030
+       * testsuite/ld-arm/arm-elf.exp: Run new stm32l4xx-fix-vldm-dp
+       tests. Fix misnamed stm32l4xx-fix-all.
+       * testsuite/ld-arm/stm32l4xx-fix-vldm-dp.s: New tests for multiple
+       loads with DP registers.
+       * testsuite/ld-arm/stm32l4xx-fix-vldm-dp.d: New reference file.
+       * testsuite/ld-arm/stm32l4xx-fix-vldm.s: Add missing comment.
+       * testsuite/ld-arm/stm32l4xx-fix-all.s: Add tests for multiple
+       loads with DP registers.
+       * testsuite/ld-arm/stm32l4xx-fix-all.d: Update reference.
+
 2016-05-09  Pitchumani Sivanupandi  <pitchumani.s@atmel.com>
 
        * testsuite/ld-elf/flags1.d (readelf): Dump section header instead
index 0af32c09e3d612326c557433db3a3a8e111bb6e6..fea70a18f41d73f12f1f1f55373527fb06640d42 100644 (file)
@@ -167,10 +167,14 @@ set armelftests_common_1 {
      "-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 VLDM, DP registers"
+     "-EL --fix-stm32l4xx-629360 -Ttext=0x8000" "" "-EL -mcpu=cortex-m4 -mfpu=fpv4-sp-d16" {stm32l4xx-fix-vldm-dp.s}
+     {{objdump -dr stm32l4xx-fix-vldm-dp.d}}
+     "stm32l4xx-fix-vldm-dp"}
     {"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-fix-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}}
index 59f3ed1c922a1a16b5c6bacc44e605d0e56ccaf0..c67f95d2dd19c0925518ca2225fe828f1a750172 100644 (file)
@@ -6,37 +6,37 @@ 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>
+    8004:      f000 b86e       b\.w    80e4 <__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>
+    8014:      f000 b868       b\.w    80e8 <__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>
+    8024:      f000 b862       b\.w    80ec <__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>
+    8034:      f000 b85c       b\.w    80f0 <__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>
+    8044:      f000 b856       b\.w    80f4 <__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>
+    8054:      f000 b850       b\.w    80f8 <__stm32l4xx_veneer_5_r>
     8058:      f7f0 a000       udf\.w  #0
     805c:      f7f0 a000       udf\.w  #0
     8060:      f7f0 a000       udf\.w  #0
@@ -44,7 +44,7 @@ Disassembly of section \.text:
 
 00008068 <__stm32l4xx_veneer_6>:
     8068:      ecf6 4a08       vldmia  r6!, {s9-s16}
-    806c:      f000 b822       b\.w    80b4 <__stm32l4xx_veneer_6_r>
+    806c:      f000 b846       b\.w    80fc <__stm32l4xx_veneer_6_r>
     8070:      f7f0 a000       udf\.w  #0
     8074:      f7f0 a000       udf\.w  #0
     8078:      f7f0 a000       udf\.w  #0
@@ -52,32 +52,65 @@ Disassembly of section \.text:
 
 00008080 <__stm32l4xx_veneer_7>:
     8080:      ecfd 0a08       vpop    {s1-s8}
-    8084:      f000 b818       b\.w    80b8 <__stm32l4xx_veneer_7_r>
+    8084:      f000 b83c       b\.w    8100 <__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>
+00008098 <__stm32l4xx_veneer_8>:
+    8098:      ec99 1b08       vldmia  r9, {d1-d4}
+    809c:      f000 b832       b\.w    8104 <__stm32l4xx_veneer_8_r>
+    80a0:      f7f0 a000       udf\.w  #0
+    80a4:      f7f0 a000       udf\.w  #0
+    80a8:      f7f0 a000       udf\.w  #0
+    80ac:      f7f0 a000       udf\.w  #0
 
-0000809c <__stm32l4xx_veneer_0_r>:
-    809c:      f7ff bfb8       b\.w    8010 <__stm32l4xx_veneer_1>
+000080b0 <__stm32l4xx_veneer_9>:
+    80b0:      ecb6 8b08       vldmia  r6!, {d8-d11}
+    80b4:      f000 b828       b\.w    8108 <__stm32l4xx_veneer_9_r>
+    80b8:      f7f0 a000       udf\.w  #0
+    80bc:      f7f0 a000       udf\.w  #0
+    80c0:      f7f0 a000       udf\.w  #0
+    80c4:      f7f0 a000       udf\.w  #0
 
-000080a0 <__stm32l4xx_veneer_1_r>:
-    80a0:      f7ff bfbe       b\.w    8020 <__stm32l4xx_veneer_2>
+000080c8 <__stm32l4xx_veneer_a>:
+    80c8:      ecbd 1b08       vpop    {d1-d4}
+    80cc:      f000 b81e       b\.w    810c <__stm32l4xx_veneer_a_r>
+    80d0:      f7f0 a000       udf\.w  #0
+    80d4:      f7f0 a000       udf\.w  #0
+    80d8:      f7f0 a000       udf\.w  #0
+    80dc:      f7f0 a000       udf\.w  #0
 
-000080a4 <__stm32l4xx_veneer_2_r>:
-    80a4:      f7ff bfc4       b\.w    8030 <__stm32l4xx_veneer_3>
+000080e0 <_start>:
+    80e0:      f7ff bf8e       b\.w    8000 <__stm32l4xx_veneer_0>
 
-000080a8 <__stm32l4xx_veneer_3_r>:
-    80a8:      f7ff bfca       b\.w    8040 <__stm32l4xx_veneer_4>
+000080e4 <__stm32l4xx_veneer_0_r>:
+    80e4:      f7ff bf94       b\.w    8010 <__stm32l4xx_veneer_1>
 
-000080ac <__stm32l4xx_veneer_4_r>:
-    80ac:      f7ff bfd0       b\.w    8050 <__stm32l4xx_veneer_5>
+000080e8 <__stm32l4xx_veneer_1_r>:
+    80e8:      f7ff bf9a       b\.w    8020 <__stm32l4xx_veneer_2>
 
-000080b0 <__stm32l4xx_veneer_5_r>:
-    80b0:      f7ff bfda       b\.w    8068 <__stm32l4xx_veneer_6>
+000080ec <__stm32l4xx_veneer_2_r>:
+    80ec:      f7ff bfa0       b\.w    8030 <__stm32l4xx_veneer_3>
 
-000080b4 <__stm32l4xx_veneer_6_r>:
-    80b4:      f7ff bfe4       b\.w    8080 <__stm32l4xx_veneer_7>
+000080f0 <__stm32l4xx_veneer_3_r>:
+    80f0:      f7ff bfa6       b\.w    8040 <__stm32l4xx_veneer_4>
+
+000080f4 <__stm32l4xx_veneer_4_r>:
+    80f4:      f7ff bfac       b\.w    8050 <__stm32l4xx_veneer_5>
+
+000080f8 <__stm32l4xx_veneer_5_r>:
+    80f8:      f7ff bfb6       b\.w    8068 <__stm32l4xx_veneer_6>
+
+000080fc <__stm32l4xx_veneer_6_r>:
+    80fc:      f7ff bfc0       b\.w    8080 <__stm32l4xx_veneer_7>
+
+00008100 <__stm32l4xx_veneer_7_r>:
+    8100:      f7ff bfca       b\.w    8098 <__stm32l4xx_veneer_8>
+
+00008104 <__stm32l4xx_veneer_8_r>:
+    8104:      f7ff bfd4       b\.w    80b0 <__stm32l4xx_veneer_9>
+
+00008108 <__stm32l4xx_veneer_9_r>:
+    8108:      f7ff bfde       b\.w    80c8 <__stm32l4xx_veneer_a>
index 0c1826670ff5cc17416856cdba2003b2e6ec1c2f..580e5b2e29be05cdd17cfa73a040c42afbc0ae00 100644 (file)
@@ -20,3 +20,6 @@ _start:
         vldm r9, {s1-s8}
         vldm r6!, {s9-s16}
         vpop {s1-s8}
+        vldm r9, {d1-d4}
+        vldm r6!, {d8-d11}
+        vpop {d1-d4}
diff --git a/ld/testsuite/ld-arm/stm32l4xx-fix-vldm-dp.d b/ld/testsuite/ld-arm/stm32l4xx-fix-vldm-dp.d
new file mode 100644 (file)
index 0000000..cd7de14
--- /dev/null
@@ -0,0 +1,49 @@
+
+.*:     file format elf32-littlearm.*
+
+
+Disassembly of section \.text:
+
+00008000 <__stm32l4xx_veneer_0>:
+    8000:      ecba 1b08       vldmia  sl!, {d1-d4}
+    8004:      ecba 5b08       vldmia  sl!, {d5-d8}
+    8008:      ecba 9b08       vldmia  sl!, {d9-d12}
+    800c:      ecba db06       vldmia  sl!, {d13-d15}
+    8010:      f1aa 0a78       sub\.w  sl, sl, #120    ; 0x78
+    8014:      f000 b826       b\.w    8064 <__stm32l4xx_veneer_0_r>
+
+00008018 <__stm32l4xx_veneer_1>:
+    8018:      ecb7 5b08       vldmia  r7!, {d5-d8}
+    801c:      ecb7 9b08       vldmia  r7!, {d9-d12}
+    8020:      ecb7 db06       vldmia  r7!, {d13-d15}
+    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:      ecbd 1b08       vpop    {d1-d4}
+    8034:      ecbd 5b02       vpop    {d5}
+    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:      ed3c 1b08       vldmdb  ip!, {d1-d4}
+    804c:      ed3c 5b08       vldmdb  ip!, {d5-d8}
+    8050:      ed3c 9b08       vldmdb  ip!, {d9-d12}
+    8054:      ed3c db06       vldmdb  ip!, {d13-d15}
+    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-dp.s b/ld/testsuite/ld-arm/stm32l4xx-fix-vldm-dp.s
new file mode 100644 (file)
index 0000000..7c7ce01
--- /dev/null
@@ -0,0 +1,27 @@
+        .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 r10, {d1-d15}
+
+        @ 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 r7!, {d5-d15}
+        @ Explicit VPOP test
+        vpop {d1-d5}
+
+        @ VLDM CASE #3
+        @ vldmd rx!, {...}
+        @ -> vldmb rx!, {8_words_or_less} for each needed 8_word
+        vldmdb r12!, {d1-d15}
index 94aa66e6d3b9c0de4300762e3a6581cc53018230..b0728016fda55596c10d2599746c7f41ac170076 100644 (file)
@@ -21,6 +21,7 @@ _start:
         @ Explicit VPOP test
         vpop {s1-s9}
 
+        @ VLDM CASE #3
         @ vldmd rx!, {...}
         @ -> vldmb rx!, {8_words_or_less} for each needed 8_word
         vldmdb r11!, {s1-s31}