Commit 7dcbf659 by Jan Hubicka Committed by Jan Hubicka

output.h (enum section_category): Export from varasm.c


	* 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
parent 3601aa8a
2005-07-31 Jan Hubicka <jh@suse.cz> 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. * tree-outof-ssa.c (coalesce_ssa_name): Use coalesce_cost.
(coalesce_vars): Likewise. (coalesce_vars): Likewise.
* tree-ssa-live.c (coalesce_cost): New. * tree-ssa-live.c (coalesce_cost): New.
......
...@@ -259,6 +259,10 @@ struct ix86_address ...@@ -259,6 +259,10 @@ struct ix86_address
extern int ix86_decompose_address (rtx, struct ix86_address *); extern int ix86_decompose_address (rtx, struct ix86_address *);
extern int memory_address_length (rtx addr); 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 #ifdef RTX_CODE
extern void ix86_fp_comparison_codes (enum rtx_code code, enum rtx_code *, extern void ix86_fp_comparison_codes (enum rtx_code code, enum rtx_code *,
......
...@@ -812,6 +812,11 @@ unsigned int ix86_preferred_stack_boundary; ...@@ -812,6 +812,11 @@ unsigned int ix86_preferred_stack_boundary;
/* Values 1-5: see jump.c */ /* Values 1-5: see jump.c */
int ix86_branch_cost; 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. */ /* Prefix built by ASM_GENERATE_INTERNAL_LABEL. */
char internal_label_prefix[16]; char internal_label_prefix[16];
int internal_label_prefix_len; int internal_label_prefix_len;
...@@ -945,6 +950,12 @@ static const char * const x86_64_reg_class_name[] = { ...@@ -945,6 +950,12 @@ static const char * const x86_64_reg_class_name[] = {
static REAL_VALUE_TYPE ext_80387_constants_table [5]; static REAL_VALUE_TYPE ext_80387_constants_table [5];
static bool ext_80387_constants_init = 0; static bool ext_80387_constants_init = 0;
static void init_ext_80387_constants (void); 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. */ /* Initialize the GCC target structure. */
#undef TARGET_ATTRIBUTE_TABLE #undef TARGET_ATTRIBUTE_TABLE
...@@ -965,6 +976,9 @@ static void init_ext_80387_constants (void); ...@@ -965,6 +976,9 @@ static void init_ext_80387_constants (void);
#undef TARGET_ASM_FUNCTION_EPILOGUE #undef TARGET_ASM_FUNCTION_EPILOGUE
#define TARGET_ASM_FUNCTION_EPILOGUE ix86_output_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 #undef TARGET_ASM_OPEN_PAREN
#define TARGET_ASM_OPEN_PAREN "" #define TARGET_ASM_OPEN_PAREN ""
#undef TARGET_ASM_CLOSE_PAREN #undef TARGET_ASM_CLOSE_PAREN
...@@ -1291,14 +1305,14 @@ override_options (void) ...@@ -1291,14 +1305,14 @@ override_options (void)
{ {
if (!strcmp (ix86_cmodel_string, "small")) if (!strcmp (ix86_cmodel_string, "small"))
ix86_cmodel = flag_pic ? CM_SMALL_PIC : CM_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) else if (flag_pic)
sorry ("code model %s not supported in PIC mode", ix86_cmodel_string); sorry ("code model %s not supported in PIC mode", ix86_cmodel_string);
else if (!strcmp (ix86_cmodel_string, "32")) else if (!strcmp (ix86_cmodel_string, "32"))
ix86_cmodel = CM_32; ix86_cmodel = CM_32;
else if (!strcmp (ix86_cmodel_string, "kernel") && !flag_pic) else if (!strcmp (ix86_cmodel_string, "kernel") && !flag_pic)
ix86_cmodel = CM_KERNEL; 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) else if (!strcmp (ix86_cmodel_string, "large") && !flag_pic)
ix86_cmodel = CM_LARGE; ix86_cmodel = CM_LARGE;
else else
...@@ -1502,6 +1516,14 @@ override_options (void) ...@@ -1502,6 +1516,14 @@ override_options (void)
else else
ix86_branch_cost = i; 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) if (ix86_tls_dialect_string)
{ {
...@@ -1641,6 +1663,175 @@ override_options (void) ...@@ -1641,6 +1663,175 @@ override_options (void)
flag_schedule_insns_after_reload = flag_schedule_insns = 0; 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 void
optimization_options (int level, int size ATTRIBUTE_UNUSED) optimization_options (int level, int size ATTRIBUTE_UNUSED)
{ {
...@@ -4644,6 +4835,9 @@ ix86_expand_prologue (void) ...@@ -4644,6 +4835,9 @@ ix86_expand_prologue (void)
if (pic_reg_used) if (pic_reg_used)
{ {
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)); insn = emit_insn (gen_set_got (pic_offset_table_rtx));
/* Even with accurate pre-reload life analysis, we can wind up /* Even with accurate pre-reload life analysis, we can wind up
...@@ -5173,6 +5367,8 @@ legitimate_constant_p (rtx x) ...@@ -5173,6 +5367,8 @@ legitimate_constant_p (rtx x)
if (GET_CODE (x) == UNSPEC) if (GET_CODE (x) == UNSPEC)
switch (XINT (x, 1)) switch (XINT (x, 1))
{ {
case UNSPEC_GOTOFF:
return TARGET_64BIT;
case UNSPEC_TPOFF: case UNSPEC_TPOFF:
case UNSPEC_NTPOFF: case UNSPEC_NTPOFF:
return local_exec_symbolic_operand (XVECEXP (x, 0, 0), Pmode); return local_exec_symbolic_operand (XVECEXP (x, 0, 0), Pmode);
...@@ -5232,11 +5428,16 @@ legitimate_pic_operand_p (rtx x) ...@@ -5232,11 +5428,16 @@ legitimate_pic_operand_p (rtx x)
{ {
case CONST: case CONST:
inner = XEXP (x, 0); 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". */ /* Only some unspecs are valid as "constants". */
if (GET_CODE (inner) == UNSPEC) if (GET_CODE (inner) == UNSPEC)
switch (XINT (inner, 1)) switch (XINT (inner, 1))
{ {
case UNSPEC_GOTOFF:
return TARGET_64BIT;
case UNSPEC_TPOFF: case UNSPEC_TPOFF:
return local_exec_symbolic_operand (XVECEXP (inner, 0, 0), Pmode); return local_exec_symbolic_operand (XVECEXP (inner, 0, 0), Pmode);
default: default:
...@@ -5269,7 +5470,7 @@ legitimate_pic_address_disp_p (rtx disp) ...@@ -5269,7 +5470,7 @@ legitimate_pic_address_disp_p (rtx disp)
if (tls_symbolic_operand (disp, GET_MODE (disp))) if (tls_symbolic_operand (disp, GET_MODE (disp)))
return 0; return 0;
if (GET_CODE (disp) == SYMBOL_REF if (GET_CODE (disp) == SYMBOL_REF
&& ix86_cmodel == CM_SMALL_PIC && !SYMBOL_REF_FAR_ADDR_P (disp)
&& SYMBOL_REF_LOCAL_P (disp)) && SYMBOL_REF_LOCAL_P (disp))
return 1; return 1;
if (GET_CODE (disp) == LABEL_REF) if (GET_CODE (disp) == LABEL_REF)
...@@ -5284,7 +5485,7 @@ legitimate_pic_address_disp_p (rtx disp) ...@@ -5284,7 +5485,7 @@ legitimate_pic_address_disp_p (rtx disp)
if (tls_symbolic_operand (op0, GET_MODE (op0))) if (tls_symbolic_operand (op0, GET_MODE (op0)))
return 0; return 0;
if (((GET_CODE (op0) == SYMBOL_REF if (((GET_CODE (op0) == SYMBOL_REF
&& ix86_cmodel == CM_SMALL_PIC && !SYMBOL_REF_FAR_ADDR_P (op0)
&& SYMBOL_REF_LOCAL_P (op0)) && SYMBOL_REF_LOCAL_P (op0))
|| GET_CODE (op0) == LABEL_REF) || GET_CODE (op0) == LABEL_REF)
&& GET_CODE (op1) == CONST_INT && GET_CODE (op1) == CONST_INT
...@@ -5302,7 +5503,8 @@ legitimate_pic_address_disp_p (rtx disp) ...@@ -5302,7 +5503,8 @@ legitimate_pic_address_disp_p (rtx disp)
/* We are unsafe to allow PLUS expressions. This limit allowed distance /* We are unsafe to allow PLUS expressions. This limit allowed distance
of GOT tables. We should not need these anyway. */ of GOT tables. We should not need these anyway. */
if (GET_CODE (disp) != UNSPEC if (GET_CODE (disp) != UNSPEC
|| XINT (disp, 1) != UNSPEC_GOTPCREL) || (XINT (disp, 1) != UNSPEC_GOTPCREL
&& XINT (disp, 1) != UNSPEC_GOTOFF))
return 0; return 0;
if (GET_CODE (XVECEXP (disp, 0, 0)) != SYMBOL_REF if (GET_CODE (XVECEXP (disp, 0, 0)) != SYMBOL_REF
...@@ -5632,6 +5834,40 @@ legitimize_pic_address (rtx orig, rtx reg) ...@@ -5632,6 +5834,40 @@ legitimize_pic_address (rtx orig, rtx reg)
if (TARGET_64BIT && legitimate_pic_address_disp_p (addr)) if (TARGET_64BIT && legitimate_pic_address_disp_p (addr))
new = 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)) else if (!TARGET_64BIT && local_symbolic_operand (addr, Pmode))
{ {
/* This symbol may be referenced via a displacement from the PIC /* This symbol may be referenced via a displacement from the PIC
...@@ -17525,6 +17761,49 @@ ix86_md_asm_clobbers (tree outputs ATTRIBUTE_UNUSED, ...@@ -17525,6 +17761,49 @@ ix86_md_asm_clobbers (tree outputs ATTRIBUTE_UNUSED,
return clobbers; 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. */ /* Worker function for REVERSE_CONDITION. */
enum rtx_code enum rtx_code
......
...@@ -961,7 +961,8 @@ do { \ ...@@ -961,7 +961,8 @@ do { \
#define REAL_PIC_OFFSET_TABLE_REGNUM 3 #define REAL_PIC_OFFSET_TABLE_REGNUM 3
#define PIC_OFFSET_TABLE_REGNUM \ #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) \ : reload_completed ? REGNO (pic_offset_table_rtx) \
: REAL_PIC_OFFSET_TABLE_REGNUM) : REAL_PIC_OFFSET_TABLE_REGNUM)
...@@ -2143,7 +2144,8 @@ enum cmodel { ...@@ -2143,7 +2144,8 @@ enum cmodel {
CM_KERNEL, /* Assumes all code and data fits in the high 31 bits. */ 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_MEDIUM, /* Assumes code fits in the low 31 bits; data unlimited. */
CM_LARGE, /* No assumptions. */ 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; extern enum cmodel ix86_cmodel;
...@@ -2160,7 +2162,7 @@ enum asm_dialect { ...@@ -2160,7 +2162,7 @@ enum asm_dialect {
extern enum asm_dialect ix86_asm_dialect; extern enum asm_dialect ix86_asm_dialect;
extern unsigned int ix86_preferred_stack_boundary; extern unsigned int ix86_preferred_stack_boundary;
extern int ix86_branch_cost; extern int ix86_branch_cost, ix86_section_threshold;
/* Smallest class containing REGNO. */ /* Smallest class containing REGNO. */
extern enum reg_class const regclass_map[FIRST_PSEUDO_REGISTER]; extern enum reg_class const regclass_map[FIRST_PSEUDO_REGISTER];
...@@ -2281,6 +2283,10 @@ struct machine_function GTY(()) ...@@ -2281,6 +2283,10 @@ struct machine_function GTY(())
#define X86_FILE_START_VERSION_DIRECTIVE false #define X86_FILE_START_VERSION_DIRECTIVE false
#define X86_FILE_START_FLTUSED 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: Local variables:
version-control: t version-control: t
......
...@@ -13788,6 +13788,14 @@ ...@@ -13788,6 +13788,14 @@
[(set_attr "type" "multi") [(set_attr "type" "multi")
(set_attr "length" "12")]) (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" (define_expand "epilogue"
[(const_int 1)] [(const_int 1)]
"" ""
......
...@@ -87,6 +87,10 @@ mbranch-cost= ...@@ -87,6 +87,10 @@ mbranch-cost=
Target RejectNegative Joined Var(ix86_branch_cost_string) Target RejectNegative Joined Var(ix86_branch_cost_string)
Branches are this expensive (1-5, arbitrary units) 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= mcmodel=
Target RejectNegative Joined Var(ix86_cmodel_string) Target RejectNegative Joined Var(ix86_cmodel_string)
Use given x86-64 code model Use given x86-64 code model
......
...@@ -110,7 +110,8 @@ ...@@ -110,7 +110,8 @@
/* TLS symbols are not constant. */ /* TLS symbols are not constant. */
if (tls_symbolic_operand (op, Pmode)) if (tls_symbolic_operand (op, Pmode))
return false; 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: case LABEL_REF:
/* For certain code models, the code is near as well. */ /* For certain code models, the code is near as well. */
...@@ -150,7 +151,9 @@ ...@@ -150,7 +151,9 @@
end of 31bits boundary. We may also accept pretty end of 31bits boundary. We may also accept pretty
large negative constants knowing that all objects are large negative constants knowing that all objects are
in the positive half of address space. */ 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 && offset < 16*1024*1024
&& trunc_int_for_mode (offset, SImode) == offset) && trunc_int_for_mode (offset, SImode) == offset)
return 1; return 1;
...@@ -224,7 +227,9 @@ ...@@ -224,7 +227,9 @@
/* TLS symbols are not constant. */ /* TLS symbols are not constant. */
if (tls_symbolic_operand (op, Pmode)) if (tls_symbolic_operand (op, Pmode))
return false; 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: case LABEL_REF:
/* For certain code models, the code is near as well. */ /* For certain code models, the code is near as well. */
...@@ -247,7 +252,9 @@ ...@@ -247,7 +252,9 @@
offsets, since one bit is available for free. Negative offsets, since one bit is available for free. Negative
offsets are limited by the size of NULL pointer area offsets are limited by the size of NULL pointer area
specified by the ABI. */ 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 && GET_CODE (op2) == CONST_INT
&& trunc_int_for_mode (INTVAL (op2), DImode) > -0x10000 && trunc_int_for_mode (INTVAL (op2), DImode) > -0x10000
&& trunc_int_for_mode (INTVAL (op2), SImode) == INTVAL (op2)) && trunc_int_for_mode (INTVAL (op2), SImode) == INTVAL (op2))
......
...@@ -52,7 +52,11 @@ Boston, MA 02110-1301, USA. */ ...@@ -52,7 +52,11 @@ Boston, MA 02110-1301, USA. */
%{Wa,*:%*} %{m32:--32} %{m64:--64}" %{Wa,*:%*} %{m32:--32} %{m64:--64}"
#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \ #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. */ /* This is used to align code labels according to Intel recommendations. */
...@@ -75,3 +79,9 @@ Boston, MA 02110-1301, USA. */ ...@@ -75,3 +79,9 @@ Boston, MA 02110-1301, USA. */
#undef PREFERRED_DEBUGGING_TYPE #undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG #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
...@@ -521,7 +521,7 @@ Objective-C and Objective-C++ Dialects}. ...@@ -521,7 +521,7 @@ Objective-C and Objective-C++ Dialects}.
-m96bit-long-double -mregparm=@var{num} -msseregparm @gol -m96bit-long-double -mregparm=@var{num} -msseregparm @gol
-momit-leaf-frame-pointer -mno-red-zone -mno-tls-direct-seg-refs @gol -momit-leaf-frame-pointer -mno-red-zone -mno-tls-direct-seg-refs @gol
-mcmodel=@var{code-model} @gol -mcmodel=@var{code-model} @gol
-m32 -m64} -m32 -m64 -mlarge-data-threshold=@var{num}}
@emph{IA-64 Options} @emph{IA-64 Options}
@gccoptlist{-mbig-endian -mlittle-endian -mgnu-as -mgnu-ld -mno-pic @gol @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 ...@@ -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 @code{long double} will be modified. Hence they will not be binary
compatible with arrays or structures in code compiled without that switch. 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 @item -msvr3-shlib
@itemx -mno-svr3-shlib @itemx -mno-svr3-shlib
......
...@@ -500,6 +500,44 @@ extern void no_asm_to_stream (FILE *); ...@@ -500,6 +500,44 @@ extern void no_asm_to_stream (FILE *);
#define SECTION_NOTYPE 0x80000 /* don't output @progbits */ #define SECTION_NOTYPE 0x80000 /* don't output @progbits */
#define SECTION_MACH_DEP 0x100000 /* subsequent bits reserved for target */ #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); extern bool set_named_section_flags (const char *, unsigned int);
#define named_section_flags(NAME, FLAGS) \ #define named_section_flags(NAME, FLAGS) \
named_section_real((NAME), (FLAGS), /*decl=*/NULL_TREE) 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); ...@@ -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_no_named_section (const char *, unsigned int, tree);
extern void default_elf_asm_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_coff_asm_named_section (const char *, unsigned int, tree);
extern void default_pe_asm_named_section (const char *, unsigned int, tree); extern void default_pe_asm_named_section (const char *, unsigned int, tree);
......
...@@ -5017,47 +5017,7 @@ default_select_section (tree decl, int reloc, ...@@ -5017,47 +5017,7 @@ default_select_section (tree decl, int reloc,
data_section (); data_section ();
} }
/* A helper function for default_elf_select_section and
default_elf_unique_section. Categorizes the DECL. */
enum section_category 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) categorize_decl_for_section (tree decl, int reloc, int shlib)
{ {
enum section_category ret; enum section_category ret;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment