]> gcc.gnu.org Git - gcc.git/commitdiff
output.h (enum section_category): Export from varasm.c
authorJan Hubicka <jh@suse.cz>
Sun, 31 Jul 2005 09:12:34 +0000 (11:12 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sun, 31 Jul 2005 09:12:34 +0000 (09:12 +0000)
* output.h (enum section_category): Export from varasm.c
(categorize_decl_for_section): Likewise.
* varasm.c (enum section_category): Kill.
(categorize_decl_for_section): Make global.
* i386-protos.h (x86_output_aligned_bss, x86_elf_aligned_common):
Declare.
* i386.c (ix86_section_threshold): New static variable.
(ix86_in_large_data_p, ix86_encode_section_info,
x86_64_elf_unique_section,
x86_64_elf_select_section): New functions.
(TARGET_ENCODE_SECTION_INFO): Define
(override_options): Enable medium model for PIC.
(ix86_expand_prologue): Expand gen_set_got_rex64.
(legitimate_constant_p): Handle new UNSPECs.
(legitimate_pic_address_disp_p): Likewise.
(legitimize_pic_address): Lower MEDIUM model addressing.
* i386.h (PIC_OFFSET_TABLE_REGNUM): Set for medium model PIC.
(enum cmodel): Add MEDIUM_PIC.
(SYMBOL_REF_FAR_ADDR_P): New macro.
(SYMBOL_FLAG_FAR_ADDR): New flag.
* i386.md (movdi): Support medium model.
(set_got_rex64): New pattern.
* i386.opt (mlarge-data-threshold): New flag.
* predicates.md (zext_operand/sext_operand): Deal with medium model.
* x86-64.h (ASM_OUTPUT_ALIGNED_BSS): Use x86_output_aligned_bss.
(ASM_OUTPUT_ALIGNED_COMMON, TARGET_ASM_SELECT_SECTION,
TARGET_ASM_UNIQUE_SECTION): New.

* invoke.texi (-mlarge_data_threshold): Document

From-SVN: r102606

gcc/ChangeLog
gcc/config/i386/i386-protos.h
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/config/i386/i386.md
gcc/config/i386/i386.opt
gcc/config/i386/predicates.md
gcc/config/i386/x86-64.h
gcc/doc/invoke.texi
gcc/output.h
gcc/varasm.c

index a2c7bdc02729c1f3971ee69a88bc58222b5394c3..967a610e24d65b1c77ed0923dc4d92396225963d 100644 (file)
@@ -1,3 +1,35 @@
+2005-07-31  Jan Hubicka  <jh@suse.cz>
+
+       * output.h (enum section_category): Export from varasm.c
+       (categorize_decl_for_section): Likewise.
+       * varasm.c (enum section_category): Kill.
+       (categorize_decl_for_section): Make global.
+       * i386-protos.h (x86_output_aligned_bss, x86_elf_aligned_common):
+       Declare.
+       * i386.c (ix86_section_threshold): New static variable.
+       (ix86_in_large_data_p, ix86_encode_section_info,
+       x86_64_elf_unique_section,
+       x86_64_elf_select_section): New functions.
+       (TARGET_ENCODE_SECTION_INFO): Define
+       (override_options): Enable medium model for PIC.
+       (ix86_expand_prologue): Expand gen_set_got_rex64.
+       (legitimate_constant_p): Handle new UNSPECs.
+       (legitimate_pic_address_disp_p): Likewise.
+       (legitimize_pic_address): Lower MEDIUM model addressing.
+       * i386.h (PIC_OFFSET_TABLE_REGNUM): Set for medium model PIC.
+       (enum cmodel): Add MEDIUM_PIC.
+       (SYMBOL_REF_FAR_ADDR_P): New macro.
+       (SYMBOL_FLAG_FAR_ADDR): New flag.
+       * i386.md (movdi): Support medium model.
+       (set_got_rex64): New pattern.
+       * i386.opt (mlarge-data-threshold): New flag.
+       * predicates.md (zext_operand/sext_operand): Deal with medium model.
+       * x86-64.h (ASM_OUTPUT_ALIGNED_BSS): Use x86_output_aligned_bss.
+       (ASM_OUTPUT_ALIGNED_COMMON, TARGET_ASM_SELECT_SECTION,
+       TARGET_ASM_UNIQUE_SECTION): New.
+
+       * invoke.texi (-mlarge_data_threshold): Document
+
 2005-07-31  Jan Hubicka  <jh@suse.cz>
 
        * tree-outof-ssa.c (coalesce_ssa_name): Use coalesce_cost.
index dfbf11ac25646ae99004ea7d89f68740e5699df2..94cecdc9ca22d08c78bcaa75e371125ce0532811 100644 (file)
@@ -259,6 +259,10 @@ struct ix86_address
 
 extern int ix86_decompose_address (rtx, struct ix86_address *);
 extern int memory_address_length (rtx addr);
+extern void x86_output_aligned_bss (FILE *, tree, const char *,
+                                   unsigned HOST_WIDE_INT, int);
+extern void x86_elf_aligned_common (FILE *, const char *,
+                                   unsigned HOST_WIDE_INT, int);
 
 #ifdef RTX_CODE
 extern void ix86_fp_comparison_codes (enum rtx_code code, enum rtx_code *,
index e9cf7db9f858c20ab353e69141b5eff4e65dcd99..94648b1d38f2d4e6158c1d3955fac7393b9d7843 100644 (file)
@@ -812,6 +812,11 @@ unsigned int ix86_preferred_stack_boundary;
 /* Values 1-5: see jump.c */
 int ix86_branch_cost;
 
+/* Variables which are this size or smaller are put in the data/bss
+   or ldata/lbss sections.  */
+
+int ix86_section_threshold = 65536;
+
 /* Prefix built by ASM_GENERATE_INTERNAL_LABEL.  */
 char internal_label_prefix[16];
 int internal_label_prefix_len;
@@ -945,6 +950,12 @@ static const char * const x86_64_reg_class_name[] = {
 static REAL_VALUE_TYPE ext_80387_constants_table [5];
 static bool ext_80387_constants_init = 0;
 static void init_ext_80387_constants (void);
+static bool ix86_in_large_data_p (tree);
+static void ix86_encode_section_info (tree, rtx, int);
+static void x86_64_elf_unique_section (tree decl, int reloc) ATTRIBUTE_UNUSED;
+static void x86_64_elf_select_section (tree decl, int reloc,
+                                      unsigned HOST_WIDE_INT align)
+                                     ATTRIBUTE_UNUSED;
 \f
 /* Initialize the GCC target structure.  */
 #undef TARGET_ATTRIBUTE_TABLE
@@ -965,6 +976,9 @@ static void init_ext_80387_constants (void);
 #undef TARGET_ASM_FUNCTION_EPILOGUE
 #define TARGET_ASM_FUNCTION_EPILOGUE ix86_output_function_epilogue
 
+#undef TARGET_ENCODE_SECTION_INFO
+#define TARGET_ENCODE_SECTION_INFO ix86_encode_section_info
+
 #undef TARGET_ASM_OPEN_PAREN
 #define TARGET_ASM_OPEN_PAREN ""
 #undef TARGET_ASM_CLOSE_PAREN
@@ -1291,14 +1305,14 @@ override_options (void)
     {
       if (!strcmp (ix86_cmodel_string, "small"))
        ix86_cmodel = flag_pic ? CM_SMALL_PIC : CM_SMALL;
+      else if (!strcmp (ix86_cmodel_string, "medium"))
+       ix86_cmodel = flag_pic ? CM_MEDIUM_PIC : CM_MEDIUM;
       else if (flag_pic)
        sorry ("code model %s not supported in PIC mode", ix86_cmodel_string);
       else if (!strcmp (ix86_cmodel_string, "32"))
        ix86_cmodel = CM_32;
       else if (!strcmp (ix86_cmodel_string, "kernel") && !flag_pic)
        ix86_cmodel = CM_KERNEL;
-      else if (!strcmp (ix86_cmodel_string, "medium") && !flag_pic)
-       ix86_cmodel = CM_MEDIUM;
       else if (!strcmp (ix86_cmodel_string, "large") && !flag_pic)
        ix86_cmodel = CM_LARGE;
       else
@@ -1502,6 +1516,14 @@ override_options (void)
       else
        ix86_branch_cost = i;
     }
+  if (ix86_section_threshold_string)
+    {
+      i = atoi (ix86_section_threshold_string);
+      if (i < 0)
+       error ("-mlarge-data-threshold=%d is negative", i);
+      else
+       ix86_section_threshold = i;
+    }
 
   if (ix86_tls_dialect_string)
     {
@@ -1641,6 +1663,175 @@ override_options (void)
     flag_schedule_insns_after_reload = flag_schedule_insns = 0;
 }
 \f
+/* switch to the appropriate section for output of DECL.
+   DECL is either a `VAR_DECL' node or a constant of some sort.
+   RELOC indicates whether forming the initial value of DECL requires
+   link-time relocations.  */
+
+static void
+x86_64_elf_select_section (tree decl, int reloc,
+                        unsigned HOST_WIDE_INT align)
+{
+  if ((ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_MEDIUM_PIC)
+      && ix86_in_large_data_p (decl))
+    {
+      const char *sname = NULL;
+      switch (categorize_decl_for_section (decl, reloc, flag_pic))
+       {
+       case SECCAT_DATA:
+         sname = ".ldata";
+         break;
+       case SECCAT_DATA_REL:
+         sname = ".ldata.rel";
+         break;
+       case SECCAT_DATA_REL_LOCAL:
+         sname = ".ldata.rel.local";
+         break;
+       case SECCAT_DATA_REL_RO:
+         sname = ".ldata.rel.ro";
+         break;
+       case SECCAT_DATA_REL_RO_LOCAL:
+         sname = ".ldata.rel.ro.local";
+         break;
+       case SECCAT_BSS:
+         sname = ".lbss";
+         break;
+       case SECCAT_RODATA:
+       case SECCAT_RODATA_MERGE_STR:
+       case SECCAT_RODATA_MERGE_STR_INIT:
+       case SECCAT_RODATA_MERGE_CONST:
+         sname = ".lrodata";
+         break;
+       case SECCAT_SRODATA:
+       case SECCAT_SDATA:
+       case SECCAT_SBSS:
+         gcc_unreachable ();
+       case SECCAT_TEXT:
+       case SECCAT_TDATA:
+       case SECCAT_TBSS:
+         /* We don't split these for medium model.  Place them into
+            default sections and hope for best.  */
+         break;
+       }
+      if (sname)
+       {
+          named_section (decl, sname, reloc);
+         return;
+       }
+    }
+  default_elf_select_section (decl, reloc, align);
+}
+
+/* Build up a unique section name, expressed as a
+   STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
+   RELOC indicates whether the initial value of EXP requires
+   link-time relocations.  */
+
+static void
+x86_64_elf_unique_section (tree decl, int reloc)
+{
+  if ((ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_MEDIUM_PIC)
+      && ix86_in_large_data_p (decl))
+    {
+      const char *prefix = NULL;
+      /* We only need to use .gnu.linkonce if we don't have COMDAT groups.  */
+      bool one_only = DECL_ONE_ONLY (decl) && !HAVE_COMDAT_GROUP;
+
+      switch (categorize_decl_for_section (decl, reloc, flag_pic))
+       {
+       case SECCAT_DATA:
+       case SECCAT_DATA_REL:
+       case SECCAT_DATA_REL_LOCAL:
+       case SECCAT_DATA_REL_RO:
+       case SECCAT_DATA_REL_RO_LOCAL:
+          prefix = one_only ? ".gnu.linkonce.ld." : ".ldata.";
+         break;
+       case SECCAT_BSS:
+          prefix = one_only ? ".gnu.linkonce.lb." : ".lbss.";
+         break;
+       case SECCAT_RODATA:
+       case SECCAT_RODATA_MERGE_STR:
+       case SECCAT_RODATA_MERGE_STR_INIT:
+       case SECCAT_RODATA_MERGE_CONST:
+          prefix = one_only ? ".gnu.linkonce.lr." : ".lrodata.";
+         break;
+       case SECCAT_SRODATA:
+       case SECCAT_SDATA:
+       case SECCAT_SBSS:
+         gcc_unreachable ();
+       case SECCAT_TEXT:
+       case SECCAT_TDATA:
+       case SECCAT_TBSS:
+         /* We don't split these for medium model.  Place them into
+            default sections and hope for best.  */
+         break;
+       }
+      if (prefix)
+       {
+         const char *name;
+         size_t nlen, plen;
+         char *string;
+         plen = strlen (prefix);
+
+         name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+         name = targetm.strip_name_encoding (name);
+         nlen = strlen (name);
+
+         string = alloca (nlen + plen + 1);
+         memcpy (string, prefix, plen);
+         memcpy (string + plen, name, nlen + 1);
+
+         DECL_SECTION_NAME (decl) = build_string (nlen + plen, string);
+         return;
+       }
+    }
+  default_unique_section (decl, reloc);
+}
+
+/* This says how to output assembler code to declare an
+   uninitialized external linkage data object.
+
+   For medim model x86-64 we need to use .largecomm opcode for
+   large objects.  */
+void
+x86_elf_aligned_common (FILE *file,
+                       const char *name, unsigned HOST_WIDE_INT size,
+                       int align)
+{
+  if ((ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_MEDIUM_PIC)
+      && size > (unsigned int)ix86_section_threshold)
+    fprintf (file, ".largecomm\t");
+  else
+    fprintf (file, "%s", COMMON_ASM_OP);
+  assemble_name (file, name);
+  fprintf (file, ","HOST_WIDE_INT_PRINT_UNSIGNED",%u\n",
+          size, align / BITS_PER_UNIT);
+}
+
+/* Utility function for targets to use in implementing
+   ASM_OUTPUT_ALIGNED_BSS.  */
+
+void
+x86_output_aligned_bss (FILE *file, tree decl ATTRIBUTE_UNUSED,
+                       const char *name, unsigned HOST_WIDE_INT size,
+                       int align)
+{
+  if ((ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_MEDIUM_PIC)
+      && size > (unsigned int)ix86_section_threshold)
+    named_section (decl, ".lbss", 0);
+  else
+    bss_section ();
+  ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
+#ifdef ASM_DECLARE_OBJECT_NAME
+  last_assemble_variable_decl = decl;
+  ASM_DECLARE_OBJECT_NAME (file, name, decl);
+#else
+  /* Standard thing is just output label for the object.  */
+  ASM_OUTPUT_LABEL (file, name);
+#endif /* ASM_DECLARE_OBJECT_NAME */
+  ASM_OUTPUT_SKIP (file, size ? size : 1);
+}
+\f
 void
 optimization_options (int level, int size ATTRIBUTE_UNUSED)
 {
@@ -4644,7 +4835,10 @@ ix86_expand_prologue (void)
 
   if (pic_reg_used)
     {
-      insn = emit_insn (gen_set_got (pic_offset_table_rtx));
+      if (TARGET_64BIT)
+        insn = emit_insn (gen_set_got_rex64 (pic_offset_table_rtx));
+      else
+        insn = emit_insn (gen_set_got (pic_offset_table_rtx));
 
       /* Even with accurate pre-reload life analysis, we can wind up
         deleting all references to the pic register after reload.
@@ -5173,6 +5367,8 @@ legitimate_constant_p (rtx x)
       if (GET_CODE (x) == UNSPEC)
        switch (XINT (x, 1))
          {
+         case UNSPEC_GOTOFF:
+           return TARGET_64BIT;
          case UNSPEC_TPOFF:
          case UNSPEC_NTPOFF:
            return local_exec_symbolic_operand (XVECEXP (x, 0, 0), Pmode);
@@ -5232,11 +5428,16 @@ legitimate_pic_operand_p (rtx x)
     {
     case CONST:
       inner = XEXP (x, 0);
+      if (GET_CODE (inner) == PLUS
+         && GET_CODE (XEXP (inner, 1)) == CONST_INT)
+       inner = XEXP (inner, 0);
 
       /* Only some unspecs are valid as "constants".  */
       if (GET_CODE (inner) == UNSPEC)
        switch (XINT (inner, 1))
          {
+         case UNSPEC_GOTOFF:
+           return TARGET_64BIT;
          case UNSPEC_TPOFF:
            return local_exec_symbolic_operand (XVECEXP (inner, 0, 0), Pmode);
          default:
@@ -5269,7 +5470,7 @@ legitimate_pic_address_disp_p (rtx disp)
       if (tls_symbolic_operand (disp, GET_MODE (disp)))
        return 0;
       if (GET_CODE (disp) == SYMBOL_REF
-         && ix86_cmodel == CM_SMALL_PIC
+         && !SYMBOL_REF_FAR_ADDR_P (disp)
          && SYMBOL_REF_LOCAL_P (disp))
        return 1;
       if (GET_CODE (disp) == LABEL_REF)
@@ -5284,7 +5485,7 @@ legitimate_pic_address_disp_p (rtx disp)
          if (tls_symbolic_operand (op0, GET_MODE (op0)))
            return 0;
          if (((GET_CODE (op0) == SYMBOL_REF
-               && ix86_cmodel == CM_SMALL_PIC
+               && !SYMBOL_REF_FAR_ADDR_P (op0)
                && SYMBOL_REF_LOCAL_P (op0))
               || GET_CODE (op0) == LABEL_REF)
              && GET_CODE (op1) == CONST_INT
@@ -5302,7 +5503,8 @@ legitimate_pic_address_disp_p (rtx disp)
       /* We are unsafe to allow PLUS expressions.  This limit allowed distance
          of GOT tables.  We should not need these anyway.  */
       if (GET_CODE (disp) != UNSPEC
-         || XINT (disp, 1) != UNSPEC_GOTPCREL)
+         || (XINT (disp, 1) != UNSPEC_GOTPCREL
+             && XINT (disp, 1) != UNSPEC_GOTOFF))
        return 0;
 
       if (GET_CODE (XVECEXP (disp, 0, 0)) != SYMBOL_REF
@@ -5632,6 +5834,40 @@ legitimize_pic_address (rtx orig, rtx reg)
 
   if (TARGET_64BIT && legitimate_pic_address_disp_p (addr))
     new = addr;
+  else if (TARGET_64BIT
+          && ix86_cmodel != CM_SMALL_PIC
+          && local_symbolic_operand (addr, Pmode))
+    {
+      rtx tmpreg;
+      /* This symbol may be referenced via a displacement from the PIC
+        base address (@GOTOFF).  */
+
+      if (reload_in_progress)
+       regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
+      if (GET_CODE (addr) == CONST)
+       addr = XEXP (addr, 0);
+      if (GET_CODE (addr) == PLUS)
+         {
+            new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (addr, 0)), UNSPEC_GOTOFF);
+           new = gen_rtx_PLUS (Pmode, new, XEXP (addr, 1));
+         }
+       else
+          new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
+      new = gen_rtx_CONST (Pmode, new);
+      if (!reg)
+        tmpreg = gen_reg_rtx (Pmode);
+      else
+       tmpreg = reg;
+      emit_move_insn (tmpreg, new);
+
+      if (reg != 0)
+       {
+         new = expand_simple_binop (Pmode, PLUS, reg, pic_offset_table_rtx,
+                                    tmpreg, 1, OPTAB_DIRECT);
+         new = reg;
+       }
+      else new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, tmpreg);
+    }
   else if (!TARGET_64BIT && local_symbolic_operand (addr, Pmode))
     {
       /* This symbol may be referenced via a displacement from the PIC
@@ -7884,7 +8120,7 @@ ix86_expand_move (enum machine_mode mode, rtx operands[])
 #else
       if (GET_CODE (op0) == MEM)
        op1 = force_reg (Pmode, op1);
-      else
+      else 
        op1 = legitimize_address (op1, op1, Pmode);
 #endif /* TARGET_MACHO */
     }
@@ -17525,6 +17761,49 @@ ix86_md_asm_clobbers (tree outputs ATTRIBUTE_UNUSED,
   return clobbers;
 }
 
+/* Return true if this goes in small data/bss.  */
+
+static bool
+ix86_in_large_data_p (tree exp)
+{
+  if (ix86_cmodel != CM_MEDIUM && ix86_cmodel != CM_MEDIUM_PIC)
+    return false;
+
+  /* Functions are never large data.  */
+  if (TREE_CODE (exp) == FUNCTION_DECL)
+    return false;
+
+  if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
+    {
+      const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp));
+      if (strcmp (section, ".ldata") == 0
+         || strcmp (section, ".lbss") == 0)
+       return true;
+      return false;
+    }
+  else
+    {
+      HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
+
+      /* If this is an incomplete type with size 0, then we can't put it
+        in data because it might be too big when completed.  */
+      if (!size || size > ix86_section_threshold)
+       return true;
+    }
+
+  return false;
+}
+static void
+ix86_encode_section_info (tree decl, rtx rtl, int first)
+{
+  default_encode_section_info (decl, rtl, first);
+
+  if (TREE_CODE (decl) == VAR_DECL
+      && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
+      && ix86_in_large_data_p (decl))
+    SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= SYMBOL_FLAG_FAR_ADDR;
+}
+
 /* Worker function for REVERSE_CONDITION.  */
 
 enum rtx_code
index e140bd291a238a094548702003d225bb14cf5851..d1f5dd95f563a350f6b38ea797122530c3a33c86 100644 (file)
@@ -961,7 +961,8 @@ do {                                                                        \
 #define REAL_PIC_OFFSET_TABLE_REGNUM  3
 
 #define PIC_OFFSET_TABLE_REGNUM                                \
-  (TARGET_64BIT || !flag_pic ? INVALID_REGNUM          \
+  ((TARGET_64BIT && ix86_cmodel == CM_SMALL_PIC)       \
+   || !flag_pic ? INVALID_REGNUM                       \
    : reload_completed ? REGNO (pic_offset_table_rtx)   \
    : REAL_PIC_OFFSET_TABLE_REGNUM)
 
@@ -2143,7 +2144,8 @@ enum cmodel {
   CM_KERNEL,   /* Assumes all code and data fits in the high 31 bits.  */
   CM_MEDIUM,   /* Assumes code fits in the low 31 bits; data unlimited.  */
   CM_LARGE,    /* No assumptions.  */
-  CM_SMALL_PIC /* Assumes code+data+got/plt fits in a 31 bit region.  */
+  CM_SMALL_PIC,        /* Assumes code+data+got/plt fits in a 31 bit region.  */
+  CM_MEDIUM_PIC        /* Assumes code+got/plt fits in a 31 bit region.  */
 };
 
 extern enum cmodel ix86_cmodel;
@@ -2160,7 +2162,7 @@ enum asm_dialect {
 
 extern enum asm_dialect ix86_asm_dialect;
 extern unsigned int ix86_preferred_stack_boundary;
-extern int ix86_branch_cost;
+extern int ix86_branch_cost, ix86_section_threshold;
 
 /* Smallest class containing REGNO.  */
 extern enum reg_class const regclass_map[FIRST_PSEUDO_REGISTER];
@@ -2281,6 +2283,10 @@ struct machine_function GTY(())
 #define X86_FILE_START_VERSION_DIRECTIVE false
 #define X86_FILE_START_FLTUSED false
 
+/* Flag to mark data that is in the large address area.  */
+#define SYMBOL_FLAG_FAR_ADDR           (SYMBOL_FLAG_MACH_DEP << 0)
+#define SYMBOL_REF_FAR_ADDR_P(X)       \
+       ((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_FAR_ADDR) != 0)
 /*
 Local variables:
 version-control: t
index 685c645af134b7b4dc0d382db861c9eaabb38cee..d533408b7700cf06cfc7c412c1e7b2f5b1aa3b4c 100644 (file)
   [(set_attr "type" "multi")
    (set_attr "length" "12")])
 
+(define_insn "set_got_rex64"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
+  "TARGET_64BIT"
+  "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
+  [(set_attr "type" "lea")
+   (set_attr "length" "6")])
+
 (define_expand "epilogue"
   [(const_int 1)]
   ""
index effd1e16aa0094cfbffc8b7e7f300612cd82bc48..2a51fcbedbbb60bac4db80e404f319785b0541f7 100644 (file)
@@ -87,6 +87,10 @@ mbranch-cost=
 Target RejectNegative Joined Var(ix86_branch_cost_string)
 Branches are this expensive (1-5, arbitrary units)
 
+mlarge-data-threshold=
+Target RejectNegative Joined Var(ix86_section_threshold_string)
+Data greater than given threshold will go into .ldata section in x86-64 medium model
+
 mcmodel=
 Target RejectNegative Joined Var(ix86_cmodel_string)
 Use given x86-64 code model
index 292d46e52fee39a0db9864f2f6bcf54e43a3a4ee..f8ff8049d0f37294d5d5be52b8672397758ba88b 100644 (file)
       /* TLS symbols are not constant.  */
       if (tls_symbolic_operand (op, Pmode))
        return false;
-      return (ix86_cmodel == CM_SMALL || ix86_cmodel == CM_KERNEL);
+      return (ix86_cmodel == CM_SMALL || ix86_cmodel == CM_KERNEL
+             || (ix86_cmodel == CM_MEDIUM && !SYMBOL_REF_FAR_ADDR_P (op)));
 
     case LABEL_REF:
       /* For certain code models, the code is near as well.  */
                 end of 31bits boundary.  We may also accept pretty
                 large negative constants knowing that all objects are
                 in the positive half of address space.  */
-             if (ix86_cmodel == CM_SMALL
+             if ((ix86_cmodel == CM_SMALL
+                  || (ix86_cmodel == CM_MEDIUM
+                      && !SYMBOL_REF_FAR_ADDR_P (op1)))
                  && offset < 16*1024*1024
                  && trunc_int_for_mode (offset, SImode) == offset)
                return 1;
       /* TLS symbols are not constant.  */
       if (tls_symbolic_operand (op, Pmode))
        return false;
-      return ix86_cmodel == CM_SMALL;
+      return (ix86_cmodel == CM_SMALL
+             || (ix86_cmodel == CM_MEDIUM
+                 && !SYMBOL_REF_FAR_ADDR_P (op)));
 
     case LABEL_REF:
       /* For certain code models, the code is near as well.  */
                 offsets, since one bit is available for free.  Negative
                 offsets are limited by the size of NULL pointer area
                 specified by the ABI.  */
-             if (ix86_cmodel == CM_SMALL
+             if ((ix86_cmodel == CM_SMALL
+                  || (ix86_cmodel == CM_MEDIUM
+                      && !SYMBOL_REF_FAR_ADDR_P (op1)))
                  && GET_CODE (op2) == CONST_INT
                  && trunc_int_for_mode (INTVAL (op2), DImode) > -0x10000
                  && trunc_int_for_mode (INTVAL (op2), SImode) == INTVAL (op2))
index c80353b0df193d1fc5cbd6d9b4c8d090a8b3303d..b0e6947e86311af428ef007f1db7b053da4858a5 100644 (file)
@@ -52,7 +52,11 @@ Boston, MA 02110-1301, USA.  */
  %{Wa,*:%*} %{m32:--32} %{m64:--64}"
 
 #define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
-  asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)
+  x86_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)
+
+#undef  ASM_OUTPUT_ALIGNED_COMMON
+#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN)             \
+  x86_elf_aligned_common (FILE, NAME, SIZE, ALIGN);
 
 /* This is used to align code labels according to Intel recommendations.  */
 
@@ -75,3 +79,9 @@ Boston, MA 02110-1301, USA.  */
 
 #undef PREFERRED_DEBUGGING_TYPE
 #define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
+
+#undef TARGET_ASM_SELECT_SECTION
+#define TARGET_ASM_SELECT_SECTION  x86_64_elf_select_section
+
+#undef TARGET_ASM_UNIQUE_SECTION
+#define TARGET_ASM_UNIQUE_SECTION  x86_64_elf_unique_section
index 5004419a89743b0d87d9f7016e43e9b1a729283d..399083de5c136de9b5babe561582b270af6bf7e6 100644 (file)
@@ -521,7 +521,7 @@ Objective-C and Objective-C++ Dialects}.
 -m96bit-long-double  -mregparm=@var{num}  -msseregparm @gol
 -momit-leaf-frame-pointer  -mno-red-zone -mno-tls-direct-seg-refs @gol
 -mcmodel=@var{code-model} @gol
--m32  -m64}
+-m32  -m64 -mlarge-data-threshold=@var{num}}
 
 @emph{IA-64 Options}
 @gccoptlist{-mbig-endian  -mlittle-endian  -mgnu-as  -mgnu-ld  -mno-pic @gol
@@ -9046,6 +9046,11 @@ their size as well as function calling convention for function taking
 @code{long double} will be modified.  Hence they will not be binary
 compatible with arrays or structures in code compiled without that switch.
 
+@item -mmlarge-data-threshold=@var{number}
+@opindex mlarge-data-threshold=@var{number}
+When @option{-mcmodel=medium} is specified, the data greater than
+@var{threshold} are placed in large data section.  This value must be the
+same across all object linked into the binarry and defaults to 65535.
 
 @item -msvr3-shlib
 @itemx -mno-svr3-shlib
index 221e4df185076d2aae770d1b5c62fa4a5e200407..c0dfb5fd1c432035506c07146683f70323b69fb8 100644 (file)
@@ -500,6 +500,44 @@ extern void no_asm_to_stream (FILE *);
 #define SECTION_NOTYPE  0x80000        /* don't output @progbits */
 #define SECTION_MACH_DEP 0x100000      /* subsequent bits reserved for target */
 
+/* A helper function for default_elf_select_section and
+   default_elf_unique_section.  Categorizes the DECL.  */
+
+enum section_category
+{
+  SECCAT_TEXT,
+
+  SECCAT_RODATA,
+  SECCAT_RODATA_MERGE_STR,
+  SECCAT_RODATA_MERGE_STR_INIT,
+  SECCAT_RODATA_MERGE_CONST,
+  SECCAT_SRODATA,
+
+  SECCAT_DATA,
+
+  /* To optimize loading of shared programs, define following subsections
+     of data section:
+       _REL    Contains data that has relocations, so they get grouped
+               together and dynamic linker will visit fewer pages in memory.
+       _RO     Contains data that is otherwise read-only.  This is useful
+               with prelinking as most relocations won't be dynamically
+               linked and thus stay read only.
+       _LOCAL  Marks data containing relocations only to local objects.
+               These relocations will get fully resolved by prelinking.  */
+  SECCAT_DATA_REL,
+  SECCAT_DATA_REL_LOCAL,
+  SECCAT_DATA_REL_RO,
+  SECCAT_DATA_REL_RO_LOCAL,
+
+  SECCAT_SDATA,
+  SECCAT_TDATA,
+
+  SECCAT_BSS,
+  SECCAT_SBSS,
+  SECCAT_TBSS
+};
+
+
 extern bool set_named_section_flags (const char *, unsigned int);
 #define named_section_flags(NAME, FLAGS) \
   named_section_real((NAME), (FLAGS), /*decl=*/NULL_TREE)
@@ -510,6 +548,7 @@ extern unsigned int default_section_type_flags_1 (tree, const char *, int, int);
 
 extern void default_no_named_section (const char *, unsigned int, tree);
 extern void default_elf_asm_named_section (const char *, unsigned int, tree);
+extern enum section_category categorize_decl_for_section (tree, int, int);
 extern void default_coff_asm_named_section (const char *, unsigned int, tree);
 extern void default_pe_asm_named_section (const char *, unsigned int, tree);
 
index 88068b5205c21ab2839042aa04566da1ecce7551..6c5a5333024566f0de84d495e03b574211aedf3f 100644 (file)
@@ -5017,47 +5017,7 @@ default_select_section (tree decl, int reloc,
     data_section ();
 }
 
-/* A helper function for default_elf_select_section and
-   default_elf_unique_section.  Categorizes the DECL.  */
-
 enum section_category
-{
-  SECCAT_TEXT,
-
-  SECCAT_RODATA,
-  SECCAT_RODATA_MERGE_STR,
-  SECCAT_RODATA_MERGE_STR_INIT,
-  SECCAT_RODATA_MERGE_CONST,
-  SECCAT_SRODATA,
-
-  SECCAT_DATA,
-
-  /* To optimize loading of shared programs, define following subsections
-     of data section:
-       _REL    Contains data that has relocations, so they get grouped
-               together and dynamic linker will visit fewer pages in memory.
-       _RO     Contains data that is otherwise read-only.  This is useful
-               with prelinking as most relocations won't be dynamically
-               linked and thus stay read only.
-       _LOCAL  Marks data containing relocations only to local objects.
-               These relocations will get fully resolved by prelinking.  */
-  SECCAT_DATA_REL,
-  SECCAT_DATA_REL_LOCAL,
-  SECCAT_DATA_REL_RO,
-  SECCAT_DATA_REL_RO_LOCAL,
-
-  SECCAT_SDATA,
-  SECCAT_TDATA,
-
-  SECCAT_BSS,
-  SECCAT_SBSS,
-  SECCAT_TBSS
-};
-
-static enum section_category
-categorize_decl_for_section (tree, int, int);
-
-static enum section_category
 categorize_decl_for_section (tree decl, int reloc, int shlib)
 {
   enum section_category ret;
This page took 0.110652 seconds and 5 git commands to generate.