arm.c (pic_labelno): New.
authorDaniel Jacobowitz <dan@codesourcery.com>
Mon, 14 Nov 2005 17:07:42 +0000 (17:07 +0000)
committerDaniel Jacobowitz <drow@gcc.gnu.org>
Mon, 14 Nov 2005 17:07:42 +0000 (17:07 +0000)
* config/arm/arm.c (pic_labelno): New.
(arm_load_pic_register): Use an UNSPEC_PIC_LABEL instead of a
LABEL_REF.  Pass only the labelno to PIC insns.
(arm_call_tls_get_addr, legitimize_tls_address): Likewise.
(arm_output_addr_const_extra): Handle UNSPEC_PIC_LABEL.
* arm.md (UNSPEC_PIC_LABEL): New constant.
(pic_add_dot_plus_four, pic_add_dot_plus_eight)
(tls_load_dot_plus_eight): Expect a labelno instead of a LABEL_REF.
Use the correct label prefix.

From-SVN: r106893

gcc/ChangeLog
gcc/config/arm/arm.c
gcc/config/arm/arm.md

index d3b10b04a9fc5c94676d9768fe5518ff230d026a..8ad58d5fdabc45ee406964de36b5eb33acd16fba 100644 (file)
@@ -1,3 +1,15 @@
+2005-11-14  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * config/arm/arm.c (pic_labelno): New.
+       (arm_load_pic_register): Use an UNSPEC_PIC_LABEL instead of a
+       LABEL_REF.  Pass only the labelno to PIC insns.
+       (arm_call_tls_get_addr, legitimize_tls_address): Likewise.
+       (arm_output_addr_const_extra): Handle UNSPEC_PIC_LABEL.
+       * arm.md (UNSPEC_PIC_LABEL): New constant.
+       (pic_add_dot_plus_four, pic_add_dot_plus_eight)
+       (tls_load_dot_plus_eight): Expect a labelno instead of a LABEL_REF.
+       Use the correct label prefix.
+
 2005-11-14  Daniel Jacobowitz  <dan@codesourcery.com>
 
        * config/arm/arm.c (legitimize_tls_address): Use correct rtx for
index 4702efa2fb547c895cf82d722a2b3270f75c168d..c3a7562f8fa06645ace8aae2fb2f02b91aaecaa9 100644 (file)
@@ -3340,6 +3340,7 @@ thumb_find_work_register (unsigned long pushed_regs_mask)
   gcc_unreachable ();
 }
 
+static GTY(()) int pic_labelno;
 
 /* Generate code to load the PIC register.  In thumb mode SCRATCH is a
    low register.  */
@@ -3348,7 +3349,7 @@ void
 arm_load_pic_register (unsigned long saved_regs ATTRIBUTE_UNUSED)
 {
 #ifndef AOF_ASSEMBLER
-  rtx l1, pic_tmp, pic_tmp2, pic_rtx;
+  rtx l1, labelno, pic_tmp, pic_tmp2, pic_rtx;
   rtx global_offset_table;
 
   if (current_function_uses_pic_offset_table == 0 || TARGET_SINGLE_PIC_BASE)
@@ -3356,12 +3357,17 @@ arm_load_pic_register (unsigned long saved_regs ATTRIBUTE_UNUSED)
 
   gcc_assert (flag_pic);
 
-  l1 = gen_label_rtx ();
+  /* 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);
 
   global_offset_table = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
   /* On the ARM the PC register contains 'dot + 8' at the time of the
      addition, on the Thumb it is 'dot + 4'.  */
-  pic_tmp = plus_constant (gen_rtx_LABEL_REF (Pmode, l1), TARGET_ARM ? 8 : 4);
+  pic_tmp = plus_constant (l1, TARGET_ARM ? 8 : 4);
   if (GOT_PCREL)
     pic_tmp2 = gen_rtx_CONST (VOIDmode,
                            gen_rtx_PLUS (Pmode, global_offset_table, pc_rtx));
@@ -3374,7 +3380,7 @@ arm_load_pic_register (unsigned long saved_regs ATTRIBUTE_UNUSED)
     {
       emit_insn (gen_pic_load_addr_arm (pic_offset_table_rtx, pic_rtx));
       emit_insn (gen_pic_add_dot_plus_eight (pic_offset_table_rtx,
-                                            pic_offset_table_rtx, l1));
+                                            pic_offset_table_rtx, labelno));
     }
   else
     {
@@ -3390,7 +3396,7 @@ arm_load_pic_register (unsigned long saved_regs ATTRIBUTE_UNUSED)
       else
        emit_insn (gen_pic_load_addr_thumb (pic_offset_table_rtx, pic_rtx));
       emit_insn (gen_pic_add_dot_plus_four (pic_offset_table_rtx,
-                                           pic_offset_table_rtx, l1));
+                                           pic_offset_table_rtx, labelno));
     }
 
   /* Need to emit this whether or not we obey regdecls,
@@ -3822,22 +3828,24 @@ load_tls_operand (rtx x, rtx reg)
 static rtx
 arm_call_tls_get_addr (rtx x, rtx reg, rtx *valuep, int reloc)
 {
-  rtx insns, label, sum;
+  rtx insns, label, labelno, sum;
 
   start_sequence ();
 
-  label = gen_label_rtx ();
+  labelno = GEN_INT (pic_labelno++);
+  label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL);
+  label = gen_rtx_CONST (VOIDmode, label);
+
   sum = gen_rtx_UNSPEC (Pmode,
-                       gen_rtvec (4, x, GEN_INT (reloc),
-                                  gen_rtx_LABEL_REF (Pmode, label),
+                       gen_rtvec (4, x, GEN_INT (reloc), label,
                                   GEN_INT (TARGET_ARM ? 8 : 4)),
                        UNSPEC_TLS);
   reg = load_tls_operand (sum, reg);
 
   if (TARGET_ARM)
-    emit_insn (gen_pic_add_dot_plus_eight (reg, reg, label));
+    emit_insn (gen_pic_add_dot_plus_eight (reg, reg, labelno));
   else
-    emit_insn (gen_pic_add_dot_plus_four (reg, reg, label));
+    emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno));
 
   *valuep = emit_library_call_value (get_tls_get_addr (), NULL_RTX, LCT_PURE, /* LCT_CONST?  */
                                     Pmode, 1, reg, Pmode);
@@ -3851,7 +3859,7 @@ arm_call_tls_get_addr (rtx x, rtx reg, rtx *valuep, int reloc)
 rtx
 legitimize_tls_address (rtx x, rtx reg)
 {
-  rtx dest, tp, label, sum, insns, ret, eqv, addend;
+  rtx dest, tp, label, labelno, sum, insns, ret, eqv, addend;
   unsigned int model = SYMBOL_REF_TLS_MODEL (x);
 
   switch (model)
@@ -3879,19 +3887,20 @@ legitimize_tls_address (rtx x, rtx reg)
       return gen_rtx_PLUS (Pmode, dest, addend);
 
     case TLS_MODEL_INITIAL_EXEC:
-      label = gen_label_rtx ();
+      labelno = GEN_INT (pic_labelno++);
+      label = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, labelno), UNSPEC_PIC_LABEL);
+      label = gen_rtx_CONST (VOIDmode, label);
       sum = gen_rtx_UNSPEC (Pmode,
-                           gen_rtvec (4, x, GEN_INT (TLS_IE32),
-                                      gen_rtx_LABEL_REF (Pmode, label),
+                           gen_rtvec (4, x, GEN_INT (TLS_IE32), label,
                                       GEN_INT (TARGET_ARM ? 8 : 4)),
                            UNSPEC_TLS);
       reg = load_tls_operand (sum, reg);
 
       if (TARGET_ARM)
-       emit_insn (gen_tls_load_dot_plus_eight (reg, reg, label));
+       emit_insn (gen_tls_load_dot_plus_eight (reg, reg, labelno));
       else
        {
-         emit_insn (gen_pic_add_dot_plus_four (reg, reg, label));
+         emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno));
          emit_move_insn (reg, gen_const_mem (SImode, reg));
        }
 
@@ -15431,6 +15440,16 @@ arm_output_addr_const_extra (FILE *fp, rtx x)
 {
   if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLS)
     return arm_emit_tls_decoration (fp, x);
+  else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_PIC_LABEL)
+    {
+      char label[256];
+      int labelno = INTVAL (XVECEXP (x, 0, 0));
+
+      ASM_GENERATE_INTERNAL_LABEL (label, "LPIC", labelno);
+      assemble_name_raw (fp, label);
+
+      return TRUE;
+    }
   else if (GET_CODE (x) == CONST_VECTOR)
     return arm_emit_vector_const (fp, x);
 
index 5ad2266de808b682957c1c5b7d5f4567e93ec1f2..1b671fa1d1ee73a315c4c16cc2f3c6df107a35c3 100644 (file)
@@ -91,6 +91,8 @@
    (UNSPEC_WMADDS   18) ; Used by the intrinsic form of the iWMMXt WMADDS instruction.
    (UNSPEC_WMADDU   19) ; Used by the intrinsic form of the iWMMXt WMADDU instruction.
    (UNSPEC_TLS      20) ; A symbol that has been treated properly for TLS usage.
+   (UNSPEC_PIC_LABEL 21) ; A label used for PIC access that does not appear in the
+                         ; instruction stream.
   ]
 )
 
        (unspec:SI [(plus:SI (match_operand:SI 1 "register_operand" "0")
                             (const (plus:SI (pc) (const_int 4))))]
                   UNSPEC_PIC_BASE))
-   (use (label_ref (match_operand 2 "" "")))]
+   (use (match_operand 2 "" ""))]
   "TARGET_THUMB"
   "*
-  (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
-                            CODE_LABEL_NUMBER (operands[2]));
+  (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
+                                    INTVAL (operands[2]));
   return \"add\\t%0, %|pc\";
   "
   [(set_attr "length" "2")]
        (unspec:SI [(plus:SI (match_operand:SI 1 "register_operand" "r")
                             (const (plus:SI (pc) (const_int 8))))]
                   UNSPEC_PIC_BASE))
-   (use (label_ref (match_operand 2 "" "")))]
+   (use (match_operand 2 "" ""))]
   "TARGET_ARM"
   "*
-    (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
-                              CODE_LABEL_NUMBER (operands[2]));
+    (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
+                                      INTVAL (operands[2]));
     return \"add%?\\t%0, %|pc, %1\";
   "
   [(set_attr "predicable" "yes")]
        (mem:SI (unspec:SI [(plus:SI (match_operand:SI 1 "register_operand" "r")
                                     (const (plus:SI (pc) (const_int 8))))]
                           UNSPEC_PIC_BASE)))
-   (use (label_ref (match_operand 2 "" "")))]
+   (use (match_operand 2 "" ""))]
   "TARGET_ARM"
   "*
-    (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
-                              CODE_LABEL_NUMBER (operands[2]));
+    (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
+                                      INTVAL (operands[2]));
     return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
   "
   [(set_attr "predicable" "yes")]