Commit 3bcb1bb0 by Nick Clifton

Minot for,matting imrpovemants and synchronisation with devo sources

From-SVN: r31937
parent 914a3b8c
...@@ -106,6 +106,7 @@ extern char * output_move_double PARAMS ((rtx *)); ...@@ -106,6 +106,7 @@ extern char * output_move_double PARAMS ((rtx *));
extern char * output_return_instruction PARAMS ((rtx, int, int)); extern char * output_return_instruction PARAMS ((rtx, int, int));
extern int store_multiple_sequence PARAMS ((rtx *, int, int *, int *, HOST_WIDE_INT *)); extern int store_multiple_sequence PARAMS ((rtx *, int, int *, int *, HOST_WIDE_INT *));
extern int symbol_mentioned_p PARAMS ((rtx)); extern int symbol_mentioned_p PARAMS ((rtx));
extern int arm_is_longcall_p PARAMS ((rtx, int, int));
#if defined AOF_ASSEMBLER #if defined AOF_ASSEMBLER
extern rtx aof_pic_entry PARAMS ((rtx)); extern rtx aof_pic_entry PARAMS ((rtx));
#endif /* AOF_ASSEMBLER */ #endif /* AOF_ASSEMBLER */
...@@ -145,6 +146,7 @@ extern int shift_operator PARAMS ((rtx, Mmode)); ...@@ -145,6 +146,7 @@ extern int shift_operator PARAMS ((rtx, Mmode));
extern int shiftable_operator PARAMS ((rtx, Mmode)); extern int shiftable_operator PARAMS ((rtx, Mmode));
extern int soft_df_operand PARAMS ((rtx, Mmode)); extern int soft_df_operand PARAMS ((rtx, Mmode));
extern int store_multiple_operation PARAMS ((rtx, Mmode)); extern int store_multiple_operation PARAMS ((rtx, Mmode));
#if defined TREE_CODE #if defined TREE_CODE
extern rtx arm_function_arg PARAMS ((CUMULATIVE_ARGS *, Mmode, tree, int)); extern rtx arm_function_arg PARAMS ((CUMULATIVE_ARGS *, Mmode, tree, int));
extern void arm_init_cumulative_args PARAMS ((CUMULATIVE_ARGS *, tree, rtx, int)); extern void arm_init_cumulative_args PARAMS ((CUMULATIVE_ARGS *, tree, rtx, int));
......
/* Routines for GCC for ARM/pe. /* Routines for GCC for ARM/pe.
Copyright (C) 1995, 1996 Free Software Foundation, Inc. Copyright (C) 1995, 1996, 2000 Free Software Foundation, Inc.
Contributed by Doug Evans (dje@cygnus.com). Contributed by Doug Evans (dje@cygnus.com).
This file is part of GNU CC. This file is part of GNU CC.
...@@ -28,6 +28,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -28,6 +28,7 @@ Boston, MA 02111-1307, USA. */
#include "tree.h" #include "tree.h"
#include "expr.h" #include "expr.h"
#include "toplev.h" #include "toplev.h"
#include "arm-protos.h"
extern int current_function_anonymous_args; extern int current_function_anonymous_args;
......
/* Definitions of target machine for GNU compiler, for ARM with PE obj format. /* Definitions of target machine for GNU compiler, for ARM with PE obj format.
Copyright (C) 1995, 1996, 1999 Free Software Foundation, Inc. Copyright (C) 1995, 1996, 1999, 2000 Free Software Foundation, Inc.
Contributed by Doug Evans (dje@cygnus.com). Contributed by Doug Evans (dje@cygnus.com).
This file is part of GNU CC. This file is part of GNU CC.
...@@ -44,18 +44,22 @@ Boston, MA 02111-1307, USA. */ ...@@ -44,18 +44,22 @@ Boston, MA 02111-1307, USA. */
/* Experimental addition for pr 7885. /* Experimental addition for pr 7885.
Ignore dllimport for functions. */ Ignore dllimport for functions. */
#define TARGET_NOP_FUN_DLLIMPORT (target_flags & 0x20000) #define TARGET_FLAG_NOP_FUN (1 << 24)
#undef TARGET_NOP_FUN_DLLIMPORT
#define TARGET_NOP_FUN_DLLIMPORT (target_flags & TARGET_FLAG_NOP_FUN)
#undef SUBTARGET_SWITCHES #undef SUBTARGET_SWITCHES
#define SUBTARGET_SWITCHES \ #define SUBTARGET_SWITCHES \
{ "nop-fun-dllimport", 0x20000, "Ignore dllimport attribute for functions" }, \ { "nop-fun-dllimport", TARGET_FLAG_NOP_FUN, "Ignore dllimport attribute for functions" }, \
{ "no-nop-fun-dllimport", -0x20000, "" }, { "no-nop-fun-dllimport", - TARGET_FLAG_NOP_FUN, "" },
#undef TARGET_DEFAULT #undef TARGET_DEFAULT
#define TARGET_DEFAULT (ARM_FLAG_SOFT_FLOAT + 0x20000) #define TARGET_DEFAULT (ARM_FLAG_SOFT_FLOAT | TARGET_FLAG_NOP_FUN)
#undef WCHAR_TYPE #undef WCHAR_TYPE
#define WCHAR_TYPE "short unsigned int" #define WCHAR_TYPE "short unsigned int"
#undef WCHAR_TYPE_SIZE #undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE 16 #define WCHAR_TYPE_SIZE 16
...@@ -91,19 +95,10 @@ Boston, MA 02111-1307, USA. */ ...@@ -91,19 +95,10 @@ Boston, MA 02111-1307, USA. */
The attributes in ATTRIBUTES have previously been assigned to DECL. */ The attributes in ATTRIBUTES have previously been assigned to DECL. */
#undef VALID_MACHINE_DECL_ATTRIBUTE #undef VALID_MACHINE_DECL_ATTRIBUTE
#define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, IDENTIFIER, ARGS) \ #define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, IDENTIFIER, ARGS) \
arm_pe_valid_machine_decl_attribute (DECL, ATTRIBUTES, IDENTIFIER, ARGS) arm_pe_valid_machine_decl_attribute (DECL, ATTRIBUTES, IDENTIFIER, ARGS)
#if 0 /* Needed when we tried type attributes. */
/* A C expression whose value is zero if the attributes on
TYPE1 and TYPE2 are incompatible, one if they are compatible,
and two if they are nearly compatible (which causes a warning to be
generated). */
#define COMP_TYPE_ATTRIBUTES(TYPE1, TYPE2) \
arm_pe_comp_type_attributes ((TYPE1), (TYPE2))
#endif
#define MERGE_MACHINE_DECL_ATTRIBUTES(OLD, NEW) \ #define MERGE_MACHINE_DECL_ATTRIBUTES(OLD, NEW) \
arm_pe_merge_machine_decl_attributes ((OLD), (NEW)) arm_pe_merge_machine_decl_attributes ((OLD), (NEW))
/* In addition to the stuff done in arm.h, we must mark dll symbols specially. /* In addition to the stuff done in arm.h, we must mark dll symbols specially.
Definitions of dllexport'd objects install some info in the .drectve Definitions of dllexport'd objects install some info in the .drectve
...@@ -114,7 +109,7 @@ arm_pe_merge_machine_decl_attributes ((OLD), (NEW)) ...@@ -114,7 +109,7 @@ arm_pe_merge_machine_decl_attributes ((OLD), (NEW))
Note that we can be called twice on the same decl. */ Note that we can be called twice on the same decl. */
#undef ENCODE_SECTION_INFO #undef ENCODE_SECTION_INFO
#define ENCODE_SECTION_INFO(DECL) \ #define ENCODE_SECTION_INFO(DECL) \
arm_pe_encode_section_info (DECL) arm_pe_encode_section_info (DECL)
/* Used to implement dllexport overriding dllimport semantics. It's also used /* Used to implement dllexport overriding dllimport semantics. It's also used
to handle vtables - the first pass won't do anything because to handle vtables - the first pass won't do anything because
...@@ -146,7 +141,7 @@ arm_pe_encode_section_info (DECL) ...@@ -146,7 +141,7 @@ arm_pe_encode_section_info (DECL)
#define UNIQUE_SECTION_P(DECL) DECL_ONE_ONLY (DECL) #define UNIQUE_SECTION_P(DECL) DECL_ONE_ONLY (DECL)
#define UNIQUE_SECTION(DECL,RELOC) arm_pe_unique_section (DECL, RELOC) #define UNIQUE_SECTION(DECL, RELOC) arm_pe_unique_section (DECL, RELOC)
#define SUPPORTS_ONE_ONLY 1 #define SUPPORTS_ONE_ONLY 1
...@@ -156,87 +151,97 @@ arm_pe_encode_section_info (DECL) ...@@ -156,87 +151,97 @@ arm_pe_encode_section_info (DECL)
define this macro in such cases. */ define this macro in such cases. */
#undef ASM_OUTPUT_SECTION_NAME #undef ASM_OUTPUT_SECTION_NAME
#define ASM_OUTPUT_SECTION_NAME(STREAM, DECL, NAME, RELOC) \ #define ASM_OUTPUT_SECTION_NAME(STREAM, DECL, NAME, RELOC) \
do { \ do \
if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL) \ { \
fprintf (STREAM, "\t.section %s,\"x\"\n", (NAME)); \ if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL) \
else if ((DECL) && DECL_READONLY_SECTION (DECL, RELOC)) \ fprintf (STREAM, "\t.section %s,\"x\"\n", (NAME)); \
fprintf (STREAM, "\t.section %s,\"\"\n", (NAME)); \ else if ((DECL) && DECL_READONLY_SECTION (DECL, RELOC)) \
else \ fprintf (STREAM, "\t.section %s,\"\"\n", (NAME)); \
fprintf (STREAM, "\t.section %s,\"w\"\n", (NAME)); \ else \
/* Functions may have been compiled at various levels of \ fprintf (STREAM, "\t.section %s,\"w\"\n", (NAME)); \
optimization so we can't use `same_size' here. Instead, \ /* Functions may have been compiled at various levels of \
have the linker pick one. */ \ optimization so we can't use `same_size' here. \
if ((DECL) && DECL_ONE_ONLY (DECL)) \ Instead, have the linker pick one. */ \
fprintf (STREAM, "\t.linkonce %s\n", \ if ((DECL) && DECL_ONE_ONLY (DECL)) \
TREE_CODE (DECL) == FUNCTION_DECL \ fprintf (STREAM, "\t.linkonce %s\n", \
? "discard" : "same_size"); \ TREE_CODE (DECL) == FUNCTION_DECL \
} while (0) ? "discard" : "same_size"); \
} \
while (0)
/* This outputs a lot of .req's to define alias for various registers. /* This outputs a lot of .req's to define alias for various registers.
Let's try to avoid this. */ Let's try to avoid this. */
#undef ASM_FILE_START #undef ASM_FILE_START
#define ASM_FILE_START(STREAM) \ #define ASM_FILE_START(STREAM) \
do { \ do \
extern char * version_string; \ { \
fprintf (STREAM, "%s Generated by gcc %s for ARM/pe\n", \ extern char * version_string; \
ASM_COMMENT_START, version_string); \ asm_fprintf (STREAM, "%@ Generated by gcc %s for ARM/pe\n",\
output_file_directive ((STREAM), main_input_filename); \ version_string); \
} while (0) output_file_directive ((STREAM), main_input_filename); \
} \
while (0)
/* Output a reference to a label. */ /* Output a reference to a label. */
#undef ASM_OUTPUT_LABELREF #undef ASM_OUTPUT_LABELREF
#define ASM_OUTPUT_LABELREF(STREAM, NAME) \ #define ASM_OUTPUT_LABELREF(STREAM, NAME) \
fprintf (STREAM, "%s%s", USER_LABEL_PREFIX, ARM_STRIP_NAME_ENCODING (NAME)) fprintf (STREAM, "%s%s", USER_LABEL_PREFIX, ARM_STRIP_NAME_ENCODING (NAME))
/* Output a function definition label. */ /* Output a function definition label. */
#undef ASM_DECLARE_FUNCTION_NAME #undef ASM_DECLARE_FUNCTION_NAME
#define ASM_DECLARE_FUNCTION_NAME(STREAM, NAME, DECL) \ #define ASM_DECLARE_FUNCTION_NAME(STREAM, NAME, DECL) \
do { \ do \
if (arm_dllexport_name_p (NAME)) \
{ \ { \
drectve_section (); \ if (arm_dllexport_name_p (NAME)) \
fprintf (STREAM, "\t.ascii \" -export:%s\"\n", \ { \
ARM_STRIP_NAME_ENCODING (NAME)); \ drectve_section (); \
function_section (DECL); \ fprintf (STREAM, "\t.ascii \" -export:%s\"\n",\
ARM_STRIP_NAME_ENCODING (NAME)); \
function_section (DECL); \
} \
if (TARGET_POKE_FUNCTION_NAME) \
arm_poke_function_name ((STREAM), (NAME)); \
ASM_OUTPUT_LABEL ((STREAM), (NAME)); \
} \ } \
if (TARGET_POKE_FUNCTION_NAME) \ while (0)
arm_poke_function_name ((STREAM), (NAME)); \
ASM_OUTPUT_LABEL ((STREAM), (NAME)); \
} while (0)
/* Output a common block. */ /* Output a common block. */
#undef ASM_OUTPUT_COMMON #undef ASM_OUTPUT_COMMON
#define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \ #define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \
do { \ do \
if (arm_dllexport_name_p (NAME)) \
{ \
drectve_section (); \
fprintf ((STREAM), "\t.ascii \" -export:%s\"\n", \
ARM_STRIP_NAME_ENCODING (NAME)); \
} \
if (! arm_dllimport_name_p (NAME)) \
{ \ { \
fprintf ((STREAM), "\t.comm\t"); \ if (arm_dllexport_name_p (NAME)) \
assemble_name ((STREAM), (NAME)); \ { \
fprintf ((STREAM), ", %d\t%s %d\n", \ drectve_section (); \
(ROUNDED), ASM_COMMENT_START, (SIZE)); \ fprintf ((STREAM), "\t.ascii \" -export:%s\"\n",\
ARM_STRIP_NAME_ENCODING (NAME)); \
} \
if (! arm_dllimport_name_p (NAME)) \
{ \
fprintf ((STREAM), "\t.comm\t"); \
assemble_name ((STREAM), (NAME)); \
asm_fprintf ((STREAM), ", %d\t%@ %d\n", \
(ROUNDED), (SIZE)); \
} \
} \ } \
} while (0) while (0)
/* Output the label for an initialized variable. */ /* Output the label for an initialized variable. */
#undef ASM_DECLARE_OBJECT_NAME #undef ASM_DECLARE_OBJECT_NAME
#define ASM_DECLARE_OBJECT_NAME(STREAM, NAME, DECL) \ #define ASM_DECLARE_OBJECT_NAME(STREAM, NAME, DECL) \
do { \ do \
if (arm_dllexport_name_p (NAME)) \
{ \ { \
enum in_section save_section = in_section; \ if (arm_dllexport_name_p (NAME)) \
drectve_section (); \ { \
fprintf (STREAM, "\t.ascii \" -export:%s\"\n", \ enum in_section save_section = in_section; \
ARM_STRIP_NAME_ENCODING (NAME)); \ drectve_section (); \
switch_to_section (save_section, (DECL)); \ fprintf (STREAM, "\t.ascii \" -export:%s\"\n",\
ARM_STRIP_NAME_ENCODING (NAME)); \
switch_to_section (save_section, (DECL)); \
} \
ASM_OUTPUT_LABEL ((STREAM), (NAME)); \
} \ } \
ASM_OUTPUT_LABEL ((STREAM), (NAME)); \ while (0)
} while (0)
/* Support the ctors/dtors and other sections. */ /* Support the ctors/dtors and other sections. */
...@@ -272,21 +277,21 @@ drectve_section () \ ...@@ -272,21 +277,21 @@ drectve_section () \
The problem is that we want to temporarily switch sections in The problem is that we want to temporarily switch sections in
ASM_DECLARE_OBJECT_NAME and then switch back to the original section ASM_DECLARE_OBJECT_NAME and then switch back to the original section
afterwards. */ afterwards. */
#define SWITCH_TO_SECTION_FUNCTION \ #define SWITCH_TO_SECTION_FUNCTION \
void \ void \
switch_to_section (section, decl) \ switch_to_section (section, decl) \
enum in_section section; \ enum in_section section; \
tree decl; \ tree decl; \
{ \ { \
switch (section) \ switch (section) \
{ \ { \
case in_text: text_section (); break; \ case in_text: text_section (); break; \
case in_data: data_section (); break; \ case in_data: data_section (); break; \
case in_named: named_section (decl, NULL, 0); break; \ case in_named: named_section (decl, NULL, 0); break; \
case in_rdata: rdata_section (); break; \ case in_rdata: rdata_section (); break; \
case in_ctors: ctors_section (); break; \ case in_ctors: ctors_section (); break; \
case in_dtors: dtors_section (); break; \ case in_dtors: dtors_section (); break; \
case in_drectve: drectve_section (); break; \ case in_drectve: drectve_section (); break; \
default: abort (); break; \ default: abort (); break; \
} \ } \
} }
CROSS_LIBGCC1 = libgcc1-asm.a CROSS_LIBGCC1 = libgcc1-asm.a
LIB1ASMSRC = arm/lib1funcs.asm LIB1ASMSRC = arm/lib1funcs.asm
LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_tls LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_tls _call_via_rX
# We want fine grained libraries, so use the new code to build the # We want fine grained libraries, so use the new code to build the
# floating point emulation libraries. # floating point emulation libraries.
...@@ -21,13 +21,51 @@ dp-bit.c: $(srcdir)/config/fp-bit.c ...@@ -21,13 +21,51 @@ dp-bit.c: $(srcdir)/config/fp-bit.c
echo '#endif' >> dp-bit.c echo '#endif' >> dp-bit.c
cat $(srcdir)/config/fp-bit.c >> dp-bit.c cat $(srcdir)/config/fp-bit.c >> dp-bit.c
# MULTILIB_OPTIONS = mlittle-endian/mbig-endian mhard-float/msoft-float mapcs-32/mapcs-26 fno-leading-underscore/fleading-underscore # MULTILIB_OPTIONS = mlittle-endian/mbig-endian
# MULTILIB_DIRNAMES = le be fpu soft 32bit 26bit elf under # MULTILIB_DIRNAMES = le be
# MULTILIB_EXCEPTIONS = # MULTILIB_EXCEPTIONS =
# MULTILIB_MATCHES = # MULTILIB_MATCHES = mbig-endian=mbe mlittle-endian=mle
#
# MULTILIB_OPTIONS += mhard-float/msoft-float
# MULTILIB_DIRNAMES += fpu soft
#
# MULTILIB_OPTIONS += mapcs-32/mapcs-26
# MULTILIB_DIRNAMES += 32bit 26bit
#
# MULTILIB_OPTIONS += mno-thumb-interwork/mthumb-interwork
# MULTILIB_DIRNAMES += normal interwork
# MULTILIB_EXCEPTIONS += *mapcs-26/*mthumb-interwork*
#
# MULTILIB_OPTIONS += fno-leading-underscore/fleading-underscore
# MULTILIB_DIRNAMES += elf under
#
# MULTILIB_OPTIONS += mcpu=arm7
# MULTILIB_DIRNAMES += nofmult
# MULTILIB_EXCEPTIONS += *mthumb-interwork*/*mcpu=arm7*
# # We have to match all the arm cpu variants which do not have the
# # multiply instruction and treat them as if the user had specified
# # -mcpu=arm7. Note that in the following the ? is interpreted as
# # an = for the purposes of matching command line options.
# # FIXME: There ought to be a better way to do this.
# MULTILIB_MATCHES += mcpu?arm7=mcpu?arm7d
# MULTILIB_MATCHES += mcpu?arm7=mcpu?arm7di
# MULTILIB_MATCHES += mcpu?arm7=mcpu?arm70
# MULTILIB_MATCHES += mcpu?arm7=mcpu?arm700
# MULTILIB_MATCHES += mcpu?arm7=mcpu?arm700i
# MULTILIB_MATCHES += mcpu?arm7=mcpu?arm710
# MULTILIB_MATCHES += mcpu?arm7=mcpu?arm710c
# MULTILIB_MATCHES += mcpu?arm7=mcpu?arm7100
# MULTILIB_MATCHES += mcpu?arm7=mcpu?arm7500
# MULTILIB_MATCHES += mcpu?arm7=mcpu?arm7500fe
# MULTILIB_MATCHES += mcpu?arm7=mcpu?arm6
# MULTILIB_MATCHES += mcpu?arm7=mcpu?arm60
# MULTILIB_MATCHES += mcpu?arm7=mcpu?arm600
# MULTILIB_MATCHES += mcpu?arm7=mcpu?arm610
# MULTILIB_MATCHES += mcpu?arm7=mcpu?arm620
#
# EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o # EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o
# LIBGCC = stmp-multilib # LIBGCC = stmp-multilib
# INSTALL_LIBGCC = install-multilib # INSTALL_LIBGCC = install-multilib
# If EXTRA_MULTILIB_PARTS is not defined above then define EXTRA_PARTS here # If EXTRA_MULTILIB_PARTS is not defined above then define EXTRA_PARTS here
EXTRA_PARTS = crtbegin.o crtend.o EXTRA_PARTS = crtbegin.o crtend.o
......
CROSS_LIBGCC1 = libgcc1-asm.a CROSS_LIBGCC1 = libgcc1-asm.a
LIB1ASMSRC = arm/lib1funcs.asm LIB1ASMSRC = arm/lib1funcs.asm
LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_tls LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_tls _call_via_rX
# We want fine grained libraries, so use the new code to build the # We want fine grained libraries, so use the new code to build the
# floating point emulation libraries. # floating point emulation libraries.
...@@ -22,9 +22,11 @@ dp-bit.c: $(srcdir)/config/fp-bit.c ...@@ -22,9 +22,11 @@ dp-bit.c: $(srcdir)/config/fp-bit.c
cat $(srcdir)/config/fp-bit.c >> dp-bit.c cat $(srcdir)/config/fp-bit.c >> dp-bit.c
# Avoid building a duplicate set of libraries for the default endian-ness. # Avoid building a duplicate set of libraries for the default endian-ness.
MULTILIB_OPTIONS = mlittle-endian/mbig-endian mhard-float MULTILIB_OPTIONS = mlittle-endian/mbig-endian mhard-float
MULTILIB_DIRNAMES = le be fpu MULTILIB_DIRNAMES = le be fpu
MULTILIB_MATCHES = MULTILIB_MATCHES =
LIBGCC = stmp-multilib LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib INSTALL_LIBGCC = install-multilib
...@@ -141,6 +141,13 @@ extern int arm_structure_size_boundary; ...@@ -141,6 +141,13 @@ extern int arm_structure_size_boundary;
dwarf2.out. */ dwarf2.out. */
#define UNALIGNED_WORD_ASM_OP ".4byte" #define UNALIGNED_WORD_ASM_OP ".4byte"
#define ASM_OUTPUT_DWARF2_ADDR_CONST(FILE,ADDR) \
if (((ADDR)[0] == '.') && ((ADDR)[1] == 'L')) \
fprintf ((FILE), "\t%s\t%s", UNALIGNED_WORD_ASM_OP, (ADDR)); \
else \
fprintf ((FILE), "\t%s\t%s", \
UNALIGNED_WORD_ASM_OP, (ADDR))
#define ASM_OUTPUT_DWARF_ADDR_CONST(FILE,RTX) \ #define ASM_OUTPUT_DWARF_ADDR_CONST(FILE,RTX) \
do \ do \
{ \ { \
......
/* Output routines for GCC for ARM/Thumb /* Output routines for GCC for ARM/Thumb
Copyright (C) 1996 Cygnus Software Technologies Ltd Copyright (C) 1996, 2000 Cygnus Software Technologies Ltd
The basis of this contribution was generated by The basis of this contribution was generated by
Richard Earnshaw, Advanced RISC Machines Ltd Richard Earnshaw, Advanced RISC Machines Ltd
...@@ -36,6 +36,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -36,6 +36,7 @@ Boston, MA 02111-1307, USA. */
#include "insn-config.h" #include "insn-config.h"
#include "recog.h" #include "recog.h"
#include "toplev.h" #include "toplev.h"
#include "thumb-protos.h"
int current_function_anonymous_args = 0; int current_function_anonymous_args = 0;
...@@ -492,8 +493,7 @@ dump_table (scan) ...@@ -492,8 +493,7 @@ dump_table (scan)
} }
/* Non zero if the src operand needs to be fixed up */ /* Non zero if the src operand needs to be fixed up */
static static int
int
fixit (src, mode) fixit (src, mode)
rtx src; rtx src;
enum machine_mode mode; enum machine_mode mode;
...@@ -513,8 +513,7 @@ fixit (src, mode) ...@@ -513,8 +513,7 @@ fixit (src, mode)
&& CONSTANT_POOL_ADDRESS_P (XEXP (src, 0)))); && CONSTANT_POOL_ADDRESS_P (XEXP (src, 0))));
} }
/* Find the last barrier less than MAX_COUNT bytes from FROM, or create one. */ /* Find the last barrier less than MAX_COUNT bytes from FROM, or create one. */
#define MAX_COUNT_SI 1000 #define MAX_COUNT_SI 1000
static rtx static rtx
...@@ -530,7 +529,7 @@ find_barrier (from) ...@@ -530,7 +529,7 @@ find_barrier (from)
if (GET_CODE (from) == BARRIER) if (GET_CODE (from) == BARRIER)
return from; return from;
/* Count the length of this insn */ /* Count the length of this insn. */
if (GET_CODE (from) == INSN if (GET_CODE (from) == INSN
&& GET_CODE (PATTERN (from)) == SET && GET_CODE (PATTERN (from)) == SET
&& CONSTANT_P (SET_SRC (PATTERN (from))) && CONSTANT_P (SET_SRC (PATTERN (from)))
...@@ -543,7 +542,7 @@ find_barrier (from) ...@@ -543,7 +542,7 @@ find_barrier (from)
} }
/* We didn't find a barrier in time to /* We didn't find a barrier in time to
dump our stuff, so we'll make one */ dump our stuff, so we'll make one. */
label = gen_label_rtx (); label = gen_label_rtx ();
if (from) if (from)
...@@ -551,21 +550,21 @@ find_barrier (from) ...@@ -551,21 +550,21 @@ find_barrier (from)
else else
from = get_last_insn (); from = get_last_insn ();
/* Walk back to be just before any jump */ /* Walk back to be just before any jump. */
while (GET_CODE (from) == JUMP_INSN while (GET_CODE (from) == JUMP_INSN
|| GET_CODE (from) == NOTE || GET_CODE (from) == NOTE
|| GET_CODE (from) == CODE_LABEL) || GET_CODE (from) == CODE_LABEL)
from = PREV_INSN (from); from = PREV_INSN (from);
from = emit_jump_insn_after (gen_jump (label), from); from = emit_jump_insn_after (gen_jump (label), from);
JUMP_LABEL (from) = label; JUMP_LABEL (from) = label;
found_barrier = emit_barrier_after (from); found_barrier = emit_barrier_after (from);
emit_label_after (label, found_barrier); emit_label_after (label, found_barrier);
return found_barrier; return found_barrier;
} }
/* Non zero if the insn is a move instruction which needs to be fixed. */ /* Non zero if the insn is a move instruction which needs to be fixed. */
static int static int
broken_move (insn) broken_move (insn)
rtx insn; rtx insn;
...@@ -628,16 +627,16 @@ thumb_reorg (first) ...@@ -628,16 +627,16 @@ thumb_reorg (first)
if (broken_move (insn)) if (broken_move (insn))
{ {
/* This is a broken move instruction, scan ahead looking for /* This is a broken move instruction, scan ahead looking for
a barrier to stick the constant table behind */ a barrier to stick the constant table behind. */
rtx scan; rtx scan;
rtx barrier = find_barrier (insn); rtx barrier = find_barrier (insn);
/* Now find all the moves between the points and modify them */ /* Now find all the moves between the points and modify them. */
for (scan = insn; scan != barrier; scan = NEXT_INSN (scan)) for (scan = insn; scan != barrier; scan = NEXT_INSN (scan))
{ {
if (broken_move (scan)) if (broken_move (scan))
{ {
/* This is a broken move instruction, add it to the pool */ /* This is a broken move instruction, add it to the pool. */
rtx pat = PATTERN (scan); rtx pat = PATTERN (scan);
rtx src = SET_SRC (pat); rtx src = SET_SRC (pat);
rtx dst = SET_DEST (pat); rtx dst = SET_DEST (pat);
...@@ -649,7 +648,7 @@ thumb_reorg (first) ...@@ -649,7 +648,7 @@ thumb_reorg (first)
/* If this is an HImode constant load, convert it into /* If this is an HImode constant load, convert it into
an SImode constant load. Since the register is always an SImode constant load. Since the register is always
32 bits this is safe. We have to do this, since the 32 bits this is safe. We have to do this, since the
load pc-relative instruction only does a 32-bit load. */ load pc-relative instruction only does a 32-bit load. */
if (mode == HImode) if (mode == HImode)
{ {
mode = SImode; mode = SImode;
...@@ -668,12 +667,12 @@ thumb_reorg (first) ...@@ -668,12 +667,12 @@ thumb_reorg (first)
/* Build a jump insn wrapper around the move instead /* Build a jump insn wrapper around the move instead
of an ordinary insn, because we want to have room for of an ordinary insn, because we want to have room for
the target label rtx in fld[7], which an ordinary the target label rtx in fld[7], which an ordinary
insn doesn't have. */ insn doesn't have. */
newinsn = emit_jump_insn_after (gen_rtx (SET, VOIDmode, newinsn = emit_jump_insn_after (gen_rtx (SET, VOIDmode,
dst, newsrc), scan); dst, newsrc), scan);
JUMP_LABEL (newinsn) = pool_vector_label; JUMP_LABEL (newinsn) = pool_vector_label;
/* But it's still an ordinary insn */ /* But it's still an ordinary insn. */
PUT_CODE (newinsn, INSN); PUT_CODE (newinsn, INSN);
/* If debugging information is going to be emitted /* If debugging information is going to be emitted
...@@ -692,8 +691,7 @@ thumb_reorg (first) ...@@ -692,8 +691,7 @@ thumb_reorg (first)
pool will be marked. Only necessary if debugging pool will be marked. Only necessary if debugging
info is being emitted. Only necessary for info is being emitted. Only necessary for
references to memory whose address is given by a references to memory whose address is given by a
symbol. */ symbol. */
if (optimize > 0 if (optimize > 0
&& flag_expensive_optimizations && flag_expensive_optimizations
&& write_symbols != NO_DEBUG && write_symbols != NO_DEBUG
...@@ -702,19 +700,19 @@ thumb_reorg (first) ...@@ -702,19 +700,19 @@ thumb_reorg (first)
replace_symbols_in_block replace_symbols_in_block
(DECL_INITIAL (current_function_decl), src, newsrc); (DECL_INITIAL (current_function_decl), src, newsrc);
/* Kill old insn */ /* Kill old insn. */
delete_insn (scan); delete_insn (scan);
scan = newinsn; scan = newinsn;
} }
} }
dump_table (barrier); dump_table (barrier);
} }
} }
} }
/* Routines for generating rtl */ /* Routines for generating rtl. */
void void
thumb_expand_movstrqi (operands) thumb_expand_movstrqi (operands)
rtx *operands; rtx *operands;
...@@ -888,7 +886,7 @@ thumb_exit (f, reg_containing_return_addr) ...@@ -888,7 +886,7 @@ thumb_exit (f, reg_containing_return_addr)
pops_needed += 2; pops_needed += 2;
} }
/* If there is nothing to pop then just emit the BX instruction and return.*/ /* If there is nothing to pop then just emit the BX instruction and return. */
if (pops_needed == 0) if (pops_needed == 0)
{ {
asm_fprintf (f, "\tbx\t%s\n", reg_names [reg_containing_return_addr]); asm_fprintf (f, "\tbx\t%s\n", reg_names [reg_containing_return_addr]);
...@@ -1355,7 +1353,7 @@ thumb_function_prologue (f, frame_size) ...@@ -1355,7 +1353,7 @@ thumb_function_prologue (f, frame_size)
if (TARGET_BACKTRACE) if (TARGET_BACKTRACE)
{ {
char * name; const char * name;
int offset; int offset;
int work_register = 0; int work_register = 0;
...@@ -1396,7 +1394,7 @@ thumb_function_prologue (f, frame_size) ...@@ -1396,7 +1394,7 @@ thumb_function_prologue (f, frame_size)
break; break;
} }
name = reg_names[ work_register ]; name = reg_names [work_register];
asm_fprintf (f, "\tsub\tsp, sp, #16\t@ Create stack backtrace structure\n"); asm_fprintf (f, "\tsub\tsp, sp, #16\t@ Create stack backtrace structure\n");
...@@ -1722,7 +1720,7 @@ thumb_function_epilogue (f, frame_size) ...@@ -1722,7 +1720,7 @@ thumb_function_epilogue (f, frame_size)
#endif #endif
} }
/* The bits which aren't usefully expanded as rtl. */ /* The bits which aren't usefully expanded as rtl. */
char * char *
thumb_unexpanded_epilogue () thumb_unexpanded_epilogue ()
{ {
...@@ -1771,14 +1769,10 @@ thumb_unexpanded_epilogue () ...@@ -1771,14 +1769,10 @@ thumb_unexpanded_epilogue ()
the register is used to hold a return value. */ the register is used to hold a return value. */
if (current_function_return_rtx != 0) if (current_function_return_rtx != 0)
{ mode = GET_MODE (current_function_return_rtx);
mode = GET_MODE (current_function_return_rtx);
}
else else
#endif #endif
{ mode = DECL_MODE (DECL_RESULT (current_function_decl));
mode = DECL_MODE (DECL_RESULT (current_function_decl));
}
size = GET_MODE_SIZE (mode); size = GET_MODE_SIZE (mode);
...@@ -1787,11 +1781,8 @@ thumb_unexpanded_epilogue () ...@@ -1787,11 +1781,8 @@ thumb_unexpanded_epilogue ()
mask |= 1 << 3; mask |= 1 << 3;
if (mask == 0) if (mask == 0)
{ /* Oh dear! We have no low registers into which we can pop high registers! */
/* Oh dear! We have no low registers into which we can pop high registers! */ fatal ("No low registers available for popping high registers");
fatal ("No low registers available for popping high registers");
}
for (next_hi_reg = 8; next_hi_reg < 13; next_hi_reg++) for (next_hi_reg = 8; next_hi_reg < 13; next_hi_reg++)
if (regs_ever_live[next_hi_reg] && ! call_used_regs[next_hi_reg] if (regs_ever_live[next_hi_reg] && ! call_used_regs[next_hi_reg]
...@@ -1835,13 +1826,10 @@ thumb_unexpanded_epilogue () ...@@ -1835,13 +1826,10 @@ thumb_unexpanded_epilogue ()
had_to_push_lr = (live_regs_mask || ! leaf_function || far_jump_used_p()); had_to_push_lr = (live_regs_mask || ! leaf_function || far_jump_used_p());
if (TARGET_BACKTRACE && ((live_regs_mask & 0xFF) == 0) && regs_ever_live[ ARG_4_REGISTER ] != 0) if (TARGET_BACKTRACE && ((live_regs_mask & 0xFF) == 0) && regs_ever_live[ ARG_4_REGISTER ] != 0)
{ /* The stack backtrace structure creation code had to
/* The stack backtrace structure creation code had to push R7 in order to get a work register, so we pop
push R7 in order to get a work register, so we pop it now. */
it now. */ live_regs_mask |= (1 << WORK_REGISTER);
live_regs_mask |= (1 << WORK_REGISTER);
}
if (current_function_pretend_args_size == 0 || TARGET_BACKTRACE) if (current_function_pretend_args_size == 0 || TARGET_BACKTRACE)
{ {
...@@ -1852,7 +1840,6 @@ thumb_unexpanded_epilogue () ...@@ -1852,7 +1840,6 @@ thumb_unexpanded_epilogue ()
/* Either no argument registers were pushed or a backtrace /* Either no argument registers were pushed or a backtrace
structure was created which includes an adjusted stack structure was created which includes an adjusted stack
pointer, so just pop everything. */ pointer, so just pop everything. */
if (live_regs_mask) if (live_regs_mask)
thumb_pushpop (asm_out_file, live_regs_mask, FALSE); thumb_pushpop (asm_out_file, live_regs_mask, FALSE);
...@@ -1860,7 +1847,6 @@ thumb_unexpanded_epilogue () ...@@ -1860,7 +1847,6 @@ thumb_unexpanded_epilogue ()
PC or it is was kept in LR for the entire function or PC or it is was kept in LR for the entire function or
it is still on the stack because we do not want to it is still on the stack because we do not want to
return by doing a pop {pc}. */ return by doing a pop {pc}. */
if ((live_regs_mask & (1 << PROGRAM_COUNTER)) == 0) if ((live_regs_mask & (1 << PROGRAM_COUNTER)) == 0)
thumb_exit (asm_out_file, thumb_exit (asm_out_file,
(had_to_push_lr (had_to_push_lr
...@@ -1876,10 +1862,8 @@ thumb_unexpanded_epilogue () ...@@ -1876,10 +1862,8 @@ thumb_unexpanded_epilogue ()
thumb_pushpop (asm_out_file, live_regs_mask, FALSE); thumb_pushpop (asm_out_file, live_regs_mask, FALSE);
if (had_to_push_lr) if (had_to_push_lr)
{ /* Get the return address into a temporary register. */
/* Get the return address into a temporary register. */ thumb_pushpop (asm_out_file, 1 << ARG_4_REGISTER, 0);
thumb_pushpop (asm_out_file, 1 << ARG_4_REGISTER, 0);
}
/* Remove the argument registers that were pushed onto the stack. */ /* Remove the argument registers that were pushed onto the stack. */
asm_fprintf (asm_out_file, "\tadd\t%s, %s, #%d\n", asm_fprintf (asm_out_file, "\tadd\t%s, %s, #%d\n",
......
...@@ -1296,37 +1296,5 @@ extern int making_const_table; ...@@ -1296,37 +1296,5 @@ extern int making_const_table;
/* Options specific to Thumb */ /* Options specific to Thumb */
/* True if a return instruction can be used in this function. */ /* True if a return instruction can be used in this function. */
int thumb_trivial_epilogue ();
#define USE_RETURN (reload_completed && thumb_trivial_epilogue ()) #define USE_RETURN (reload_completed && thumb_trivial_epilogue ())
extern char * thumb_unexpanded_epilogue ();
extern char * output_move_mem_multiple ();
extern char * thumb_load_double_from_address ();
extern char * output_return ();
extern int far_jump_used_p();
extern int is_called_in_ARM_mode ();
extern void thumb_finalize_pic ();
extern void thumb_reorg ();
extern void thumb_override_options ();
extern int is_pic ();
extern int thumb_symbol_mentioned_p ();
extern void thumb_function_prologue ();
extern void thumb_function_epilogue ();
extern void thumb_print_operand ();
extern void thumb_final_prescan_insn ();
extern int thumb_cmp_operand ();
extern void thumb_expand_movstrqi ();
extern void thumb_expand_prologue ();
extern void thumb_expand_epilogue ();
extern int arm_valid_machine_decl_attribute ();
extern void thumb_init_expanders ();
#ifndef RTX_CODE
struct rtx_def;
#define Rtx struct rtx_def *
#else
#define Rtx rtx
#endif
extern Rtx thumb_return_addr ();
...@@ -107,6 +107,9 @@ func_ptr __DTOR_END__[1] = { (func_ptr) 0 }; ...@@ -107,6 +107,9 @@ func_ptr __DTOR_END__[1] = { (func_ptr) 0 };
dwarf2.out. */ dwarf2.out. */
#define UNALIGNED_WORD_ASM_OP ".4byte" #define UNALIGNED_WORD_ASM_OP ".4byte"
#define ASM_OUTPUT_DWARF2_ADDR_CONST(FILE,ADDR) \
fprintf ((FILE), "\t%s\t%s", UNALIGNED_WORD_ASM_OP, ADDR)
#define ASM_OUTPUT_DWARF_ADDR_CONST(FILE,RTX) \ #define ASM_OUTPUT_DWARF_ADDR_CONST(FILE,RTX) \
do { \ do { \
fprintf ((FILE), "\t%s\t", UNALIGNED_WORD_ASM_OP); \ fprintf ((FILE), "\t%s\t", UNALIGNED_WORD_ASM_OP); \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment