diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-07-31 09:12:34 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-07-31 09:12:34 +0000 |
commit | 43e4a084f6bba2151bbad13a71324ecf18957a10 (patch) | |
tree | 87b4af46aac16d4fea8bf9447284ab5f9c4ceba0 /gcc | |
parent | a74f1f7469830d0a6c3865a33ab0eab75737967a (diff) | |
download | gcc-43e4a084f6bba2151bbad13a71324ecf18957a10.tar.gz |
* 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
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@102606 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 32 | ||||
-rw-r--r-- | gcc/config/i386/i386-protos.h | 4 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 293 | ||||
-rw-r--r-- | gcc/config/i386/i386.h | 12 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 8 | ||||
-rw-r--r-- | gcc/config/i386/i386.opt | 4 | ||||
-rw-r--r-- | gcc/config/i386/predicates.md | 15 | ||||
-rw-r--r-- | gcc/config/i386/x86-64.h | 12 | ||||
-rw-r--r-- | gcc/doc/invoke.texi | 7 | ||||
-rw-r--r-- | gcc/output.h | 39 | ||||
-rw-r--r-- | gcc/varasm.c | 40 |
11 files changed, 410 insertions, 56 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a2c7bdc0272..967a610e24d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,37 @@ 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. (coalesce_vars): Likewise. * tree-ssa-live.c (coalesce_cost): New. diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index dfbf11ac256..94cecdc9ca2 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -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 *, diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index e9cf7db9f85..94648b1d38f 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -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; /* 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; } +/* 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); +} + 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 diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index e140bd291a2..d1f5dd95f56 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -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 diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 685c645af13..d533408b770 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -13788,6 +13788,14 @@ [(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)] "" diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt index effd1e16aa0..2a51fcbedbb 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -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 diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 292d46e52fe..f8ff8049d0f 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -110,7 +110,8 @@ /* 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. */ @@ -150,7 +151,9 @@ 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; @@ -224,7 +227,9 @@ /* 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. */ @@ -247,7 +252,9 @@ 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)) diff --git a/gcc/config/i386/x86-64.h b/gcc/config/i386/x86-64.h index c80353b0df1..b0e6947e863 100644 --- a/gcc/config/i386/x86-64.h +++ b/gcc/config/i386/x86-64.h @@ -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 diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 5004419a897..399083de5c1 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -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 diff --git a/gcc/output.h b/gcc/output.h index 221e4df1850..c0dfb5fd1c4 100644 --- a/gcc/output.h +++ b/gcc/output.h @@ -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); diff --git a/gcc/varasm.c b/gcc/varasm.c index 88068b5205c..6c5a5333024 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -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; |