diff options
author | rearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-07-23 13:19:49 +0000 |
---|---|---|
committer | rearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-07-23 13:19:49 +0000 |
commit | 55c1e470ac2b4e06e5ae02835c0aab4d2489b95d (patch) | |
tree | 19da1682a58ea729ccd498c477ae585bf6a6d7fe /gcc/config/arm | |
parent | 46146b305693904e5c231381872141c9f3a8bb8a (diff) | |
download | gcc-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.c | 43 | ||||
-rw-r--r-- | gcc/config/arm/arm.h | 29 | ||||
-rw-r--r-- | gcc/config/arm/arm.md | 8 | ||||
-rw-r--r-- | gcc/config/arm/elf.h | 3 |
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 |