t-elf, [...]: New files.
* config/sh/t-elf, config/sh/crt1.asm, config/sh/crti.asm, config/sh/crtn.asm: New files. * config/sh/t-sh (EXTRA_MULTILIB_PARTS): Set. (crt1.o, crti.o, crtn.o): New targets. * configure.in [sh-*-elf*, sh-*-rtemself*] (tmake_file): Added sh/t-elf. * configure: Rebuilt. * config/sh/sh.h (INIT_SECTION_ASM_OP, FINI_SECTION_ASM_OP, STARTFILE_SPEC, ENDFILE_SPEC, CRT_CALL_STATIC_FUNCTION): Define. * config/sh/elf.h (INIT_SECTION_ASM_OP, FINI_SECTION_ASM_OP): Undefine for config/elfos.h to redefine. (STARTFILE_SPEC, ENDFILE_SPEC): Redefine after config/elfos.h. * config/sh/sh-protos.h (nonpic_symbol_mentioned_p, legitimize_pic_address, output_pic_addr_const): Declare. * config/sh/sh.h (CONDITIONAL_REGISTER_USAGE): Fix PIC register. (PREFERGOT_BIT, TARGET_PREFERGOT): Likewise. (TARGET_SWITCHES): New switch -mprefergot. (OVERRIDE_OPTIONS): Set flag_no_function_cse unless -mprefergot. (PIC_OFFSET_TABLE_REGNUM): Define. (GOT_SYMBOL_TABLE): Likewise. (LEGITIMIZE_ADDRESS): Use legitimize_pic_address. (ENCODE_SECTION_INFO): Define. (FINALIZE_PIC): New macros. (LEGITIMATE_PIC_OPERAND_P, SYMBOLIC_CONST_P): New macro. (ASM_OUTPUT_INT, ASM_OUTPUT_SHORT): Use output_pic_addr_const. * config/sh/sh.c (print_operand_address): Use output_pic_addr_const. (prepare_move_operands): Call emit_pic_move or emit_pic_const_move if appropriate. (output_far_jump): For PIC, use braf and output long offset. (machine_dependent_reorg): (sh_expand_prologue): Save and initialize the PIC register. (sh_expand_epilogue): Restore it. (initial_elimination_offset): Account for it. (nonpic_symbol_mentioned_p): New function. (legitimize_pic_address): Likewise. (output_pic_addr_const): Likewise. * config/sh/sh.md (calli_pcrel, call_valuei_pcrel): New insns. (call, call_value): Use them. (GOTaddr2picreg, sym_label2reg, symGOT2reg, symGOTOFF2reg, symPLT_label2reg): New expands. * invoke.texi (SH Options): Document -mprefergot. From-SVN: r36111
This commit is contained in:
parent
6462bb432f
commit
1a66cd67e2
@ -1,3 +1,50 @@
|
||||
2000-09-02 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
* config/sh/t-elf, config/sh/crt1.asm, config/sh/crti.asm,
|
||||
config/sh/crtn.asm: New files.
|
||||
* config/sh/t-sh (EXTRA_MULTILIB_PARTS): Set.
|
||||
(crt1.o, crti.o, crtn.o): New targets.
|
||||
* configure.in [sh-*-elf*, sh-*-rtemself*] (tmake_file): Added
|
||||
sh/t-elf.
|
||||
* configure: Rebuilt.
|
||||
* config/sh/sh.h (INIT_SECTION_ASM_OP, FINI_SECTION_ASM_OP,
|
||||
STARTFILE_SPEC, ENDFILE_SPEC, CRT_CALL_STATIC_FUNCTION): Define.
|
||||
* config/sh/elf.h (INIT_SECTION_ASM_OP, FINI_SECTION_ASM_OP):
|
||||
Undefine for config/elfos.h to redefine.
|
||||
(STARTFILE_SPEC, ENDFILE_SPEC): Redefine after config/elfos.h.
|
||||
|
||||
2000-09-02 Alexandre Oliva <aoliva@redhat.com>, Niibe Yutaka <gniibe@m17n.org>, Kaz Kojima <kkojima@rr.iij4u.or.jp>
|
||||
|
||||
* config/sh/sh-protos.h (nonpic_symbol_mentioned_p,
|
||||
legitimize_pic_address, output_pic_addr_const): Declare.
|
||||
* config/sh/sh.h (CONDITIONAL_REGISTER_USAGE): Fix PIC register.
|
||||
(PREFERGOT_BIT, TARGET_PREFERGOT): Likewise.
|
||||
(TARGET_SWITCHES): New switch -mprefergot.
|
||||
(OVERRIDE_OPTIONS): Set flag_no_function_cse unless -mprefergot.
|
||||
(PIC_OFFSET_TABLE_REGNUM): Define.
|
||||
(GOT_SYMBOL_TABLE): Likewise.
|
||||
(LEGITIMIZE_ADDRESS): Use legitimize_pic_address.
|
||||
(ENCODE_SECTION_INFO): Define.
|
||||
(FINALIZE_PIC): New macros.
|
||||
(LEGITIMATE_PIC_OPERAND_P, SYMBOLIC_CONST_P): New macro.
|
||||
(ASM_OUTPUT_INT, ASM_OUTPUT_SHORT): Use output_pic_addr_const.
|
||||
* config/sh/sh.c (print_operand_address): Use output_pic_addr_const.
|
||||
(prepare_move_operands): Call emit_pic_move or
|
||||
emit_pic_const_move if appropriate.
|
||||
(output_far_jump): For PIC, use braf and output long offset.
|
||||
(machine_dependent_reorg):
|
||||
(sh_expand_prologue): Save and initialize the PIC register.
|
||||
(sh_expand_epilogue): Restore it.
|
||||
(initial_elimination_offset): Account for it.
|
||||
(nonpic_symbol_mentioned_p): New function.
|
||||
(legitimize_pic_address): Likewise.
|
||||
(output_pic_addr_const): Likewise.
|
||||
* config/sh/sh.md (calli_pcrel, call_valuei_pcrel): New insns.
|
||||
(call, call_value): Use them.
|
||||
(GOTaddr2picreg, sym_label2reg, symGOT2reg, symGOTOFF2reg,
|
||||
symPLT_label2reg): New expands.
|
||||
* invoke.texi (SH Options): Document -mprefergot.
|
||||
|
||||
2000-09-01 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
* rtl.h (ASM_OPERANDS_INPUT_CONSTRAINT_EXP): New macro.
|
||||
|
107
gcc/config/sh/crt1.asm
Normal file
107
gcc/config/sh/crt1.asm
Normal file
@ -0,0 +1,107 @@
|
||||
/* Copyright (C) 2000 Free Software Foundation, Inc.
|
||||
This file was pretty much copied from newlib.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
In addition to the permissions in the GNU General Public License, the
|
||||
Free Software Foundation gives you unlimited permission to link the
|
||||
compiled version of this file into combinations with other programs,
|
||||
and to distribute those combinations without any restriction coming
|
||||
from the use of this file. (The General Public License restrictions
|
||||
do apply in other respects; for example, they cover modification of
|
||||
the file, and distribution when not linked into a combine
|
||||
executable.)
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
.section .text
|
||||
.global start
|
||||
start:
|
||||
mov.l stack_k,r15
|
||||
|
||||
! zero out bss
|
||||
mov.l edata_k,r0
|
||||
mov.l end_k,r1
|
||||
mov #0,r2
|
||||
start_l:
|
||||
mov.l r2,@r0
|
||||
add #4,r0
|
||||
cmp/ge r0,r1
|
||||
bt start_l
|
||||
|
||||
#if defined (__SH3E__) || defined(__SH4_SINGLE__) || defined(__SH4__) || defined(__SH4_SINGLE_ONLY)
|
||||
mov.l set_fpscr_k, r1
|
||||
jsr @r1
|
||||
mov #0,r4
|
||||
lds r3,fpscr
|
||||
#endif /* defined (__SH3E__) || defined(__SH4_SINGLE__) || defined(__SH4__) || defined(__SH4_SINGLE_ONLY__) */
|
||||
|
||||
! arrange for exit to call fini
|
||||
mov.l atexit_k,r0
|
||||
jsr @r0
|
||||
mov.l fini_k,r4
|
||||
|
||||
! call init
|
||||
mov.l init_k,r0
|
||||
jsr @r0
|
||||
nop
|
||||
|
||||
! call the mainline
|
||||
mov.l main_k,r0
|
||||
jsr @r0
|
||||
nop
|
||||
|
||||
! call exit
|
||||
mov r0,r4
|
||||
mov.l exit_k,r0
|
||||
jsr @r0
|
||||
nop
|
||||
|
||||
.align 2
|
||||
#if defined (__SH3E__) || defined(__SH4_SINGLE__) || defined(__SH4__) || defined(__SH4_SINGLE_ONLY__)
|
||||
set_fpscr_k:
|
||||
.long ___set_fpscr
|
||||
#endif /* defined (__SH3E__) || defined(__SH4_SINGLE__) || defined(__SH4__) || defined(SH4_SINGLE_ONLY) */
|
||||
stack_k:
|
||||
.long _stack
|
||||
edata_k:
|
||||
.long _edata
|
||||
end_k:
|
||||
.long _end
|
||||
main_k:
|
||||
.long _main
|
||||
exit_k:
|
||||
.long _exit
|
||||
atexit_k:
|
||||
.long _atexit
|
||||
init_k:
|
||||
.long _init
|
||||
fini_k:
|
||||
.long _fini
|
||||
|
||||
! supplied for backward compatibility only, in case of linking
|
||||
! code whose main() was compiled with an older version of GCC.
|
||||
.global ___main
|
||||
___main:
|
||||
rts
|
||||
nop
|
||||
|
||||
#ifdef __ELF__
|
||||
.section .stack,"aw"
|
||||
#else
|
||||
.section .stack
|
||||
#endif
|
||||
_stack: .long 0xdeaddead
|
101
gcc/config/sh/crti.asm
Normal file
101
gcc/config/sh/crti.asm
Normal file
@ -0,0 +1,101 @@
|
||||
/* Copyright (C) 2000 Free Software Foundation, Inc.
|
||||
This file was adapted from glibc sources.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
In addition to the permissions in the GNU General Public License, the
|
||||
Free Software Foundation gives you unlimited permission to link the
|
||||
compiled version of this file into combinations with other programs,
|
||||
and to distribute those combinations without any restriction coming
|
||||
from the use of this file. (The General Public License restrictions
|
||||
do apply in other respects; for example, they cover modification of
|
||||
the file, and distribution when not linked into a combine
|
||||
executable.)
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* The code in sections .init and .fini is supposed to be a single
|
||||
regular function. The function in .init is called directly from
|
||||
start in crt1.asm. The function in .fini is atexit()ed in crt1.asm
|
||||
too.
|
||||
|
||||
crti.asm contributes the prologue of a function to these sections,
|
||||
and crtn.asm comes up the epilogue. STARTFILE_SPEC should list
|
||||
crti.o before any other object files that might add code to .init
|
||||
or .fini sections, and ENDFILE_SPEC should list crtn.o after any
|
||||
such object files. */
|
||||
|
||||
.section .init
|
||||
/* The alignment below can't be smaller, otherwide the mova below
|
||||
breaks. Yes, we might align just the label, but then we'd be
|
||||
exchanging an alignment here for one there, since the code fragment
|
||||
below ensures 4-byte alignment on __ELF__. */
|
||||
#ifdef __ELF__
|
||||
.p2align 2
|
||||
#else
|
||||
.p2align 1
|
||||
#endif
|
||||
.global _init
|
||||
_init:
|
||||
#ifdef __ELF__
|
||||
mov.l r12,@-r15
|
||||
mova 0f,r0
|
||||
mov.l 0f,r12
|
||||
#endif
|
||||
mov.l r14,@-r15
|
||||
#ifdef __ELF__
|
||||
add r0,r12
|
||||
#endif
|
||||
sts.l pr,@-r15
|
||||
#ifdef __ELF__
|
||||
bra 1f
|
||||
#endif
|
||||
mov r15,r14
|
||||
#ifdef __ELF__
|
||||
0: .long _GLOBAL_OFFSET_TABLE_
|
||||
1:
|
||||
#endif
|
||||
|
||||
.section .fini
|
||||
/* The alignment below can't be smaller, otherwide the mova below
|
||||
breaks. Yes, we might align just the label, but then we'd be
|
||||
exchanging an alignment here for one there, since the code fragment
|
||||
below ensures 4-byte alignment on __ELF__. */
|
||||
#ifdef __ELF__
|
||||
.p2align 2
|
||||
#else
|
||||
.p2align 1
|
||||
#endif
|
||||
.global _fini
|
||||
_fini:
|
||||
#ifdef __ELF__
|
||||
mov.l r12,@-r15
|
||||
mova 0f,r0
|
||||
mov.l 0f,r12
|
||||
#endif
|
||||
mov.l r14,@-r15
|
||||
#ifdef __ELF__
|
||||
add r0,r12
|
||||
#endif
|
||||
sts.l pr,@-r15
|
||||
#ifdef __ELF__
|
||||
bra 1f
|
||||
#endif
|
||||
mov r15,r14
|
||||
#ifdef __ELF__
|
||||
0: .long _GLOBAL_OFFSET_TABLE_
|
||||
1:
|
||||
#endif
|
52
gcc/config/sh/crtn.asm
Normal file
52
gcc/config/sh/crtn.asm
Normal file
@ -0,0 +1,52 @@
|
||||
/* Copyright (C) 2000 Free Software Foundation, Inc.
|
||||
This file was adapted from glibc sources.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
In addition to the permissions in the GNU General Public License, the
|
||||
Free Software Foundation gives you unlimited permission to link the
|
||||
compiled version of this file into combinations with other programs,
|
||||
and to distribute those combinations without any restriction coming
|
||||
from the use of this file. (The General Public License restrictions
|
||||
do apply in other respects; for example, they cover modification of
|
||||
the file, and distribution when not linked into a combine
|
||||
executable.)
|
||||
|
||||
GNU CC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* See an explanation about .init and .fini in crti.asm. */
|
||||
|
||||
.section .init
|
||||
mov r15,r14
|
||||
lds.l @r15+,pr
|
||||
mov.l @r15+,r14
|
||||
rts
|
||||
#ifdef __ELF__
|
||||
mov.l @r15+,r12
|
||||
#else
|
||||
nop
|
||||
#endif
|
||||
|
||||
.section .fini
|
||||
mov r15,r14
|
||||
lds.l @r15+,pr
|
||||
mov.l @r15+,r14
|
||||
rts
|
||||
#ifdef __ELF__
|
||||
mov.l @r15+,r12
|
||||
#else
|
||||
nop
|
||||
#endif
|
@ -43,6 +43,8 @@ Boston, MA 02111-1307, USA. */
|
||||
#undef ASM_OUTPUT_DESTRUCTOR
|
||||
#undef ASM_DECLARE_FUNCTION_NAME
|
||||
#undef MAX_OFILE_ALIGNMENT
|
||||
#undef INIT_SECTION_ASM_OP
|
||||
#undef FINI_SECTION_ASM_OP
|
||||
|
||||
/* Be ELF-like. */
|
||||
#include "svr4.h"
|
||||
@ -110,13 +112,15 @@ do { \
|
||||
fprintf ((FILE), "\t.stabs \"\",%d,0,0,Letext\nLetext:\n", N_SO); \
|
||||
} while (0)
|
||||
|
||||
/* Arrange to call __main, rather than using crtbegin.o and crtend.o
|
||||
and relying on .init and .fini being executed at appropriate times. */
|
||||
#undef INIT_SECTION_ASM_OP
|
||||
#undef FINI_SECTION_ASM_OP
|
||||
#undef STARTFILE_SPEC
|
||||
#undef ENDFILE_SPEC
|
||||
|
||||
/* HANDLE_SYSV_PRAGMA (defined by svr4.h) takes precedence over HANDLE_PRAGMA.
|
||||
We want to use the HANDLE_PRAGMA from sh.h. */
|
||||
#undef HANDLE_SYSV_PRAGMA
|
||||
|
||||
#undef STARTFILE_SPEC
|
||||
#define STARTFILE_SPEC \
|
||||
"%{!shared: crt1.o%s} crti.o%s \
|
||||
%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}"
|
||||
|
||||
#undef ENDFILE_SPEC
|
||||
#define ENDFILE_SPEC \
|
||||
"%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s"
|
||||
|
@ -42,10 +42,13 @@ extern int fp_zero_operand PARAMS ((rtx));
|
||||
extern int fp_one_operand PARAMS ((rtx));
|
||||
extern int fp_int_operand PARAMS ((rtx));
|
||||
extern rtx get_fpscr_rtx PARAMS ((void));
|
||||
extern rtx legitimize_pic_address PARAMS ((rtx, enum machine_mode, rtx));
|
||||
extern int nonpic_symbol_mentioned_p PARAMS ((rtx));
|
||||
extern void emit_sf_insn PARAMS ((rtx));
|
||||
extern void emit_df_insn PARAMS ((rtx));
|
||||
extern void print_operand_address PARAMS ((FILE *, rtx));
|
||||
extern void print_operand PARAMS ((FILE *, rtx, int));
|
||||
extern void output_pic_addr_const PARAMS ((FILE *, rtx));
|
||||
extern int expand_block_move PARAMS ((rtx *));
|
||||
extern int prepare_move_operands PARAMS ((rtx[], enum machine_mode mode));
|
||||
extern void from_compare PARAMS ((rtx *, int));
|
||||
|
@ -201,7 +201,7 @@ print_operand_address (stream, x)
|
||||
break;
|
||||
|
||||
default:
|
||||
output_addr_const (stream, x);
|
||||
output_pic_addr_const (stream, x);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -457,6 +457,31 @@ prepare_move_operands (operands, mode)
|
||||
rtx operands[];
|
||||
enum machine_mode mode;
|
||||
{
|
||||
if (mode == SImode && flag_pic)
|
||||
{
|
||||
rtx temp;
|
||||
if (SYMBOLIC_CONST_P (operands[1]))
|
||||
{
|
||||
if (GET_CODE (operands[0]) == MEM)
|
||||
operands[1] = force_reg (Pmode, operands[1]);
|
||||
else
|
||||
{
|
||||
temp = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
|
||||
operands[1] = legitimize_pic_address (operands[1], SImode, temp);
|
||||
}
|
||||
}
|
||||
else if (GET_CODE (operands[1]) == CONST
|
||||
&& GET_CODE (XEXP (operands[1], 0)) == PLUS
|
||||
&& SYMBOLIC_CONST_P (XEXP (XEXP (operands[1], 0), 0)))
|
||||
{
|
||||
temp = legitimize_pic_address (XEXP (XEXP (operands[1], 0), 0),
|
||||
SImode, gen_reg_rtx (Pmode));
|
||||
operands[1] = expand_binop (SImode, add_optab, temp,
|
||||
XEXP (XEXP (operands[1], 0), 1),
|
||||
gen_reg_rtx (Pmode), 0, OPTAB_LIB_WIDEN);
|
||||
}
|
||||
}
|
||||
|
||||
if (! reload_in_progress && ! reload_completed)
|
||||
{
|
||||
/* Copy the source to a register if both operands aren't registers. */
|
||||
@ -702,6 +727,9 @@ output_far_jump (insn, op)
|
||||
else
|
||||
{
|
||||
far = 1;
|
||||
if (flag_pic)
|
||||
jump = "mov.l %O0,%1;braf %1";
|
||||
else
|
||||
jump = "mov.l %O0,%1;jmp @%1";
|
||||
}
|
||||
/* If we have a scratch register available, use it. */
|
||||
@ -730,6 +758,9 @@ output_far_jump (insn, op)
|
||||
output_asm_insn (".align 2", 0);
|
||||
ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (this.lab));
|
||||
this.op = op;
|
||||
if (far && flag_pic)
|
||||
output_asm_insn (".long %O2-%O0", &this.lab);
|
||||
else
|
||||
output_asm_insn (far ? ".long %O2" : ".word %O2-%O0", &this.lab);
|
||||
return "";
|
||||
}
|
||||
@ -3214,6 +3245,19 @@ machine_dependent_reorg (first)
|
||||
/* Remove the clobber of r0. */
|
||||
XEXP (clobber, 0) = gen_rtx_SCRATCH (Pmode);
|
||||
}
|
||||
/* This is a mova needing a label. Create it. */
|
||||
else if (GET_CODE (src) == CONST
|
||||
&& GET_CODE (XEXP (src, 0)) == UNSPEC
|
||||
&& XINT (XEXP (src, 0), 1) == 1
|
||||
&& GET_CODE (XVECEXP (XEXP (src, 0),
|
||||
0, 0)) == CONST)
|
||||
{
|
||||
lab = add_constant (XVECEXP (XEXP (src, 0),
|
||||
0, 0), mode, 0);
|
||||
newsrc = gen_rtx_LABEL_REF (VOIDmode, lab);
|
||||
newsrc = gen_rtx_UNSPEC (VOIDmode,
|
||||
gen_rtvec (1, newsrc), 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
lab = add_constant (src, mode, 0);
|
||||
@ -3874,7 +3918,20 @@ sh_expand_prologue ()
|
||||
that already happens to be at the function start into the prologue. */
|
||||
if (target_flags != save_flags)
|
||||
emit_insn (gen_toggle_sz ());
|
||||
if (flag_pic && (current_function_uses_pic_offset_table
|
||||
|| regs_ever_live[PIC_OFFSET_TABLE_REGNUM]))
|
||||
{
|
||||
if ((live_regs_mask & (1 << PIC_OFFSET_TABLE_REGNUM)) != 0)
|
||||
abort ();
|
||||
d += UNITS_PER_WORD;
|
||||
live_regs_mask |= (1 << PIC_OFFSET_TABLE_REGNUM);
|
||||
}
|
||||
push_regs (live_regs_mask, live_regs_mask2);
|
||||
|
||||
if (flag_pic && (current_function_uses_pic_offset_table
|
||||
|| regs_ever_live[PIC_OFFSET_TABLE_REGNUM]))
|
||||
emit_insn (gen_GOTaddr2picreg ());
|
||||
|
||||
if (target_flags != save_flags)
|
||||
emit_insn (gen_toggle_sz ());
|
||||
|
||||
@ -3926,6 +3983,8 @@ sh_expand_epilogue ()
|
||||
|
||||
if (target_flags != save_flags)
|
||||
emit_insn (gen_toggle_sz ());
|
||||
if (flag_pic && current_function_uses_pic_offset_table)
|
||||
live_regs_mask |= (1 << PIC_OFFSET_TABLE_REGNUM);
|
||||
if (live_regs_mask & (1 << PR_REG))
|
||||
pop (PR_REG);
|
||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||
@ -4329,6 +4388,11 @@ initial_elimination_offset (from, to)
|
||||
|
||||
int live_regs_mask, live_regs_mask2;
|
||||
live_regs_mask = calc_live_regs (®s_saved, &live_regs_mask2);
|
||||
if (flag_pic && current_function_uses_pic_offset_table)
|
||||
{
|
||||
regs_saved++;
|
||||
live_regs_mask |= (1 << PIC_OFFSET_TABLE_REGNUM);
|
||||
}
|
||||
total_auto_space = rounded_frame_size (regs_saved);
|
||||
target_flags = save_flags;
|
||||
|
||||
@ -5189,3 +5253,184 @@ sh_insn_length_adjustment (insn)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return TRUE if X references a SYMBOL_REF whose symbol doesn't have
|
||||
@GOT or @GOTOFF. */
|
||||
int
|
||||
nonpic_symbol_mentioned_p (x)
|
||||
rtx x;
|
||||
{
|
||||
register const char *fmt;
|
||||
register int i;
|
||||
|
||||
if (GET_CODE (x) == SYMBOL_REF)
|
||||
return 1;
|
||||
|
||||
if (GET_CODE (x) == UNSPEC
|
||||
&& (XINT (x, 1) >= 6 && XINT (x, 1) <= 9))
|
||||
return 0;
|
||||
|
||||
fmt = GET_RTX_FORMAT (GET_CODE (x));
|
||||
for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
|
||||
{
|
||||
if (fmt[i] == 'E')
|
||||
{
|
||||
register int j;
|
||||
|
||||
for (j = XVECLEN (x, i) - 1; j >= 0; j--)
|
||||
if (nonpic_symbol_mentioned_p (XVECEXP (x, i, j)))
|
||||
return 1;
|
||||
}
|
||||
else if (fmt[i] == 'e' && nonpic_symbol_mentioned_p (XEXP (x, i)))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Convert a non-PIC address in `orig' to a PIC address using @GOT or
|
||||
@GOTOFF in `reg'. */
|
||||
rtx
|
||||
legitimize_pic_address (orig, mode, reg)
|
||||
rtx orig;
|
||||
enum machine_mode mode;
|
||||
rtx reg;
|
||||
{
|
||||
if (GET_CODE (orig) == LABEL_REF
|
||||
|| (GET_CODE (orig) == SYMBOL_REF
|
||||
&& (CONSTANT_POOL_ADDRESS_P (orig)
|
||||
/* SYMBOL_REF_FLAG is set on static symbols. */
|
||||
|| SYMBOL_REF_FLAG (orig))))
|
||||
{
|
||||
if (reg == 0)
|
||||
reg = gen_reg_rtx (Pmode);
|
||||
|
||||
emit_insn (gen_symGOTOFF2reg (reg, orig));
|
||||
return reg;
|
||||
}
|
||||
else if (GET_CODE (orig) == SYMBOL_REF)
|
||||
{
|
||||
if (reg == 0)
|
||||
reg = gen_reg_rtx (Pmode);
|
||||
|
||||
emit_insn (gen_symGOT2reg (reg, orig));
|
||||
return reg;
|
||||
}
|
||||
return orig;
|
||||
}
|
||||
|
||||
/* Like output_addr_const(), but recognize PIC unspecs and special
|
||||
expressions. */
|
||||
void
|
||||
output_pic_addr_const (file, x)
|
||||
FILE *file;
|
||||
rtx x;
|
||||
{
|
||||
char buf[256];
|
||||
|
||||
switch (GET_CODE (x))
|
||||
{
|
||||
case PC:
|
||||
if (flag_pic)
|
||||
putc ('.', file);
|
||||
else
|
||||
abort ();
|
||||
break;
|
||||
|
||||
case SYMBOL_REF:
|
||||
assemble_name (file, XSTR (x, 0));
|
||||
break;
|
||||
|
||||
case LABEL_REF:
|
||||
x = XEXP (x, 0);
|
||||
/* FALLTHRU */
|
||||
case CODE_LABEL:
|
||||
ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
|
||||
assemble_name (asm_out_file, buf);
|
||||
break;
|
||||
|
||||
case CONST:
|
||||
output_pic_addr_const (file, XEXP (x, 0));
|
||||
break;
|
||||
|
||||
case CONST_INT:
|
||||
fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
|
||||
break;
|
||||
|
||||
case CONST_DOUBLE:
|
||||
if (GET_MODE (x) == VOIDmode)
|
||||
{
|
||||
/* We can use %d if the number is <32 bits and positive. */
|
||||
if (CONST_DOUBLE_HIGH (x) || CONST_DOUBLE_LOW (x) < 0)
|
||||
fprintf (file, "0x%lx%08lx",
|
||||
(unsigned long) CONST_DOUBLE_HIGH (x),
|
||||
(unsigned long) CONST_DOUBLE_LOW (x));
|
||||
else
|
||||
fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x));
|
||||
}
|
||||
else
|
||||
/* We can't handle floating point constants;
|
||||
PRINT_OPERAND must handle them. */
|
||||
output_operand_lossage ("floating constant misused");
|
||||
break;
|
||||
|
||||
case PLUS:
|
||||
/* Some assemblers need integer constants to appear first. */
|
||||
if (GET_CODE (XEXP (x, 0)) == CONST_INT)
|
||||
{
|
||||
output_pic_addr_const (file, XEXP (x, 0));
|
||||
fprintf (file, "+");
|
||||
output_pic_addr_const (file, XEXP (x, 1));
|
||||
}
|
||||
else if (GET_CODE (XEXP (x, 1)) == CONST_INT
|
||||
|| GET_CODE (XEXP (x, 0)) == PC)
|
||||
{
|
||||
output_pic_addr_const (file, XEXP (x, 1));
|
||||
fprintf (file, "+");
|
||||
output_pic_addr_const (file, XEXP (x, 0));
|
||||
}
|
||||
else
|
||||
abort ();
|
||||
break;
|
||||
|
||||
case MINUS:
|
||||
output_pic_addr_const (file, XEXP (x, 0));
|
||||
fprintf (file, "-");
|
||||
if (GET_CODE (XEXP (x, 1)) == CONST)
|
||||
{
|
||||
putc ('(', file);
|
||||
output_pic_addr_const (file, XEXP (x, 1));
|
||||
putc (')', file);
|
||||
}
|
||||
else
|
||||
output_pic_addr_const (file, XEXP (x, 1));
|
||||
break;
|
||||
|
||||
case UNSPEC:
|
||||
if ((XVECLEN (x, 0)) > 3)
|
||||
abort ();
|
||||
output_pic_addr_const (file, XVECEXP (x, 0, 0));
|
||||
switch (XINT (x, 1))
|
||||
{
|
||||
case 6:
|
||||
/* GLOBAL_OFFSET_TABLE or local symbols, no suffix. */
|
||||
break;
|
||||
case 7:
|
||||
fputs ("@GOT", file);
|
||||
break;
|
||||
case 8:
|
||||
fputs ("@GOTOFF", file);
|
||||
break;
|
||||
case 9:
|
||||
fputs ("@PLT", file);
|
||||
break;
|
||||
default:
|
||||
output_operand_lossage ("invalid UNSPEC as operand");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
output_operand_lossage ("invalid expression as operand");
|
||||
}
|
||||
}
|
||||
|
@ -78,6 +78,11 @@ extern int code_for_indirect_jump_scratch;
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
if (flag_pic) \
|
||||
{ \
|
||||
fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
|
||||
call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
|
||||
} \
|
||||
/* Hitachi saves and restores mac registers on call. */ \
|
||||
if (TARGET_HITACHI && ! TARGET_NOMACSAVE) \
|
||||
{ \
|
||||
@ -106,6 +111,7 @@ extern int target_flags;
|
||||
#define RELAX_BIT (1<<15)
|
||||
#define HITACHI_BIT (1<<22)
|
||||
#define NOMACSAVE_BIT (1<<23)
|
||||
#define PREFERGOT_BIT (1<<24)
|
||||
#define PADSTRUCT_BIT (1<<28)
|
||||
#define LITTLE_ENDIAN_BIT (1<<29)
|
||||
#define IEEE_BIT (1<<30)
|
||||
@ -178,6 +184,9 @@ extern int target_flags;
|
||||
/* Nonzero if generating code for a little endian SH. */
|
||||
#define TARGET_LITTLE_ENDIAN (target_flags & LITTLE_ENDIAN_BIT)
|
||||
|
||||
/* Nonzero if we should prefer @GOT calls when generating PIC. */
|
||||
#define TARGET_PREFERGOT (target_flags & PREFERGOT_BIT)
|
||||
|
||||
#define TARGET_SWITCHES \
|
||||
{ {"1", SH1_BIT}, \
|
||||
{"2", SH2_BIT}, \
|
||||
@ -198,6 +207,7 @@ extern int target_flags;
|
||||
{"l", LITTLE_ENDIAN_BIT}, \
|
||||
{"no-ieee", -IEEE_BIT}, \
|
||||
{"padstruct", PADSTRUCT_BIT}, \
|
||||
{"prefergot", PREFERGOT_BIT}, \
|
||||
{"relax", RELAX_BIT}, \
|
||||
{"space", SPACE_BIT}, \
|
||||
SUBTARGET_SWITCHES \
|
||||
@ -256,6 +266,9 @@ do { \
|
||||
else \
|
||||
flag_omit_frame_pointer = 0; \
|
||||
\
|
||||
if (! TARGET_PREFERGOT) \
|
||||
flag_no_function_cse = 1; \
|
||||
\
|
||||
/* Never run scheduling before reload, since that can \
|
||||
break global alloc, and generates slower code anyway due \
|
||||
to the pressure on R0. */ \
|
||||
@ -538,6 +551,12 @@ do { \
|
||||
current function's return address. */
|
||||
#define RETURN_ADDRESS_POINTER_REGNUM 23
|
||||
|
||||
/* Register to hold the addressing base for position independent
|
||||
code access to data items. */
|
||||
#define PIC_OFFSET_TABLE_REGNUM 12
|
||||
|
||||
#define GOT_SYMBOL_NAME "*_GLOBAL_OFFSET_TABLE_"
|
||||
|
||||
/* Value should be nonzero if functions must have frame pointers.
|
||||
Zero means the frame pointer need not be set up (and parms may be accessed
|
||||
via the stack pointer) in functions that seem suitable. */
|
||||
@ -1400,6 +1419,8 @@ extern int current_function_anonymous_args;
|
||||
|
||||
#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \
|
||||
{ \
|
||||
if (flag_pic) \
|
||||
(X) = legitimize_pic_address (OLDX, MODE, NULL_RTX); \
|
||||
if (GET_CODE (X) == PLUS \
|
||||
&& (GET_MODE_SIZE (MODE) == 4 \
|
||||
|| GET_MODE_SIZE (MODE) == 8) \
|
||||
@ -1708,6 +1729,44 @@ extern int current_function_anonymous_args;
|
||||
&& GET_CODE (PATTERN (X)) != CLOBBER \
|
||||
&& get_attr_is_sfunc (X)))
|
||||
|
||||
|
||||
/* Position Independent Code. */
|
||||
/* Define this macro if references to a symbol must be treated
|
||||
differently depending on something about the variable or function
|
||||
named by the symbol (such as what section it is in).
|
||||
|
||||
On SH, if using PIC, mark a SYMBOL_REF for a non-global symbol
|
||||
so that we may access it using GOTOFF instead of GOT. */
|
||||
|
||||
#define ENCODE_SECTION_INFO(DECL) \
|
||||
do \
|
||||
{ \
|
||||
if (flag_pic) \
|
||||
{ \
|
||||
rtx rtl = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \
|
||||
? TREE_CST_RTL (DECL) : DECL_RTL (DECL)); \
|
||||
\
|
||||
SYMBOL_REF_FLAG (XEXP (rtl, 0)) = \
|
||||
(TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \
|
||||
|| ! TREE_PUBLIC (DECL)); \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define FINALIZE_PIC \
|
||||
current_function_uses_pic_offset_table |= profile_flag | profile_block_flag
|
||||
|
||||
/* We can't directly access anything that contains a symbol,
|
||||
nor can we indirect via the constant pool. */
|
||||
#define LEGITIMATE_PIC_OPERAND_P(X) \
|
||||
(! nonpic_symbol_mentioned_p (X) \
|
||||
&& (! CONSTANT_POOL_ADDRESS_P (X) \
|
||||
|| ! nonpic_symbol_mentioned_p (get_pool_constant (X))))
|
||||
|
||||
#define SYMBOLIC_CONST_P(X) \
|
||||
((GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == LABEL_REF) \
|
||||
&& nonpic_symbol_mentioned_p (X))
|
||||
|
||||
/* Compute the cost of an address. For the SH, all valid addresses are
|
||||
the same cost. */
|
||||
/* ??? Perhaps we should make reg+reg addresses have higher cost because
|
||||
@ -2003,12 +2062,12 @@ do { char dstr[30]; \
|
||||
|
||||
#define ASM_OUTPUT_INT(STREAM, EXP) \
|
||||
(fprintf ((STREAM), "\t.long\t"), \
|
||||
output_addr_const ((STREAM), (EXP)), \
|
||||
output_pic_addr_const ((STREAM), (EXP)), \
|
||||
fputc ('\n', (STREAM)))
|
||||
|
||||
#define ASM_OUTPUT_SHORT(STREAM, EXP) \
|
||||
(fprintf ((STREAM), "\t.short\t"), \
|
||||
output_addr_const ((STREAM), (EXP)), \
|
||||
output_pic_addr_const ((STREAM), (EXP)), \
|
||||
fputc ('\n', (STREAM)))
|
||||
|
||||
#define ASM_OUTPUT_CHAR(STREAM, EXP) \
|
||||
@ -2279,3 +2338,34 @@ do { \
|
||||
fpscr_set_from_mem ((MODE), (HARD_REGS_LIVE))
|
||||
|
||||
#define DWARF_LINE_MIN_INSTR_LENGTH 2
|
||||
|
||||
#undef INIT_SECTION_ASM_OP
|
||||
#define INIT_SECTION_ASM_OP ".section\t.init"
|
||||
#undef FINI_SECTION_ASM_OP
|
||||
#define FINI_SECTION_ASM_OP ".section\t.fini"
|
||||
|
||||
#undef STARTFILE_SPEC
|
||||
#define STARTFILE_SPEC \
|
||||
"crt1.o%s crti.o%s crtbegin.o%s"
|
||||
|
||||
#undef ENDFILE_SPEC
|
||||
#define ENDFILE_SPEC \
|
||||
"crtend.o%s crtn.o%s"
|
||||
|
||||
/* SH constant pool breaks the devices in crtstuff.c to control section
|
||||
in where code resides. We have to write it as asm code. */
|
||||
#define CRT_CALL_STATIC_FUNCTION(func) \
|
||||
if (0) \
|
||||
/* This avoids warnings about the static function being unused. */ \
|
||||
func (); \
|
||||
else \
|
||||
/* We should be passing FUNC to the asm statement as an asm input \
|
||||
operand, but this breaks with -fPIC. FIXME. */ \
|
||||
asm \
|
||||
("mov.l 1f,r1\n\
|
||||
mova 2f,r0\n\
|
||||
braf r1\n\
|
||||
lds r0,pr\n\
|
||||
0: .p2align 2\n\
|
||||
1: .long " USER_LABEL_PREFIX #func " - 0b\n\
|
||||
2:")
|
||||
|
@ -3295,6 +3295,22 @@
|
||||
(const_string "single") (const_string "double")))
|
||||
(set_attr "needs_delay_slot" "yes")])
|
||||
|
||||
;; This is a pc-rel call, using bsrf, for use with PIC.
|
||||
|
||||
(define_insn "calli_pcrel"
|
||||
[(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
|
||||
(match_operand 1 "" ""))
|
||||
(use (reg:SI 48))
|
||||
(use (match_operand 2 "" ""))
|
||||
(clobber (reg:SI 17))]
|
||||
""
|
||||
"bsrf %0\\n%O2:%#"
|
||||
[(set_attr "type" "call")
|
||||
(set (attr "fp_mode")
|
||||
(if_then_else (eq_attr "fpu_single" "yes")
|
||||
(const_string "single") (const_string "double")))
|
||||
(set_attr "needs_delay_slot" "yes")])
|
||||
|
||||
(define_insn "call_valuei"
|
||||
[(set (match_operand 0 "" "=rf")
|
||||
(call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
|
||||
@ -3309,13 +3325,44 @@
|
||||
(const_string "single") (const_string "double")))
|
||||
(set_attr "needs_delay_slot" "yes")])
|
||||
|
||||
(define_insn "call_valuei_pcrel"
|
||||
[(set (match_operand 0 "" "=rf")
|
||||
(call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
|
||||
(match_operand 2 "" "")))
|
||||
(use (reg:SI 48))
|
||||
(use (match_operand 3 "" ""))
|
||||
(clobber (reg:SI 17))]
|
||||
""
|
||||
"bsrf %1\\n%O3:%#"
|
||||
[(set_attr "type" "call")
|
||||
(set (attr "fp_mode")
|
||||
(if_then_else (eq_attr "fpu_single" "yes")
|
||||
(const_string "single") (const_string "double")))
|
||||
(set_attr "needs_delay_slot" "yes")])
|
||||
|
||||
(define_expand "call"
|
||||
[(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
|
||||
(match_operand 1 "" ""))
|
||||
(use (reg:SI 48))
|
||||
(clobber (reg:SI 17))])]
|
||||
""
|
||||
"operands[0] = force_reg (SImode, XEXP (operands[0], 0));")
|
||||
"
|
||||
if (flag_pic && ! TARGET_SH1 && ! flag_unroll_loops
|
||||
&& GET_CODE (operands[0]) == MEM
|
||||
&& GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
|
||||
{
|
||||
rtx reg = gen_reg_rtx (SImode), lab = gen_label_rtx ();
|
||||
|
||||
if (SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
|
||||
emit_insn (gen_sym_label2reg (reg, XEXP (operands[0], 0), lab));
|
||||
else
|
||||
emit_insn (gen_symPLT_label2reg (reg, XEXP (operands[0], 0), lab));
|
||||
operands[0] = reg;
|
||||
emit_call_insn (gen_calli_pcrel (operands[0], operands[1], lab));
|
||||
DONE;
|
||||
}
|
||||
else
|
||||
operands[0] = force_reg (SImode, XEXP (operands[0], 0));")
|
||||
|
||||
(define_expand "call_value"
|
||||
[(parallel [(set (match_operand 0 "arith_reg_operand" "")
|
||||
@ -3324,7 +3371,24 @@
|
||||
(use (reg:SI 48))
|
||||
(clobber (reg:SI 17))])]
|
||||
""
|
||||
"operands[1] = force_reg (SImode, XEXP (operands[1], 0));")
|
||||
"
|
||||
if (flag_pic && ! TARGET_SH1 && ! flag_unroll_loops
|
||||
&& GET_CODE (operands[1]) == MEM
|
||||
&& GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
|
||||
{
|
||||
rtx reg = gen_reg_rtx (SImode), lab = gen_label_rtx ();
|
||||
|
||||
if (SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
|
||||
emit_insn (gen_sym_label2reg (reg, XEXP (operands[1], 0), lab));
|
||||
else
|
||||
emit_insn (gen_symPLT_label2reg (reg, XEXP (operands[1], 0), lab));
|
||||
operands[1] = reg;
|
||||
emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[1],
|
||||
operands[2], lab));
|
||||
DONE;
|
||||
}
|
||||
else
|
||||
operands[1] = force_reg (SImode, XEXP (operands[1], 0));")
|
||||
|
||||
(define_insn "indirect_jump"
|
||||
[(set (pc)
|
||||
@ -3418,6 +3482,58 @@
|
||||
[(set_attr "in_delay_slot" "no")
|
||||
(set_attr "type" "arith")])
|
||||
|
||||
(define_expand "GOTaddr2picreg"
|
||||
[(set (reg:SI 0) (const (unspec [(const (unspec [(match_dup 1)] 6))] 1)))
|
||||
(set (match_dup 0) (const (unspec [(match_dup 1)] 6)))
|
||||
(set (match_dup 0) (plus:SI (match_dup 0) (reg:SI 0)))]
|
||||
"" "
|
||||
{
|
||||
operands[0] = pic_offset_table_rtx;
|
||||
current_function_uses_pic_offset_table = 1;
|
||||
operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
|
||||
}
|
||||
")
|
||||
|
||||
(define_expand "sym_label2reg"
|
||||
[(set (match_operand:SI 0 "" "")
|
||||
(const (minus:SI
|
||||
(unspec [(match_operand:SI 1 "" "")] 6)
|
||||
(const (plus:SI (label_ref (match_operand:SI 2 "" ""))
|
||||
(const_int 2))))))]
|
||||
"" "")
|
||||
|
||||
(define_expand "symGOT2reg"
|
||||
[(set (match_operand:SI 0 "" "")
|
||||
(const (unspec [(match_operand:SI 1 "" "")] 7)))
|
||||
(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
|
||||
(set (match_dup 0) (mem:SI (match_dup 0)))]
|
||||
""
|
||||
"
|
||||
{
|
||||
operands[2] = pic_offset_table_rtx;
|
||||
current_function_uses_pic_offset_table = 1;
|
||||
}")
|
||||
|
||||
(define_expand "symGOTOFF2reg"
|
||||
[(set (match_operand:SI 0 "" "")
|
||||
(const (unspec [(match_operand:SI 1 "" "")] 8)))
|
||||
(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
|
||||
""
|
||||
"
|
||||
{
|
||||
operands[2] = pic_offset_table_rtx;
|
||||
current_function_uses_pic_offset_table = 1;
|
||||
}")
|
||||
|
||||
(define_expand "symPLT_label2reg"
|
||||
[(set (match_operand:SI 0 "" "")
|
||||
(const (minus:SI
|
||||
(plus:SI (pc)
|
||||
(unspec [(match_operand:SI 1 "" "")] 9))
|
||||
(const (plus:SI (label_ref (match_operand:SI 2 "" ""))
|
||||
(const_int 2))))))]
|
||||
"" "")
|
||||
|
||||
;; case instruction for switch statements.
|
||||
|
||||
;; Operand 0 is index
|
||||
@ -3912,6 +4028,9 @@
|
||||
{
|
||||
operands[1] = get_fpscr_rtx ();
|
||||
operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
|
||||
if (flag_pic)
|
||||
operands[2] = legitimize_pic_address (operands[2], SImode,
|
||||
no_new_pseudos ? operands[0] : 0);
|
||||
}")
|
||||
|
||||
(define_expand "fpu_switch1"
|
||||
@ -3923,6 +4042,9 @@
|
||||
{
|
||||
operands[1] = get_fpscr_rtx ();
|
||||
operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
|
||||
if (flag_pic)
|
||||
operands[2] = legitimize_pic_address (operands[2], SImode,
|
||||
no_new_pseudos ? operands[0] : 0);
|
||||
operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
|
||||
}")
|
||||
|
||||
|
9
gcc/config/sh/t-elf
Normal file
9
gcc/config/sh/t-elf
Normal file
@ -0,0 +1,9 @@
|
||||
EXTRA_MULTILIB_PARTS= crt1.o crti.o crtn.o \
|
||||
crtbegin.o crtend.o crtbeginS.o crtendS.o
|
||||
|
||||
# Compile crtbeginS.o and crtendS.o with pic.
|
||||
CRTSTUFF_T_CFLAGS_S = -fPIC
|
||||
|
||||
# Don't compile libgcc with -fpic for now. It's unlikely that we'll
|
||||
# build shared libraries for embedded SH.
|
||||
# TARGET_LIBGCC2_CFLAGS = -fpic
|
@ -27,3 +27,12 @@ MULTILIB_MATCHES = m2=m3 m2=m4-nofpu
|
||||
|
||||
LIBGCC = stmp-multilib
|
||||
INSTALL_LIBGCC = install-multilib
|
||||
|
||||
$(T)crt1.o: $(srcdir)/config/sh/crt1.asm $(GCC_PASSES)
|
||||
$(GCC_FOR_TARGET) $(MULTILIB_CFLAGS) -c -o $(T)crt1.o -x assembler-with-cpp $(srcdir)/config/sh/crt1.asm
|
||||
$(T)crti.o: $(srcdir)/config/sh/crti.asm $(GCC_PASSES)
|
||||
$(GCC_FOR_TARGET) $(MULTILIB_CFLAGS) -c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/sh/crti.asm
|
||||
$(T)crtn.o: $(srcdir)/config/sh/crtn.asm $(GCC_PASSES)
|
||||
$(GCC_FOR_TARGET) $(MULTILIB_CFLAGS) -c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/sh/crtn.asm
|
||||
|
||||
EXTRA_MULTILIB_PARTS= crt1.o crti.o crtn.o crtbegin.o crtend.o
|
||||
|
3
gcc/configure
vendored
3
gcc/configure
vendored
@ -6308,11 +6308,12 @@ for machine in $build $host $target; do
|
||||
use_collect2=yes
|
||||
;;
|
||||
sh-*-elf*)
|
||||
tmake_file="sh/t-sh sh/t-elf"
|
||||
tm_file="sh/sh.h sh/elf.h"
|
||||
float_format=sh
|
||||
;;
|
||||
sh-*-rtemself*)
|
||||
tmake_file="sh/t-sh t-rtems"
|
||||
tmake_file="sh/t-sh sh/t-elf t-rtems"
|
||||
tm_file="sh/sh.h sh/elf.h sh/rtemself.h"
|
||||
float_format=sh
|
||||
;;
|
||||
|
@ -3344,11 +3344,12 @@ changequote([,])dnl
|
||||
use_collect2=yes
|
||||
;;
|
||||
sh-*-elf*)
|
||||
tmake_file="sh/t-sh sh/t-elf"
|
||||
tm_file="sh/sh.h sh/elf.h"
|
||||
float_format=sh
|
||||
;;
|
||||
sh-*-rtemself*)
|
||||
tmake_file="sh/t-sh t-rtems"
|
||||
tmake_file="sh/t-sh sh/t-elf t-rtems"
|
||||
tm_file="sh/sh.h sh/elf.h sh/rtemself.h"
|
||||
float_format=sh
|
||||
;;
|
||||
|
@ -418,6 +418,7 @@ in the following sections.
|
||||
-mb -ml -mdalign -mrelax
|
||||
-mbigtable -mfmovd -mhitachi -mnomacsave
|
||||
-misize -mpadstruct -mspace
|
||||
-mprefergot
|
||||
|
||||
@emph{System V Options}
|
||||
-Qy -Qn -YP,@var{paths} -Ym,@var{dir}
|
||||
@ -6713,6 +6714,10 @@ which is incompatible with the SH ABI.
|
||||
|
||||
@item -mspace
|
||||
Optimize for space instead of speed. Implied by @code{-Os}.
|
||||
|
||||
@item -mprefergot
|
||||
When generating position-independent code, emit function calls using
|
||||
the Global Offset Table instead of the Procedure Linkage Table.
|
||||
@end table
|
||||
|
||||
@node System V Options
|
||||
|
Loading…
Reference in New Issue
Block a user