This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Medium model support in GCC
Hi,
here is updated patch, tested on x86_64-linux with and without MEDIUM
being default. Sorry for the delays - there was power outage for the
machine I tested it on.
> > if (GET_CODE (disp) == SYMBOL_REF
> > ! && !SYMBOL_REF_FAR_ADDR_P (disp)
> > && SYMBOL_REF_LOCAL_P (disp))
>
> You made one change here ...
>
> > if (((GET_CODE (op0) == SYMBOL_REF
> > ! && (ix86_cmodel == CM_SMALL_PIC
> > ! || (ix86_cmodel == CM_MEDIUM_PIC
> > ! && !SYMBOL_REF_FAR_ADDR_P (op0)))
> > && SYMBOL_REF_LOCAL_P (op0))
>
> ... but not all instances. There are at least 3 more.
There are similar instances in predicates.md that are not quite same.
We test whteher the absolute address fits in and this is true only for
small/medium model, not for PIC models and for unsigned also not for
kernel model, so I kept the conditional in a way enumerating these 2/3
models as it seems cleaner than equivalent !SYMBOL_REF_FAR_ADDR_P (op0)
&& !flag_pic && ix86_model != CM_KERNEL especially when we will have to
exclude large model we will have to add shortly too. But I can use this
form or something else if it sounds better (this is still one test
shorter)
>
> > + mlarge-data-treshold=
>
> Misspelled "threshold", all instances.
Honza
* 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
* x86-64-medium-?.c: New.
Index: output.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/output.h,v
retrieving revision 1.159
diff -c -3 -p -r1.159 output.h
*** output.h 25 Jun 2005 02:00:41 -0000 1.159
--- output.h 24 Jul 2005 14:36:43 -0000
*************** extern void no_asm_to_stream (FILE *);
*** 500,505 ****
--- 500,543 ----
#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)
*************** extern unsigned int default_section_type
*** 510,515 ****
--- 548,554 ----
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: varasm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varasm.c,v
retrieving revision 1.522
diff -c -3 -p -r1.522 varasm.c
*** varasm.c 22 Jul 2005 17:40:29 -0000 1.522
--- varasm.c 24 Jul 2005 14:36:44 -0000
*************** default_select_section (tree decl, int r
*** 5012,5058 ****
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;
--- 5012,5018 ----
Index: config/i386/i386-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386-protos.h,v
retrieving revision 1.145
diff -c -3 -p -r1.145 i386-protos.h
*** config/i386/i386-protos.h 18 Jul 2005 06:39:18 -0000 1.145
--- config/i386/i386-protos.h 24 Jul 2005 14:36:45 -0000
*************** struct ix86_address
*** 259,264 ****
--- 259,268 ----
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: config/i386/i386.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.843
diff -c -3 -p -r1.843 i386.c
*** config/i386/i386.c 18 Jul 2005 06:39:18 -0000 1.843
--- config/i386/i386.c 24 Jul 2005 14:36:46 -0000
*************** unsigned int ix86_preferred_stack_bounda
*** 812,817 ****
--- 812,822 ----
/* 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;
*************** static const char * const x86_64_reg_cla
*** 945,950 ****
--- 950,961 ----
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
*************** static void init_ext_80387_constants (vo
*** 965,970 ****
--- 976,984 ----
#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
*************** override_options (void)
*** 1291,1304 ****
{
if (!strcmp (ix86_cmodel_string, "small"))
ix86_cmodel = flag_pic ? CM_SMALL_PIC : CM_SMALL;
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
--- 1305,1318 ----
{
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, "large") && !flag_pic)
ix86_cmodel = CM_LARGE;
else
*************** override_options (void)
*** 1502,1507 ****
--- 1516,1529 ----
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)
{
*************** override_options (void)
*** 1641,1646 ****
--- 1663,1837 ----
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)
{
*************** ix86_expand_prologue (void)
*** 4644,4650 ****
if (pic_reg_used)
{
! 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.
--- 4835,4844 ----
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));
/* Even with accurate pre-reload life analysis, we can wind up
deleting all references to the pic register after reload.
*************** legitimate_constant_p (rtx x)
*** 5173,5178 ****
--- 5367,5374 ----
if (GET_CODE (x) == UNSPEC)
switch (XINT (x, 1))
{
+ case UNSPEC_GOTOFF:
+ return true;
case UNSPEC_TPOFF:
case UNSPEC_NTPOFF:
return local_exec_symbolic_operand (XVECEXP (x, 0, 0), Pmode);
*************** legitimate_pic_operand_p (rtx x)
*** 5232,5242 ****
--- 5428,5443 ----
{
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 true;
case UNSPEC_TPOFF:
return local_exec_symbolic_operand (XVECEXP (inner, 0, 0), Pmode);
default:
*************** legitimate_pic_address_disp_p (rtx disp)
*** 5269,5275 ****
if (tls_symbolic_operand (disp, GET_MODE (disp)))
return 0;
if (GET_CODE (disp) == SYMBOL_REF
! && ix86_cmodel == CM_SMALL_PIC
&& SYMBOL_REF_LOCAL_P (disp))
return 1;
if (GET_CODE (disp) == LABEL_REF)
--- 5470,5476 ----
if (tls_symbolic_operand (disp, GET_MODE (disp)))
return 0;
if (GET_CODE (disp) == SYMBOL_REF
! && !SYMBOL_REF_FAR_ADDR_P (disp)
&& SYMBOL_REF_LOCAL_P (disp))
return 1;
if (GET_CODE (disp) == LABEL_REF)
*************** legitimate_pic_address_disp_p (rtx disp)
*** 5284,5290 ****
if (tls_symbolic_operand (op0, GET_MODE (op0)))
return 0;
if (((GET_CODE (op0) == SYMBOL_REF
! && ix86_cmodel == CM_SMALL_PIC
&& SYMBOL_REF_LOCAL_P (op0))
|| GET_CODE (op0) == LABEL_REF)
&& GET_CODE (op1) == CONST_INT
--- 5485,5491 ----
if (tls_symbolic_operand (op0, GET_MODE (op0)))
return 0;
if (((GET_CODE (op0) == SYMBOL_REF
! && !SYMBOL_REF_FAR_ADDR_P (op0)
&& SYMBOL_REF_LOCAL_P (op0))
|| GET_CODE (op0) == LABEL_REF)
&& GET_CODE (op1) == CONST_INT
*************** legitimate_pic_address_disp_p (rtx disp)
*** 5302,5308 ****
/* 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)
return 0;
if (GET_CODE (XVECEXP (disp, 0, 0)) != SYMBOL_REF
--- 5503,5510 ----
/* 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_GOTOFF))
return 0;
if (GET_CODE (XVECEXP (disp, 0, 0)) != SYMBOL_REF
*************** legitimize_pic_address (rtx orig, rtx re
*** 5632,5637 ****
--- 5834,5873 ----
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
*************** ix86_md_asm_clobbers (tree outputs ATTRI
*** 17545,17550 ****
--- 17781,17829 ----
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: config/i386/i386.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.h,v
retrieving revision 1.442
diff -c -3 -p -r1.442 i386.h
*** config/i386/i386.h 18 Jul 2005 06:39:19 -0000 1.442
--- config/i386/i386.h 24 Jul 2005 14:36:47 -0000
*************** do { \
*** 961,967 ****
#define REAL_PIC_OFFSET_TABLE_REGNUM 3
#define PIC_OFFSET_TABLE_REGNUM \
! (TARGET_64BIT || !flag_pic ? INVALID_REGNUM \
: reload_completed ? REGNO (pic_offset_table_rtx) \
: REAL_PIC_OFFSET_TABLE_REGNUM)
--- 961,968 ----
#define REAL_PIC_OFFSET_TABLE_REGNUM 3
#define PIC_OFFSET_TABLE_REGNUM \
! ((TARGET_64BIT && ix86_cmodel == CM_SMALL_PIC) \
! || !flag_pic ? INVALID_REGNUM \
: reload_completed ? REGNO (pic_offset_table_rtx) \
: REAL_PIC_OFFSET_TABLE_REGNUM)
*************** enum cmodel {
*** 2143,2149 ****
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. */
};
extern enum cmodel ix86_cmodel;
--- 2144,2151 ----
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_MEDIUM_PIC /* Assumes code+got/plt fits in a 31 bit region. */
};
extern enum cmodel ix86_cmodel;
*************** enum asm_dialect {
*** 2160,2166 ****
extern enum asm_dialect ix86_asm_dialect;
extern unsigned int ix86_preferred_stack_boundary;
! extern int ix86_branch_cost;
/* Smallest class containing REGNO. */
extern enum reg_class const regclass_map[FIRST_PSEUDO_REGISTER];
--- 2162,2168 ----
extern enum asm_dialect ix86_asm_dialect;
extern unsigned int ix86_preferred_stack_boundary;
! extern int ix86_branch_cost, ix86_section_threshold;
/* Smallest class containing REGNO. */
extern enum reg_class const regclass_map[FIRST_PSEUDO_REGISTER];
*************** struct machine_function GTY(())
*** 2281,2286 ****
--- 2283,2292 ----
#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: config/i386/i386.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.md,v
retrieving revision 1.650
diff -c -3 -p -r1.650 i386.md
*** config/i386/i386.md 21 Jul 2005 19:55:03 -0000 1.650
--- config/i386/i386.md 24 Jul 2005 14:36:48 -0000
***************
*** 13781,13793 ****
(define_insn "set_got"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
(clobber (reg:CC FLAGS_REG))]
"!TARGET_64BIT"
{ return output_set_got (operands[0]); }
[(set_attr "type" "multi")
(set_attr "length" "12")])
(define_expand "epilogue"
[(const_int 1)]
""
--- 13781,13800 ----
(define_insn "set_got"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
(clobber (reg:CC FLAGS_REG))]
"!TARGET_64BIT"
{ return output_set_got (operands[0]); }
[(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: config/i386/i386.opt
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.opt,v
retrieving revision 1.4
diff -c -3 -p -r1.4 i386.opt
*** config/i386/i386.opt 11 Jul 2005 09:35:16 -0000 1.4
--- config/i386/i386.opt 24 Jul 2005 14:36:48 -0000
*************** mbranch-cost=
*** 87,92 ****
--- 87,96 ----
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: config/i386/predicates.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/predicates.md,v
retrieving revision 1.19
diff -c -3 -p -r1.19 predicates.md
*** config/i386/predicates.md 25 Jun 2005 01:21:24 -0000 1.19
--- config/i386/predicates.md 24 Jul 2005 14:36:48 -0000
***************
*** 110,116 ****
/* TLS symbols are not constant. */
if (tls_symbolic_operand (op, Pmode))
return false;
! return (ix86_cmodel == CM_SMALL || ix86_cmodel == CM_KERNEL);
case LABEL_REF:
/* For certain code models, the code is near as well. */
--- 110,117 ----
/* TLS symbols are not constant. */
if (tls_symbolic_operand (op, Pmode))
return false;
! 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,156 ****
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
&& offset < 16*1024*1024
&& trunc_int_for_mode (offset, SImode) == offset)
return 1;
--- 151,159 ----
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
! || (ix86_cmodel == CM_MEDIUM
! && !SYMBOL_REF_FAR_ADDR_P (op1)))
&& offset < 16*1024*1024
&& trunc_int_for_mode (offset, SImode) == offset)
return 1;
***************
*** 224,230 ****
/* TLS symbols are not constant. */
if (tls_symbolic_operand (op, Pmode))
return false;
! return ix86_cmodel == CM_SMALL;
case LABEL_REF:
/* For certain code models, the code is near as well. */
--- 227,235 ----
/* TLS symbols are not constant. */
if (tls_symbolic_operand (op, Pmode))
return false;
! 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,253 ****
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
&& GET_CODE (op2) == CONST_INT
&& trunc_int_for_mode (INTVAL (op2), DImode) > -0x10000
&& trunc_int_for_mode (INTVAL (op2), SImode) == INTVAL (op2))
--- 252,260 ----
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
! || (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: config/i386/x86-64.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/x86-64.h,v
retrieving revision 1.13
diff -c -3 -p -r1.13 x86-64.h
*** config/i386/x86-64.h 25 Jun 2005 01:21:24 -0000 1.13
--- config/i386/x86-64.h 24 Jul 2005 14:36:48 -0000
*************** Boston, MA 02110-1301, USA. */
*** 52,58 ****
%{Wa,*:%*} %{m32:--32} %{m64:--64}"
#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
! asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)
/* This is used to align code labels according to Intel recommendations. */
--- 52,62 ----
%{Wa,*:%*} %{m32:--32} %{m64:--64}"
#define 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. */
*************** Boston, MA 02110-1301, USA. */
*** 75,77 ****
--- 79,87 ----
#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: doc/invoke.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/invoke.texi,v
retrieving revision 1.654
diff -c -3 -p -r1.654 invoke.texi
*** doc/invoke.texi 23 Jul 2005 08:36:41 -0000 1.654
--- doc/invoke.texi 24 Jul 2005 14:36:50 -0000
*************** Objective-C and Objective-C++ Dialects}.
*** 518,524 ****
-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}
@emph{IA-64 Options}
@gccoptlist{-mbig-endian -mlittle-endian -mgnu-as -mgnu-ld -mno-pic @gol
--- 518,524 ----
-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 -mlarge-data-threshold=@var{num}}
@emph{IA-64 Options}
@gccoptlist{-mbig-endian -mlittle-endian -mgnu-as -mgnu-ld -mno-pic @gol
*************** their size as well as function calling c
*** 9021,9026 ****
--- 9021,9031 ----
@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