[ARM/FDPIC v6 04/24] [ARM] FDPIC: Add support for FDPIC for arm architecture
authorChristophe Lyon <christophe.lyon@st.com>
Tue, 10 Sep 2019 07:41:59 +0000 (09:41 +0200)
committerChristophe Lyon <clyon@gcc.gnu.org>
Tue, 10 Sep 2019 07:41:59 +0000 (09:41 +0200)
The FDPIC register is hard-coded to r9, as defined in the ABI.

We have to disable tailcall optimizations if we don't know if the
target function is in the same module. If not, we have to set r9 to
the value associated with the target module.

When generating a symbol address, we have to take into account whether
it is a pointer to data or to a function, because different
relocations are needed.

2019-09-10  Christophe Lyon  <christophe.lyon@st.com>
Mickaël Guêné <mickael.guene@st.com>

gcc/
* config/arm/arm-c.c (__FDPIC__): Define new pre-processor macro
in FDPIC mode.
* config/arm/arm-protos.h (arm_load_function_descriptor): Declare
new function.
* config/arm/arm.c (arm_option_override): Define pic register to
FDPIC_REGNUM.
(arm_function_ok_for_sibcall): Disable sibcall optimization if we
have no decl or go through PLT.
(calculate_pic_address_constant): New function.
(legitimize_pic_address): Call calculate_pic_address_constant.
(arm_load_pic_register): Handle TARGET_FDPIC.
(arm_is_segment_info_known): New function.
(arm_pic_static_addr): Add support for FDPIC.
(arm_load_function_descriptor): New function.
(arm_emit_call_insn): Add support for FDPIC.
(arm_assemble_integer): Add support for FDPIC.
* config/arm/arm.h (PIC_OFFSET_TABLE_REG_CALL_CLOBBERED):
Define. (FDPIC_REGNUM): New define.
* config/arm/arm.md (call): Add support for FDPIC.
(call_value): Likewise.
(restore_pic_register_after_call): New pattern.
(untyped_call): Disable if FDPIC.
(untyped_return): Likewise.
* config/arm/unspecs.md (UNSPEC_PIC_RESTORE): New.

gcc/testsuite/
* gcc.target/arm/fp16-aapcs-2.c: Adjust scan-assembler-times.
* gcc.target/arm/fp16-aapcs-4.c: Likewise.

Co-Authored-By: Mickaël Guêné <mickael.guene@st.com>
From-SVN: r275566

gcc/ChangeLog
gcc/config/arm/arm-c.c
gcc/config/arm/arm-protos.h
gcc/config/arm/arm.c
gcc/config/arm/arm.h
gcc/config/arm/arm.md
gcc/config/arm/unspecs.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/fp16-aapcs-2.c
gcc/testsuite/gcc.target/arm/fp16-aapcs-4.c

index 90c7ecd4e189fee8c80d00388cee5611795600c6..62fb38ab6dfc1a0283edab1a120c2b053d51141f 100644 (file)
@@ -1,3 +1,31 @@
+2019-09-10  Christophe Lyon  <christophe.lyon@st.com>
+       Mickaël Guêné <mickael.guene@st.com>
+
+       * config/arm/arm-c.c (__FDPIC__): Define new pre-processor macro
+       in FDPIC mode.
+       * config/arm/arm-protos.h (arm_load_function_descriptor): Declare
+       new function.
+       * config/arm/arm.c (arm_option_override): Define pic register to
+       FDPIC_REGNUM.
+       (arm_function_ok_for_sibcall): Disable sibcall optimization if we
+       have no decl or go through PLT.
+       (calculate_pic_address_constant): New function.
+       (legitimize_pic_address): Call calculate_pic_address_constant.
+       (arm_load_pic_register): Handle TARGET_FDPIC.
+       (arm_is_segment_info_known): New function.
+       (arm_pic_static_addr): Add support for FDPIC.
+       (arm_load_function_descriptor): New function.
+       (arm_emit_call_insn): Add support for FDPIC.
+       (arm_assemble_integer): Add support for FDPIC.
+       * config/arm/arm.h (PIC_OFFSET_TABLE_REG_CALL_CLOBBERED):
+       Define. (FDPIC_REGNUM): New define.
+       * config/arm/arm.md (call): Add support for FDPIC.
+       (call_value): Likewise.
+       (restore_pic_register_after_call): New pattern.
+       (untyped_call): Disable if FDPIC.
+       (untyped_return): Likewise.
+       * config/arm/unspecs.md (UNSPEC_PIC_RESTORE): New.
+
 2019-09-10  Christophe Lyon  <christophe.lyon@st.com>
        Mickaël Guêné <mickael.guene@st.com>
 
index 6e256ee0a122faf5ab59a5dcb40ec89bd04e5778..34695fa0112e90e4bdf317da0b9fd1d3194bf0a2 100644 (file)
@@ -203,6 +203,8 @@ arm_cpu_builtins (struct cpp_reader* pfile)
       builtin_define ("__ARM_EABI__");
     }
 
+  def_or_undef_macro (pfile, "__FDPIC__", TARGET_FDPIC);
+
   def_or_undef_macro (pfile, "__ARM_ARCH_EXT_IDIV__", TARGET_IDIV);
   def_or_undef_macro (pfile, "__ARM_FEATURE_IDIV", TARGET_IDIV);
 
index 8386d89fc0b955e85692f87fedd8710010ad2a35..f995974f9bb89ab3c7ff0888c394b0dfaf7da60c 100644 (file)
@@ -139,6 +139,7 @@ extern int arm_max_const_double_inline_cost (void);
 extern int arm_const_double_inline_cost (rtx);
 extern bool arm_const_double_by_parts (rtx);
 extern bool arm_const_double_by_immediates (rtx);
+extern rtx arm_load_function_descriptor (rtx funcdesc);
 extern void arm_emit_call_insn (rtx, rtx, bool);
 bool detect_cmse_nonsecure_call (tree);
 extern const char *output_call (rtx *);
index 8576431a8ecebb44abff0ceb4ff6f8596b782739..c34aab88178839311c3441e922c513ebd0a909c6 100644 (file)
@@ -3456,6 +3456,14 @@ arm_option_override (void)
   if (flag_pic && TARGET_VXWORKS_RTP)
     arm_pic_register = 9;
 
+  /* If in FDPIC mode then force arm_pic_register to be r9.  */
+  if (TARGET_FDPIC)
+    {
+      arm_pic_register = FDPIC_REGNUM;
+      if (TARGET_THUMB1)
+       sorry ("FDPIC mode is not supported in Thumb-1 mode");
+    }
+
   if (arm_pic_register_string != NULL)
     {
       int pic_register = decode_reg_name (arm_pic_register_string);
@@ -7251,6 +7259,15 @@ arm_function_ok_for_sibcall (tree decl, tree exp)
   if (cfun->machine->sibcall_blocked)
     return false;
 
+  if (TARGET_FDPIC)
+    {
+      /* In FDPIC, never tailcall something for which we have no decl:
+        the target function could be in a different module, requiring
+        a different FDPIC register value.  */
+      if (decl == NULL)
+       return false;
+    }
+
   /* Never tailcall something if we are generating code for Thumb-1.  */
   if (TARGET_THUMB1)
     return false;
@@ -7461,6 +7478,24 @@ require_pic_register (rtx pic_reg, bool compute_now)
     }
 }
 
+/* Generate insns to calculate the address of ORIG in pic mode.  */
+static rtx_insn *
+calculate_pic_address_constant (rtx reg, rtx pic_reg, rtx orig)
+{
+  rtx pat;
+  rtx mem;
+
+  pat = gen_calculate_pic_address (reg, pic_reg, orig);
+
+  /* Make the MEM as close to a constant as possible.  */
+  mem = SET_SRC (pat);
+  gcc_assert (MEM_P (mem) && !MEM_VOLATILE_P (mem));
+  MEM_READONLY_P (mem) = 1;
+  MEM_NOTRAP_P (mem) = 1;
+
+  return emit_insn (pat);
+}
+
 /* Legitimize PIC load to ORIG into REG.  If REG is NULL, a new pseudo is
    created to hold the result of the load.  If not NULL, PIC_REG indicates
    which register to use as PIC register, otherwise it is decided by register
@@ -7505,24 +7540,13 @@ legitimize_pic_address (rtx orig, machine_mode mode, rtx reg, rtx pic_reg,
        insn = arm_pic_static_addr (orig, reg);
       else
        {
-         rtx pat;
-         rtx mem;
-
          /* If this function doesn't have a pic register, create one now.  */
          require_pic_register (pic_reg, compute_now);
 
          if (pic_reg == NULL_RTX)
            pic_reg = cfun->machine->pic_reg;
 
-         pat = gen_calculate_pic_address (reg, pic_reg, orig);
-
-         /* Make the MEM as close to a constant as possible.  */
-         mem = SET_SRC (pat);
-         gcc_assert (MEM_P (mem) && !MEM_VOLATILE_P (mem));
-         MEM_READONLY_P (mem) = 1;
-         MEM_NOTRAP_P (mem) = 1;
-
-         insn = emit_insn (pat);
+         insn = calculate_pic_address_constant (reg, pic_reg, orig);
        }
 
       /* Put a REG_EQUAL note on this insn, so that it can be optimized
@@ -7677,7 +7701,9 @@ arm_load_pic_register (unsigned long saved_regs ATTRIBUTE_UNUSED, rtx pic_reg)
 {
   rtx l1, labelno, pic_tmp, pic_rtx;
 
-  if (crtl->uses_pic_offset_table == 0 || TARGET_SINGLE_PIC_BASE)
+  if (crtl->uses_pic_offset_table == 0
+      || TARGET_SINGLE_PIC_BASE
+      || TARGET_FDPIC)
     return;
 
   gcc_assert (flag_pic);
@@ -7746,28 +7772,128 @@ arm_load_pic_register (unsigned long saved_regs ATTRIBUTE_UNUSED, rtx pic_reg)
   emit_use (pic_reg);
 }
 
+/* Try to determine whether an object, referenced via ORIG, will be
+   placed in the text or data segment.  This is used in FDPIC mode, to
+   decide which relocations to use when accessing ORIG.  *IS_READONLY
+   is set to true if ORIG is a read-only location, false otherwise.
+   Return true if we could determine the location of ORIG, false
+   otherwise.  *IS_READONLY is valid only when we return true.  */
+static bool
+arm_is_segment_info_known (rtx orig, bool *is_readonly)
+{
+  *is_readonly = false;
+
+  if (GET_CODE (orig) == LABEL_REF)
+    {
+      *is_readonly = true;
+      return true;
+    }
+
+  if (SYMBOL_REF_P (orig))
+    {
+      if (CONSTANT_POOL_ADDRESS_P (orig))
+       {
+         *is_readonly = true;
+         return true;
+       }
+      if (SYMBOL_REF_LOCAL_P (orig)
+         && !SYMBOL_REF_EXTERNAL_P (orig)
+         && SYMBOL_REF_DECL (orig)
+         && (!DECL_P (SYMBOL_REF_DECL (orig))
+             || !DECL_COMMON (SYMBOL_REF_DECL (orig))))
+       {
+         tree decl = SYMBOL_REF_DECL (orig);
+         tree init = (TREE_CODE (decl) == VAR_DECL)
+           ? DECL_INITIAL (decl) : (TREE_CODE (decl) == CONSTRUCTOR)
+           ? decl : 0;
+         int reloc = 0;
+         bool named_section, readonly;
+
+         if (init && init != error_mark_node)
+           reloc = compute_reloc_for_constant (init);
+
+         named_section = TREE_CODE (decl) == VAR_DECL
+           && lookup_attribute ("section", DECL_ATTRIBUTES (decl));
+         readonly = decl_readonly_section (decl, reloc);
+
+         /* We don't know where the link script will put a named
+            section, so return false in such a case.  */
+         if (named_section)
+           return false;
+
+         *is_readonly = readonly;
+         return true;
+       }
+
+      /* We don't know.  */
+      return false;
+    }
+
+  gcc_unreachable ();
+}
+
 /* Generate code to load the address of a static var when flag_pic is set.  */
 static rtx_insn *
 arm_pic_static_addr (rtx orig, rtx reg)
 {
   rtx l1, labelno, offset_rtx;
+  rtx_insn *insn;
 
   gcc_assert (flag_pic);
 
-  /* We use an UNSPEC rather than a LABEL_REF because this label
-     never appears in the code stream.  */
-  labelno = GEN_INT (pic_labelno++);
-  l1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL);
-  l1 = gen_rtx_CONST (VOIDmode, l1);
+  bool is_readonly = false;
+  bool info_known = false;
 
-  /* On the ARM the PC register contains 'dot + 8' at the time of the
-     addition, on the Thumb it is 'dot + 4'.  */
-  offset_rtx = plus_constant (Pmode, l1, TARGET_ARM ? 8 : 4);
-  offset_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, orig, offset_rtx),
-                               UNSPEC_SYMBOL_OFFSET);
-  offset_rtx = gen_rtx_CONST (Pmode, offset_rtx);
+  if (TARGET_FDPIC
+      && SYMBOL_REF_P (orig)
+      && !SYMBOL_REF_FUNCTION_P (orig))
+    info_known = arm_is_segment_info_known (orig, &is_readonly);
 
-  return emit_insn (gen_pic_load_addr_unified (reg, offset_rtx, labelno));
+  if (TARGET_FDPIC
+      && SYMBOL_REF_P (orig)
+      && !SYMBOL_REF_FUNCTION_P (orig)
+      && !info_known)
+    {
+      /* We don't know where orig is stored, so we have be
+        pessimistic and use a GOT relocation.  */
+      rtx pic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM);
+
+      insn = calculate_pic_address_constant (reg, pic_reg, orig);
+    }
+  else if (TARGET_FDPIC
+          && SYMBOL_REF_P (orig)
+          && (SYMBOL_REF_FUNCTION_P (orig)
+              || !is_readonly))
+    {
+      /* We use the GOTOFF relocation.  */
+      rtx pic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM);
+
+      rtx l1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, orig), UNSPEC_PIC_SYM);
+      emit_insn (gen_movsi (reg, l1));
+      insn = emit_insn (gen_addsi3 (reg, reg, pic_reg));
+    }
+  else
+    {
+      /* Not FDPIC, not SYMBOL_REF_P or readonly: we can use
+        PC-relative access.  */
+      /* We use an UNSPEC rather than a LABEL_REF because this label
+        never appears in the code stream.  */
+      labelno = GEN_INT (pic_labelno++);
+      l1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL);
+      l1 = gen_rtx_CONST (VOIDmode, l1);
+
+      /* On the ARM the PC register contains 'dot + 8' at the time of the
+        addition, on the Thumb it is 'dot + 4'.  */
+      offset_rtx = plus_constant (Pmode, l1, TARGET_ARM ? 8 : 4);
+      offset_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, orig, offset_rtx),
+                                  UNSPEC_SYMBOL_OFFSET);
+      offset_rtx = gen_rtx_CONST (Pmode, offset_rtx);
+
+      insn = emit_insn (gen_pic_load_addr_unified (reg, offset_rtx,
+                                                  labelno));
+    }
+
+  return insn;
 }
 
 /* Return nonzero if X is valid as an ARM state addressing register.  */
@@ -16051,9 +16177,32 @@ get_jump_table_size (rtx_jump_table_data *insn)
   return 0;
 }
 
+/* Emit insns to load the function address from FUNCDESC (an FDPIC
+   function descriptor) into a register and the GOT address into the
+   FDPIC register, returning an rtx for the register holding the
+   function address.  */
+
+rtx
+arm_load_function_descriptor (rtx funcdesc)
+{
+  rtx fnaddr_reg = gen_reg_rtx (Pmode);
+  rtx pic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM);
+  rtx fnaddr = gen_rtx_MEM (Pmode, funcdesc);
+  rtx gotaddr = gen_rtx_MEM (Pmode, plus_constant (Pmode, funcdesc, 4));
+
+  emit_move_insn (fnaddr_reg, fnaddr);
+
+  /* The ABI requires the entry point address to be loaded first, but
+     since we cannot support lazy binding for lack of atomic load of
+     two 32-bits values, we do not need to bother to prevent the
+     previous load from being moved after that of the GOT address.  */
+  emit_insn (gen_restore_pic_register_after_call (pic_reg, gotaddr));
+
+  return fnaddr_reg;
+}
+
 /* Return the maximum amount of padding that will be inserted before
    label LABEL.  */
-
 static HOST_WIDE_INT
 get_label_padding (rtx label)
 {
@@ -18188,6 +18337,12 @@ arm_emit_call_insn (rtx pat, rtx addr, bool sibcall)
       use_reg (&CALL_INSN_FUNCTION_USAGE (insn), cfun->machine->pic_reg);
     }
 
+  if (TARGET_FDPIC)
+    {
+      rtx fdpic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM);
+      use_reg (&CALL_INSN_FUNCTION_USAGE (insn), fdpic_reg);
+    }
+
   if (TARGET_AAPCS_BASED)
     {
       /* For AAPCS, IP and CC can be clobbered by veneers inserted by the
@@ -23010,10 +23165,36 @@ arm_assemble_integer (rtx x, unsigned int size, int aligned_p)
                  && (!SYMBOL_REF_LOCAL_P (x)
                      || (SYMBOL_REF_DECL (x)
                          ? DECL_WEAK (SYMBOL_REF_DECL (x)) : 0))))
-           fputs ("(GOT)", asm_out_file);
+           {
+             if (TARGET_FDPIC && SYMBOL_REF_FUNCTION_P (x))
+               fputs ("(GOTFUNCDESC)", asm_out_file);
+             else
+               fputs ("(GOT)", asm_out_file);
+           }
          else
-           fputs ("(GOTOFF)", asm_out_file);
+           {
+             if (TARGET_FDPIC && SYMBOL_REF_FUNCTION_P (x))
+               fputs ("(GOTOFFFUNCDESC)", asm_out_file);
+             else
+               {
+                 bool is_readonly;
+
+                 if (!TARGET_FDPIC
+                     || arm_is_segment_info_known (x, &is_readonly))
+                   fputs ("(GOTOFF)", asm_out_file);
+                 else
+                   fputs ("(GOT)", asm_out_file);
+               }
+           }
        }
+
+      /* For FDPIC we also have to mark symbol for .data section.  */
+      if (TARGET_FDPIC
+         && !making_const_table
+         && SYMBOL_REF_P (x)
+         && SYMBOL_REF_FUNCTION_P (x))
+       fputs ("(FUNCDESC)", asm_out_file);
+
       fputc ('\n', asm_out_file);
       return true;
     }
index 8b92c830de09a3ad49420fdfacde02d8efc2a89b..e404e2cde48ad536e2fc837638e9717f12f9ce88 100644 (file)
@@ -885,6 +885,9 @@ extern int arm_arch_cmse;
    Pascal), so the following is not true.  */
 #define STATIC_CHAIN_REGNUM    12
 
+/* r9 is the FDPIC register (base register for GOT and FUNCDESC accesses).  */
+#define FDPIC_REGNUM           9
+
 /* Define this to be where the real frame pointer is if it is not possible to
    work out the offset between the frame pointer and the automatic variables
    until after register allocation has taken place.  FRAME_POINTER_REGNUM
@@ -1941,6 +1944,10 @@ extern unsigned arm_pic_register;
    data addresses in memory.  */
 #define PIC_OFFSET_TABLE_REGNUM arm_pic_register
 
+/* For FDPIC, the FDPIC register is call-clobbered (otherwise PLT
+   entries would need to handle saving and restoring it).  */
+#define PIC_OFFSET_TABLE_REG_CALL_CLOBBERED TARGET_FDPIC
+
 /* We can't directly access anything that contains a symbol,
    nor can we indirect via the constant pool.  One exception is
    UNSPEC_TLS, which is always PIC.  */
index e23683114087f6cc9ee78376529da97cfe31d3a6..027febbaebb24c5e377d3e0cdd7d387e2037ebe1 100644 (file)
        : !REG_P (callee))
       XEXP (operands[0], 0) = force_reg (Pmode, callee);
 
+    if (TARGET_FDPIC && !SYMBOL_REF_P (XEXP (operands[0], 0)))
+       /* Indirect call: set r9 with FDPIC value of callee.  */
+       XEXP (operands[0], 0)
+         = arm_load_function_descriptor (XEXP (operands[0], 0));
+
     if (detect_cmse_nonsecure_call (addr))
       {
        pat = gen_nonsecure_call_internal (operands[0], operands[1],
        pat = gen_call_internal (operands[0], operands[1], operands[2]);
        arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
       }
+
+    /* Restore FDPIC register (r9) after call.  */
+    if (TARGET_FDPIC)
+      {
+       rtx fdpic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM);
+       rtx initial_fdpic_reg
+           = get_hard_reg_initial_val (Pmode, FDPIC_REGNUM);
+
+       emit_insn (gen_restore_pic_register_after_call (fdpic_reg,
+                                                       initial_fdpic_reg));
+      }
+
     DONE;
   }"
 )
 
+(define_insn "restore_pic_register_after_call"
+  [(set (match_operand:SI 0 "s_register_operand" "+r,r")
+        (unspec:SI [(match_dup 0)
+                    (match_operand:SI 1 "nonimmediate_operand" "r,m")]
+                   UNSPEC_PIC_RESTORE))]
+  ""
+  "@
+  mov\t%0, %1
+  ldr\t%0, %1"
+)
+
 (define_expand "call_internal"
   [(parallel [(call (match_operand 0 "memory_operand")
                    (match_operand 1 "general_operand"))
        : !REG_P (callee))
       XEXP (operands[1], 0) = force_reg (Pmode, callee);
 
+    if (TARGET_FDPIC && !SYMBOL_REF_P (XEXP (operands[1], 0)))
+       /* Indirect call: set r9 with FDPIC value of callee.  */
+       XEXP (operands[1], 0)
+         = arm_load_function_descriptor (XEXP (operands[1], 0));
+
     if (detect_cmse_nonsecure_call (addr))
       {
        pat = gen_nonsecure_call_value_internal (operands[0], operands[1],
                                       operands[2], operands[3]);
        arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
       }
+
+    /* Restore FDPIC register (r9) after call.  */
+    if (TARGET_FDPIC)
+      {
+       rtx fdpic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM);
+       rtx initial_fdpic_reg
+           = get_hard_reg_initial_val (Pmode, FDPIC_REGNUM);
+
+       emit_insn (gen_restore_pic_register_after_call (fdpic_reg,
+                                                       initial_fdpic_reg));
+      }
+
     DONE;
   }"
 )
                    (const_int 0))
              (match_operand 1 "" "")
              (match_operand 2 "" "")])]
-  "TARGET_EITHER"
+  "TARGET_EITHER && !TARGET_FDPIC"
   "
   {
     int i;
 (define_expand "untyped_return"
   [(match_operand:BLK 0 "memory_operand")
    (match_operand 1 "" "")]
-  "TARGET_EITHER"
+  "TARGET_EITHER && !TARGET_FDPIC"
   "
   {
     int i;
index 41068bac90aa0ce6fef531789a38e5f7b3b27dff..a9f99d04a8a5b3591f9f06910c292aac893ebb85 100644 (file)
@@ -89,6 +89,7 @@
   UNSPEC_SP_SET                ; Represent the setting of stack protector's canary
   UNSPEC_SP_TEST       ; Represent the testing of stack protector's canary
                        ; against the guard.
+  UNSPEC_PIC_RESTORE   ; Use to restore fdpic register
 ])
 
 (define_c_enum "unspec" [
index f738a231358eb1018d9ae8435a54a0e6819c791f..f277621c8c8bae469b07d905234dde7c42f5bdda 100644 (file)
@@ -1,3 +1,9 @@
+2019-09-10  Christophe Lyon  <christophe.lyon@st.com>
+       Mickaël Guêné <mickael.guene@st.com>
+
+       * gcc.target/arm/fp16-aapcs-2.c: Adjust scan-assembler-times.
+       * gcc.target/arm/fp16-aapcs-4.c: Likewise.
+
 2019-09-09  Marek Polacek  <polacek@redhat.com>
 
        PR c++/84374 - diagnose invalid uses of decltype(auto).
index 4753e364a226a618239a8fa14fc6fdf21a9730ef..51a76fc069353beb2bce7aeafcc682ca0428f9fe 100644 (file)
@@ -17,5 +17,5 @@ F (__fp16 a, __fp16 b, __fp16 c)
 }
 
 /* { dg-final { scan-assembler-times {mov\tr[0-9]+, r[0-2]} 3 } }  */
-/* { dg-final { scan-assembler-times {mov\tr1, r0} 1 } }  */
+/* { dg-final { scan-assembler-times {mov\tr1, r[03]} 1 } }  */
 /* { dg-final { scan-assembler-times {mov\tr0, r[0-9]+} 2 } }  */
index 41c7ab780a6a3c8318476947e801a68ebe0486f5..ae65fb86184e30dc693893e9ddbd4cbb38fc15e5 100644 (file)
@@ -16,5 +16,5 @@ F (__fp16 a, __fp16 b, __fp16 c)
 }
 
 /* { dg-final { scan-assembler-times {mov\tr[0-9]+, r[0-2]} 3 } }  */
-/* { dg-final { scan-assembler-times {mov\tr1, r0} 1 } }  */
+/* { dg-final { scan-assembler-times {mov\tr1, r[03]} 1 } }  */
 /* { dg-final { scan-assembler-times {mov\tr0, r[0-9]+} 2 } }  */