summaryrefslogtreecommitdiff
path: root/gcc/config/arm
diff options
context:
space:
mode:
authorrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>1999-07-23 13:19:49 +0000
committerrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>1999-07-23 13:19:49 +0000
commit55c1e470ac2b4e06e5ae02835c0aab4d2489b95d (patch)
tree19da1682a58ea729ccd498c477ae585bf6a6d7fe /gcc/config/arm
parent46146b305693904e5c231381872141c9f3a8bb8a (diff)
downloadgcc-55c1e470ac2b4e06e5ae02835c0aab4d2489b95d.tar.gz
* config/arm/arm.h (TARGET_SWITCHES): Add
-m{no-}single-pic-base. Correct help string for -mshort-load-words. (TARGET_OPTIONS): Add -mpic-register=. (ARM_FLAG_SINGLE_PIC_BASE, TARGET_SINGLE_PIC_BASE): Define. (arm_pic_register_string): Declare. (NEED_PLT_GOT): Delete, replace with ... (NEED_GOT_RELOC, NEED_PLT_RELOC): ... these. New macros. (OUTPUT_INT_ADDR_CONST): Replace NEED_PLT_GOT with NEED_GOT_RELOC. (ASM_OUTPUT_MI_THUNK): Replace NEED_PLT_GOT with NEED_PLT_RELOC. * config/arm/arm.c (arm_override_options): Add new option -mpic-register=N. (arm_pic_register_string): New variable. (arm_finalize_pic): Respect TARGET_SINGLE_PIC_BASE. (output_func_prologue): If TARGET_SINGLE_PIC_BASE, treat the PIC register as never live. Use NEED_PLT_RELOC not NEED_PLT_GOT. (output_return_instruction): Likewise. * config/arm/elf.h (NEED_PLT_GOT): Delete, replace with ... (NEED_GOT_RELOC, NEED_PLT_RELOC): ... these. Define to flag_pic. * config/arm/arm.md: Use NEED_PLT_RELOC in place of NEED_PLT_GOT. * invoke.texi (ARM Options): Fix spelling. Remove duplicate mention of -msched-prolog. Document new options -msingle-pic-base and -mpic-register=. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@28227 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/arm')
-rw-r--r--gcc/config/arm/arm.c43
-rw-r--r--gcc/config/arm/arm.h29
-rw-r--r--gcc/config/arm/arm.md8
-rw-r--r--gcc/config/arm/elf.h3
4 files changed, 63 insertions, 20 deletions
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 2f1e7d9a1df..f970becbaae 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -142,6 +142,7 @@ enum machine_mode output_memory_reference_mode;
int current_function_anonymous_args;
/* The register number to be used for the PIC offset register. */
+const char * arm_pic_register_string = NULL;
int arm_pic_register = 9;
/* Set to one if we think that lr is only saved because of subroutine calls,
@@ -528,7 +529,8 @@ arm_override_options ()
/* For arm2/3 there is no need to do any scheduling if there is only
a floating point emulator, or we are doing software floating-point. */
- if ((TARGET_SOFT_FLOAT || arm_fpu != FP_HARD) && (tune_flags & FL_MODE32) == 0)
+ if ((TARGET_SOFT_FLOAT || arm_fpu != FP_HARD)
+ && (tune_flags & FL_MODE32) == 0)
flag_schedule_insns = flag_schedule_insns_after_reload = 0;
arm_prog_mode = TARGET_APCS_32 ? PROG_MODE_PROG32 : PROG_MODE_PROG26;
@@ -542,6 +544,25 @@ arm_override_options ()
else
warning ("Structure size boundary can only be set to 8 or 32");
}
+
+ if (arm_pic_register_string != NULL)
+ {
+ int pic_register;
+
+ if (! flag_pic)
+ warning ("-mpic-register= is useless without -fpic");
+
+ pic_register = decode_reg_name (arm_pic_register_string);
+
+ /* Prevent the user from choosing an obviously stupid PIC register. */
+ if (pic_register < 0 || call_used_regs[pic_register]
+ || pic_register == HARD_FRAME_POINTER_REGNUM
+ || pic_register == STACK_POINTER_REGNUM
+ || pic_register >= PC_REGNUM)
+ error ("Unable to use '%s' for PIC register", arm_pic_register_string);
+ else
+ arm_pic_register = pic_register;
+ }
/* If optimizing for space, don't synthesize constants.
For processors with load scheduling, it never costs more than 2 cycles
@@ -1556,7 +1577,7 @@ arm_finalize_pic ()
rtx l1, pic_tmp, pic_tmp2, seq;
rtx global_offset_table;
- if (current_function_uses_pic_offset_table == 0)
+ if (current_function_uses_pic_offset_table == 0 || TARGET_SINGLE_PIC_BASE)
return;
if (! flag_pic)
@@ -5353,7 +5374,7 @@ output_return_instruction (operand, really_return, reverse)
/* Otherwise, trap an attempted return by aborting. */
ops[0] = operand;
- ops[1] = gen_rtx_SYMBOL_REF (Pmode, NEED_PLT_GOT ? "abort(PLT)"
+ ops[1] = gen_rtx_SYMBOL_REF (Pmode, NEED_PLT_RELOC ? "abort(PLT)"
: "abort");
assemble_external_libcall (ops[1]);
output_asm_insn (reverse ? "bl%D0\t%a1" : "bl%d0\t%a1", ops);
@@ -5367,7 +5388,8 @@ output_return_instruction (operand, really_return, reverse)
if (regs_ever_live[reg] && ! call_used_regs[reg])
live_regs++;
- if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
+ if (flag_pic && ! TARGET_SINGLE_PIC_BASE
+ && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
live_regs++;
if (live_regs || (regs_ever_live[LR_REGNUM] && ! lr_save_eliminated))
@@ -5391,7 +5413,8 @@ output_return_instruction (operand, really_return, reverse)
for (reg = 0; reg <= 10; reg++)
if (regs_ever_live[reg]
&& (! call_used_regs[reg]
- || (flag_pic && reg == PIC_OFFSET_TABLE_REGNUM)))
+ || (flag_pic && ! TARGET_SINGLE_PIC_BASE
+ && reg == PIC_OFFSET_TABLE_REGNUM)))
{
strcat (instr, "%|");
strcat (instr, reg_names[reg]);
@@ -5551,7 +5574,8 @@ output_func_prologue (f, frame_size)
if (regs_ever_live[reg] && ! call_used_regs[reg])
live_regs_mask |= (1 << reg);
- if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
+ if (flag_pic && ! TARGET_SINGLE_PIC_BASE
+ && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
live_regs_mask |= (1 << PIC_OFFSET_TABLE_REGNUM);
if (frame_pointer_needed)
@@ -5617,7 +5641,7 @@ output_func_epilogue (f, frame_size)
if (TARGET_ABORT_NORETURN && volatile_func)
{
rtx op;
- op = gen_rtx_SYMBOL_REF (Pmode, NEED_PLT_GOT ? "abort(PLT)" : "abort");
+ op = gen_rtx_SYMBOL_REF (Pmode, NEED_PLT_RELOC ? "abort(PLT)" : "abort");
assemble_external_libcall (op);
output_asm_insn ("bl\t%a0", &op);
goto epilogue_done;
@@ -5630,7 +5654,10 @@ output_func_epilogue (f, frame_size)
floats_offset += 4;
}
- if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
+ /* If we aren't loading the PIC register, don't stack it even though it may
+ be live. */
+ if (flag_pic && ! TARGET_SINGLE_PIC_BASE
+ && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
{
live_regs_mask |= (1 << PIC_OFFSET_TABLE_REGNUM);
floats_offset += 4;
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index bf44db36c0e..5b43259aad2 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -319,6 +319,9 @@ Unrecognized value in TARGET_CPU_DEFAULT.
function tries to return. */
#define ARM_FLAG_ABORT_NORETURN (1 << 13)
+/* Nonzero if function prologues should not load the PIC register. */
+#define ARM_FLAG_SINGLE_PIC_BASE (1 << 14)
+
#define TARGET_APCS (target_flags & ARM_FLAG_APCS_FRAME)
#define TARGET_POKE_FUNCTION_NAME (target_flags & ARM_FLAG_POKE)
#define TARGET_FPE (target_flags & ARM_FLAG_FPE)
@@ -341,6 +344,7 @@ function tries to return. */
#define TARGET_LITTLE_WORDS (target_flags & ARM_FLAG_LITTLE_WORDS)
#define TARGET_NO_SCHED_PRO (target_flags & ARM_FLAG_NO_SCHED_PRO)
#define TARGET_ABORT_NORETURN (target_flags & ARM_FLAG_ABORT_NORETURN)
+#define TARGET_SINGLE_PIC_BASE (target_flags & ARM_FLAG_SINGLE_PIC_BASE)
/* SUBTARGET_SWITCHES is used to add flags on a per-config basis.
Bit 31 is reserved. See riscix.h. */
@@ -374,7 +378,7 @@ function tries to return. */
"Load shorts a byte at a time" }, \
{"no-short-load-bytes", -ARM_FLAG_SHORT_BYTE, "" }, \
{"short-load-words", -ARM_FLAG_SHORT_BYTE, \
- "Load words a byte at a time" }, \
+ "Load shorts a word at a time" }, \
{"no-short-load-words", ARM_FLAG_SHORT_BYTE, "" }, \
{"soft-float", ARM_FLAG_SOFT_FLOAT, \
"Use library calls to perform FP operations" }, \
@@ -395,6 +399,9 @@ function tries to return. */
{"sched-prolog", -ARM_FLAG_NO_SCHED_PRO, \
"Do not move instructions into a function's prologue" }, \
{"no-sched-prolog", ARM_FLAG_NO_SCHED_PRO, "" }, \
+ {"single-pic-base", ARM_FLAG_SINGLE_PIC_BASE, \
+ "Do not load the PIC register in function prologues" }, \
+ {"no-single-pic-base", -ARM_FLAG_SINGLE_PIC_BASE, "" },\
SUBTARGET_SWITCHES \
{"", TARGET_DEFAULT } \
}
@@ -410,7 +417,9 @@ function tries to return. */
{"fp=", & target_fp_name, \
"Specify the version of the floating point emulator" }, \
{ "structure-size-boundary=", & structure_size_string, \
- "Specify the minumum bit alignment of structures" } \
+ "Specify the minumum bit alignment of structures" }, \
+ { "pic-register=", & arm_pic_register_string, \
+ "Specify the register to be used for PIC addressing" } \
}
struct arm_cpu_select
@@ -492,9 +501,12 @@ extern int arm_is_6_or_7;
/* Nonzero if PIC code requires explicit qualifiers to generate
PLT and GOT relocs rather than the assembler doing so implicitly.
- Subtargets can override this if required. */
-#ifndef NEED_PLT_GOT
-#define NEED_PLT_GOT 0
+ Subtargets can override these if required. */
+#ifndef NEED_GOT_RELOC
+#define NEED_GOT_RELOC 0
+#endif
+#ifndef NEED_PLT_RELOC
+#define NEED_PLT_RELOC 0
#endif
/* Nonzero if we need to refer to the GOT with a PC-relative
@@ -1842,6 +1854,9 @@ enum reg_class
using sb (r9) all the time. */
extern int arm_pic_register;
+/* Used when parsing command line option -mpic-register=. */
+extern const char * arm_pic_register_string;
+
/* The register number of the register used to address a table of static
data addresses in memory. */
#define PIC_OFFSET_TABLE_REGNUM arm_pic_register
@@ -2102,7 +2117,7 @@ extern struct rtx_def * arm_compare_op1;
\
/* Mark symbols as position independent. We only do this in the \
.text segment, not in the .data segment. */ \
- if (NEED_PLT_GOT && flag_pic && making_const_table && \
+ if (NEED_GOT_RELOC && flag_pic && making_const_table && \
(GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == LABEL_REF)) \
{ \
if (GET_CODE (X) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (X)) \
@@ -2141,7 +2156,7 @@ extern struct rtx_def * arm_compare_op1;
} \
fputs ("\tb\t", FILE); \
assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0)); \
- if (NEED_PLT_GOT) \
+ if (NEED_PLT_RELOC) \
fputs ("(PLT)", FILE); \
fputc ('\n', FILE); \
} \
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 599621da0be..3abd60c2a85 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -4248,7 +4248,7 @@
"GET_CODE (operands[0]) == SYMBOL_REF"
"*
{
- return NEED_PLT_GOT ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
+ return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
}"
[(set_attr "type" "call")])
@@ -4260,7 +4260,7 @@
"GET_CODE(operands[1]) == SYMBOL_REF"
"*
{
- return NEED_PLT_GOT ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
+ return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
}"
[(set_attr "type" "call")])
@@ -5991,7 +5991,7 @@
}
output_return_instruction (NULL, FALSE, FALSE);
- return NEED_PLT_GOT ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
+ return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
}"
[(set_attr "type" "call")
(set_attr "length" "8")])
@@ -6019,7 +6019,7 @@
}
output_return_instruction (NULL, FALSE, FALSE);
- return NEED_PLT_GOT ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
+ return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
}"
[(set_attr "type" "call")
(set_attr "length" "8")])
diff --git a/gcc/config/arm/elf.h b/gcc/config/arm/elf.h
index 37645355235..3b71229de74 100644
--- a/gcc/config/arm/elf.h
+++ b/gcc/config/arm/elf.h
@@ -354,7 +354,8 @@ dtors_section () \
while (0)
/* For PIC code we need to explicitly specify (PLT) and (GOT) relocs. */
-#define NEED_PLT_GOT flag_pic
+#define NEED_PLT_RELOC flag_pic
+#define NEED_GOT_RELOC flag_pic
/* The ELF assembler handles GOT addressing differently to NetBSD. */
#define GOT_PCREL 0