parent
8f7cbf1635
commit
6cfc7210fa
|
@ -1,3 +1,42 @@
|
|||
Sat Jul 17 14:25:46 1999 Nick Clifton <nickc@cygnus.com>
|
||||
|
||||
* config/arm/aout.h: Reformat for improved readability.
|
||||
|
||||
* config/arm/arm.h: Reformat for improved readability.
|
||||
Replace uses of fprintf with asm_fprintf where appropriate.
|
||||
(ARM_DECLARE_FUNCTION_NAME): New macro: Perform any generic ARM
|
||||
function declaration assembler actions.
|
||||
(NUM_INTS): New macro: Convert from bytes to words.
|
||||
(NUM_REGS): New macro: Compute number of registers required to
|
||||
hold a quanitity of tyep MODE.
|
||||
(NUM_REGS2): New macro: Like NUM_REGS but also copes with BLKmode
|
||||
types.
|
||||
(NUM_ARG_REGS): New macro: The number of argument registers
|
||||
available.
|
||||
(ARG_REGISTER): New macro: Compute the register number of the Nth
|
||||
argument register.
|
||||
(LAST_ARG_REGNUM): New macro: The number of the last argument
|
||||
register.
|
||||
(SP_REGNUM): New macro: Register number of the stack pointer.
|
||||
(FP_REGNUM): New macro: Register number of the frame pointer.
|
||||
(FUNCTION_ARG, FUNCTION_ARG_PARTIAL_NREGS, INIT_CUMULATIVE_AGS,
|
||||
FUNCTION_ARG_ADVANCE, SETUP_INCOMING_VARARGS): Change
|
||||
CUMULATIVE_ARGS so that it counts registers not bytes.
|
||||
|
||||
* config/arm/arm.c: Rename TARGET_THUMB_INTERWORK to
|
||||
TARGET_INTERWORK.
|
||||
Replace uses of fprintf with asm_fprintf where appropriate.
|
||||
(output_ascii_pseudo_op): Replace with version from thumb.c
|
||||
|
||||
* config/arm/coff.h (ASM_FILE_START): Emit ASM_APP_OFF.
|
||||
|
||||
* config/arm/elf.h (CPP_PREDEFINES): Replace with
|
||||
SUBTARGET_CPP_SPEC.
|
||||
(ASM_DECLARE_FUNCTION_NAME): Use ARM_DECLARE_FUNCTION_NAME.
|
||||
(ASM_FILE_START): Emit ASM_APP_OFF.
|
||||
|
||||
|
||||
|
||||
Fri Jul 16 13:48:09 1999 Jeffrey A Law (law@cygnus.com)
|
||||
|
||||
* pa.c (compute_frame_size): Round frame according to
|
||||
|
|
|
@ -100,7 +100,7 @@ Boston, MA 02111-1307, USA. */
|
|||
/* Arm Assembler barfs on dollars */
|
||||
#define DOLLARS_IN_IDENTIFIERS 0
|
||||
|
||||
#define NO_DOLLAR_IN_LABEL
|
||||
#define NO_DOLLAR_IN_LABEL 1
|
||||
|
||||
/* DBX register number for a given compiler register number */
|
||||
#define DBX_REGISTER_NUMBER(REGNO) (REGNO)
|
||||
|
@ -118,39 +118,48 @@ Boston, MA 02111-1307, USA. */
|
|||
|
||||
/* Output a source filename for the debugger. RISCiX dbx insists that the
|
||||
``desc'' field is set to compiler version number >= 315 (sic). */
|
||||
#define DBX_OUTPUT_MAIN_SOURCE_FILENAME(STREAM,NAME) \
|
||||
do { \
|
||||
fprintf (STREAM, ".stabs "); \
|
||||
output_quoted_string (STREAM, NAME); \
|
||||
fprintf (STREAM, ",%d,0,315,%s\n", N_SO, <ext_label_name[1]); \
|
||||
text_section (); \
|
||||
ASM_OUTPUT_INTERNAL_LABEL (STREAM, "Ltext", 0); \
|
||||
} while (0)
|
||||
#define DBX_OUTPUT_MAIN_SOURCE_FILENAME(STREAM, NAME) \
|
||||
do \
|
||||
{ \
|
||||
fprintf (STREAM, ".stabs "); \
|
||||
output_quoted_string (STREAM, NAME); \
|
||||
fprintf (STREAM, ",%d,0,315,%s\n", N_SO, <ext_label_name[1]); \
|
||||
text_section (); \
|
||||
ASM_OUTPUT_INTERNAL_LABEL (STREAM, "Ltext", 0); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* Output a function label definition. */
|
||||
#ifndef ASM_DECLARE_FUNCTION_NAME
|
||||
#define ASM_DECLARE_FUNCTION_NAME(STREAM,NAME,DECL) \
|
||||
{ \
|
||||
if (TARGET_POKE_FUNCTION_NAME) \
|
||||
arm_poke_function_name ((STREAM), (NAME)); \
|
||||
ASM_OUTPUT_LABEL (STREAM, NAME); \
|
||||
}
|
||||
#define ASM_DECLARE_FUNCTION_NAME(STREAM, NAME, DECL) \
|
||||
do \
|
||||
{ \
|
||||
ARM_DECLARE_FUNCTION_NAME (STREAM, NAME, DECL); \
|
||||
ASM_OUTPUT_LABEL (STREAM, NAME); \
|
||||
} \
|
||||
while (0)
|
||||
#endif
|
||||
|
||||
#ifndef ASM_OUTPUT_LABEL
|
||||
#define ASM_OUTPUT_LABEL(STREAM,NAME) \
|
||||
do { \
|
||||
assemble_name (STREAM,NAME); \
|
||||
fputs (":\n", STREAM); \
|
||||
} while (0)
|
||||
#define ASM_OUTPUT_LABEL(STREAM, NAME) \
|
||||
do \
|
||||
{ \
|
||||
assemble_name (STREAM,NAME); \
|
||||
fputs (":\n", STREAM); \
|
||||
} \
|
||||
while (0)
|
||||
#endif
|
||||
|
||||
/* Output a globalising directive for a label. */
|
||||
#ifndef ASM_GLOBALIZE_LABEL
|
||||
#define ASM_GLOBALIZE_LABEL(STREAM,NAME) \
|
||||
(fprintf (STREAM, "\t.global\t"), \
|
||||
assemble_name (STREAM, NAME), \
|
||||
fputc ('\n',STREAM))
|
||||
#define ASM_GLOBALIZE_LABEL(STREAM, NAME) \
|
||||
do \
|
||||
{ \
|
||||
fprintf (STREAM, "\t.global\t"); \
|
||||
assemble_name (STREAM, NAME); \
|
||||
fputc ('\n',STREAM); \
|
||||
} \
|
||||
while (0)
|
||||
#endif
|
||||
|
||||
/* Make an internal label into a string. */
|
||||
|
@ -159,103 +168,122 @@ do { \
|
|||
sprintf (STRING, "*%s%s%u", LOCAL_LABEL_PREFIX, PREFIX, (unsigned int)(NUM))
|
||||
#endif
|
||||
|
||||
/* Nothing special is done about jump tables */
|
||||
/* #define ASM_OUTPUT_CASE_LABEL(STREAM,PREFIX,NUM,TABLE) */
|
||||
/* #define ASM_OUTPUT_CASE_END(STREAM,NUM,TABLE) */
|
||||
|
||||
/* Construct a private name. */
|
||||
#define ASM_FORMAT_PRIVATE_NAME(OUTVAR,NAME,NUMBER) \
|
||||
#define ASM_FORMAT_PRIVATE_NAME(OUTVAR, NAME, NUMBER) \
|
||||
((OUTVAR) = (char *) alloca (strlen (NAME) + 10), \
|
||||
sprintf ((OUTVAR), "%s.%d", (NAME), (NUMBER)))
|
||||
sprintf (OUTVAR, "%s.%d", NAME, NUMBER))
|
||||
|
||||
/* Output an element of a dispatch table. */
|
||||
#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM,VALUE) \
|
||||
fprintf (STREAM, "\t.word\t%sL%d\n", LOCAL_LABEL_PREFIX, VALUE)
|
||||
#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \
|
||||
asm_fprintf (STREAM, "\t.word\t%LL%d\n", VALUE)
|
||||
|
||||
#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM,BODY,VALUE,REL) \
|
||||
fprintf (STREAM, "\tb\t%sL%d\n", LOCAL_LABEL_PREFIX, (VALUE))
|
||||
#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, BODY, VALUE, REL) \
|
||||
asm_fprintf (STREAM, "\tb\t%LL%d\n", VALUE)
|
||||
|
||||
/* Output various types of constants. For real numbers we output hex, with
|
||||
a comment containing the "human" value, this allows us to pass NaN's which
|
||||
the riscix assembler doesn't understand (it also makes cross-assembling
|
||||
less likely to fail). */
|
||||
|
||||
#define ASM_OUTPUT_LONG_DOUBLE(STREAM,VALUE) \
|
||||
do { char dstr[30]; \
|
||||
long l[3]; \
|
||||
REAL_VALUE_TO_TARGET_LONG_DOUBLE (VALUE, l); \
|
||||
REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr); \
|
||||
fprintf (STREAM, "\t.long 0x%lx,0x%lx,0x%lx\t%s long double %s\n", \
|
||||
l[0], l[1], l[2], ASM_COMMENT_START, dstr); \
|
||||
} while (0)
|
||||
#define ASM_OUTPUT_LONG_DOUBLE(STREAM, VALUE) \
|
||||
do \
|
||||
{ \
|
||||
char dstr[30]; \
|
||||
long l[3]; \
|
||||
REAL_VALUE_TO_TARGET_LONG_DOUBLE (VALUE, l); \
|
||||
REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr); \
|
||||
fprintf (STREAM, "\t.long 0x%lx,0x%lx,0x%lx\t%s long double %s\n", \
|
||||
l[0], l[1], l[2], ASM_COMMENT_START, dstr); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
|
||||
#define ASM_OUTPUT_DOUBLE(STREAM, VALUE) \
|
||||
do { char dstr[30]; \
|
||||
long l[2]; \
|
||||
REAL_VALUE_TO_TARGET_DOUBLE (VALUE, l); \
|
||||
REAL_VALUE_TO_DECIMAL (VALUE, "%.14g", dstr); \
|
||||
fprintf (STREAM, "\t.long 0x%lx, 0x%lx\t%s double %s\n", l[0], \
|
||||
l[1], ASM_COMMENT_START, dstr); \
|
||||
} while (0)
|
||||
#define ASM_OUTPUT_DOUBLE(STREAM, VALUE) \
|
||||
do \
|
||||
{ \
|
||||
char dstr[30]; \
|
||||
long l[2]; \
|
||||
REAL_VALUE_TO_TARGET_DOUBLE (VALUE, l); \
|
||||
REAL_VALUE_TO_DECIMAL (VALUE, "%.14g", dstr); \
|
||||
fprintf (STREAM, "\t.long 0x%lx, 0x%lx\t%s double %s\n", l[0], \
|
||||
l[1], ASM_COMMENT_START, dstr); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define ASM_OUTPUT_FLOAT(STREAM, VALUE) \
|
||||
do { char dstr[30]; \
|
||||
long l; \
|
||||
REAL_VALUE_TO_TARGET_SINGLE (VALUE, l); \
|
||||
REAL_VALUE_TO_DECIMAL (VALUE, "%.7g", dstr); \
|
||||
fprintf (STREAM, "\t.word 0x%lx\t%s float %s\n", l, \
|
||||
ASM_COMMENT_START, dstr); \
|
||||
} while (0);
|
||||
#define ASM_OUTPUT_FLOAT(STREAM, VALUE) \
|
||||
do \
|
||||
{ \
|
||||
char dstr[30]; \
|
||||
long l; \
|
||||
REAL_VALUE_TO_TARGET_SINGLE (VALUE, l); \
|
||||
REAL_VALUE_TO_DECIMAL (VALUE, "%.7g", dstr); \
|
||||
fprintf (STREAM, "\t.word 0x%lx\t%s float %s\n", l, \
|
||||
ASM_COMMENT_START, dstr); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define ASM_OUTPUT_INT(STREAM, EXP) \
|
||||
{ \
|
||||
fprintf (STREAM, "\t.word\t"); \
|
||||
OUTPUT_INT_ADDR_CONST (STREAM, (EXP)); \
|
||||
fputc ('\n', STREAM); \
|
||||
}
|
||||
do \
|
||||
{ \
|
||||
fprintf (STREAM, "\t.word\t"); \
|
||||
OUTPUT_INT_ADDR_CONST (STREAM, EXP); \
|
||||
fputc ('\n', STREAM); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define ASM_OUTPUT_SHORT(STREAM, EXP) \
|
||||
(fprintf (STREAM, "\t.short\t"), \
|
||||
output_addr_const (STREAM, (EXP)), \
|
||||
fputc ('\n', STREAM))
|
||||
#define ASM_OUTPUT_SHORT(STREAM, EXP) \
|
||||
do \
|
||||
{ \
|
||||
fprintf (STREAM, "\t.short\t"); \
|
||||
output_addr_const (STREAM, EXP); \
|
||||
fputc ('\n', STREAM); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define ASM_OUTPUT_CHAR(STREAM, EXP) \
|
||||
(fprintf (STREAM, "\t.byte\t"), \
|
||||
output_addr_const (STREAM, (EXP)), \
|
||||
fputc ('\n', STREAM))
|
||||
#define ASM_OUTPUT_CHAR(STREAM, EXP) \
|
||||
do \
|
||||
{ \
|
||||
fprintf (STREAM, "\t.byte\t"); \
|
||||
output_addr_const (STREAM, EXP); \
|
||||
fputc ('\n', STREAM); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define ASM_OUTPUT_BYTE(STREAM, VALUE) \
|
||||
fprintf (STREAM, "\t.byte\t%d\n", VALUE)
|
||||
|
||||
#define ASM_OUTPUT_ASCII(STREAM, PTR, LEN) \
|
||||
output_ascii_pseudo_op ((STREAM), (unsigned char *)(PTR), (LEN))
|
||||
output_ascii_pseudo_op (STREAM, (unsigned char *)(PTR), LEN)
|
||||
|
||||
/* Output a gap. In fact we fill it with nulls. */
|
||||
#define ASM_OUTPUT_SKIP(STREAM, NBYTES) \
|
||||
fprintf (STREAM, "\t.space\t%d\n", NBYTES)
|
||||
fprintf (STREAM, "\t.space\t%d\n", NBYTES)
|
||||
|
||||
/* Align output to a power of two. Horrible /bin/as. */
|
||||
#ifndef ASM_OUTPUT_ALIGN
|
||||
#define ASM_OUTPUT_ALIGN(STREAM, POWER) \
|
||||
do \
|
||||
{ \
|
||||
register int amount = 1 << (POWER); \
|
||||
\
|
||||
if (amount == 2) \
|
||||
fprintf (STREAM, "\t.even\n"); \
|
||||
else if (amount != 1) \
|
||||
fprintf (STREAM, "\t.align\t%d\n", amount - 4); \
|
||||
} \
|
||||
#define ASM_OUTPUT_ALIGN(STREAM, POWER) \
|
||||
do \
|
||||
{ \
|
||||
register int amount = 1 << (POWER); \
|
||||
\
|
||||
if (amount == 2) \
|
||||
fprintf (STREAM, "\t.even\n"); \
|
||||
else if (amount != 1) \
|
||||
fprintf (STREAM, "\t.align\t%d\n", amount - 4); \
|
||||
} \
|
||||
while (0)
|
||||
#endif
|
||||
|
||||
/* Output a common block */
|
||||
#ifndef ASM_OUTPUT_COMMON
|
||||
#define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \
|
||||
(fprintf (STREAM, "\t.comm\t"), \
|
||||
assemble_name ((STREAM), (NAME)), \
|
||||
fprintf (STREAM, ", %d\t%s %d\n", ROUNDED, ASM_COMMENT_START, SIZE))
|
||||
#define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \
|
||||
do \
|
||||
{ \
|
||||
fprintf (STREAM, "\t.comm\t"); \
|
||||
assemble_name (STREAM, NAME); \
|
||||
fprintf (STREAM, ", %d\t%s %d\n", ROUNDED, \
|
||||
ASM_COMMENT_START, SIZE); \
|
||||
} \
|
||||
while (0)
|
||||
#endif
|
||||
|
||||
/* Output a local common block. /bin/as can't do this, so hack a
|
||||
|
@ -263,18 +291,20 @@ do { char dstr[30]; \
|
|||
which is guaranteed NOT to work since it doesn't define STATIC
|
||||
COMMON space but merely STATIC BSS space. */
|
||||
#ifndef ASM_OUTPUT_ALIGNED_LOCAL
|
||||
#define ASM_OUTPUT_ALIGNED_LOCAL(STREAM,NAME,SIZE,ALIGN) \
|
||||
do { \
|
||||
bss_section (); \
|
||||
ASM_OUTPUT_ALIGN (STREAM, floor_log2 (ALIGN / BITS_PER_UNIT)); \
|
||||
ASM_OUTPUT_LABEL (STREAM, NAME); \
|
||||
fprintf (STREAM, "\t.space\t%d\n", SIZE); \
|
||||
} while (0)
|
||||
#define ASM_OUTPUT_ALIGNED_LOCAL(STREAM, NAME, SIZE, ALIGN) \
|
||||
do \
|
||||
{ \
|
||||
bss_section (); \
|
||||
ASM_OUTPUT_ALIGN (STREAM, floor_log2 (ALIGN / BITS_PER_UNIT)); \
|
||||
ASM_OUTPUT_LABEL (STREAM, NAME); \
|
||||
fprintf (STREAM, "\t.space\t%d\n", SIZE); \
|
||||
} \
|
||||
while (0)
|
||||
#endif
|
||||
|
||||
/* Output a zero-initialized block. */
|
||||
#ifndef ASM_OUTPUT_ALIGNED_BSS
|
||||
#define ASM_OUTPUT_ALIGNED_BSS(STREAM,DECL,NAME,SIZE,ALIGN) \
|
||||
#define ASM_OUTPUT_ALIGNED_BSS(STREAM, DECL, NAME, SIZE, ALIGN) \
|
||||
asm_output_aligned_bss (STREAM, DECL, NAME, SIZE, ALIGN)
|
||||
#endif
|
||||
|
||||
|
|
|
@ -144,9 +144,6 @@ int current_function_anonymous_args;
|
|||
/* The register number to be used for the PIC offset register. */
|
||||
int arm_pic_register = 9;
|
||||
|
||||
/* Location counter of .text segment. */
|
||||
int arm_text_location = 0;
|
||||
|
||||
/* Set to one if we think that lr is only saved because of subroutine calls,
|
||||
but all of these can be `put after' return insns */
|
||||
int lr_save_eliminated;
|
||||
|
@ -366,7 +363,7 @@ arm_override_options ()
|
|||
switch that require certain abilities from the cpu. */
|
||||
sought = 0;
|
||||
|
||||
if (TARGET_THUMB_INTERWORK)
|
||||
if (TARGET_INTERWORK)
|
||||
{
|
||||
sought |= (FL_THUMB | FL_MODE32);
|
||||
|
||||
|
@ -456,14 +453,14 @@ arm_override_options ()
|
|||
target_flags |= ARM_FLAG_APCS_32;
|
||||
}
|
||||
|
||||
if (TARGET_THUMB_INTERWORK && !(insn_flags & FL_THUMB))
|
||||
if (TARGET_INTERWORK && !(insn_flags & FL_THUMB))
|
||||
{
|
||||
warning ("target CPU does not support interworking" );
|
||||
target_flags &= ~ARM_FLAG_THUMB;
|
||||
target_flags &= ~ARM_FLAG_INTERWORK;
|
||||
}
|
||||
|
||||
/* If interworking is enabled then APCS-32 must be selected as well. */
|
||||
if (TARGET_THUMB_INTERWORK)
|
||||
if (TARGET_INTERWORK)
|
||||
{
|
||||
if (! TARGET_APCS_32)
|
||||
warning ("interworking forces APCS-32 to be used" );
|
||||
|
@ -476,9 +473,6 @@ arm_override_options ()
|
|||
target_flags |= ARM_FLAG_APCS_FRAME;
|
||||
}
|
||||
|
||||
if (write_symbols != NO_DEBUG && flag_omit_frame_pointer)
|
||||
warning ("-g with -fomit-frame-pointer may not give sensible debugging");
|
||||
|
||||
if (TARGET_POKE_FUNCTION_NAME)
|
||||
target_flags |= ARM_FLAG_APCS_FRAME;
|
||||
|
||||
|
@ -488,6 +482,9 @@ arm_override_options ()
|
|||
if (TARGET_APCS_REENT)
|
||||
warning ("APCS reentrant code not supported. Ignored");
|
||||
|
||||
if (write_symbols != NO_DEBUG && flag_omit_frame_pointer)
|
||||
warning ("-g with -fomit-frame-pointer may not give sensible debugging");
|
||||
|
||||
/* If stack checking is disabled, we can use r10 as the PIC register,
|
||||
which keeps r9 available. */
|
||||
if (flag_pic && ! TARGET_APCS_STACK)
|
||||
|
@ -583,7 +580,7 @@ use_return_insn (iscond)
|
|||
if (iscond && arm_is_strong && frame_pointer_needed)
|
||||
return 0;
|
||||
if ((iscond && arm_is_strong)
|
||||
|| TARGET_THUMB_INTERWORK)
|
||||
|| TARGET_INTERWORK)
|
||||
{
|
||||
for (regno = 0; regno < 16; regno++)
|
||||
if (regs_ever_live[regno] && ! call_used_regs[regno])
|
||||
|
@ -4409,7 +4406,7 @@ print_multi_reg (stream, instr, mask, hat)
|
|||
if (not_first)
|
||||
fprintf (stream, ", ");
|
||||
|
||||
fprintf (stream, "%s%s", REGISTER_PREFIX, reg_names[i]);
|
||||
asm_fprintf (stream, "%R%s", reg_names[i]);
|
||||
not_first = TRUE;
|
||||
}
|
||||
|
||||
|
@ -4432,7 +4429,7 @@ output_call (operands)
|
|||
|
||||
output_asm_insn ("mov%?\t%|lr, %|pc", operands);
|
||||
|
||||
if (TARGET_THUMB_INTERWORK)
|
||||
if (TARGET_INTERWORK)
|
||||
output_asm_insn ("bx%?\t%0", operands);
|
||||
else
|
||||
output_asm_insn ("mov%?\t%|pc, %0", operands);
|
||||
|
@ -4486,7 +4483,7 @@ output_call_mem (operands)
|
|||
if (eliminate_lr2ip (&operands[0]))
|
||||
output_asm_insn ("mov%?\t%|ip, %|lr", operands);
|
||||
|
||||
if (TARGET_THUMB_INTERWORK)
|
||||
if (TARGET_INTERWORK)
|
||||
{
|
||||
output_asm_insn ("ldr%?\t%|ip, %0", operands);
|
||||
output_asm_insn ("mov%?\t%|lr, %|pc", operands);
|
||||
|
@ -4653,9 +4650,9 @@ output_move_double (operands)
|
|||
|
||||
/* Ensure the second source is not overwritten */
|
||||
if (reg1 == reg0 + (WORDS_BIG_ENDIAN ? -1 : 1))
|
||||
output_asm_insn("mov%?\t%Q0, %Q1\n\tmov%?\t%R0, %R1", operands);
|
||||
output_asm_insn ("mov%?\t%Q0, %Q1\n\tmov%?\t%R0, %R1", operands);
|
||||
else
|
||||
output_asm_insn("mov%?\t%R0, %R1\n\tmov%?\t%Q0, %Q1", operands);
|
||||
output_asm_insn ("mov%?\t%R0, %R1\n\tmov%?\t%Q0, %Q1", operands);
|
||||
}
|
||||
else if (code1 == CONST_DOUBLE)
|
||||
{
|
||||
|
@ -4684,6 +4681,7 @@ output_move_double (operands)
|
|||
otherops[1] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
|
||||
operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
|
||||
}
|
||||
|
||||
output_mov_immediate (operands);
|
||||
output_mov_immediate (otherops);
|
||||
}
|
||||
|
@ -4779,6 +4777,7 @@ output_move_double (operands)
|
|||
}
|
||||
else
|
||||
output_asm_insn ("sub%?\t%0, %1, %2", otherops);
|
||||
|
||||
return "ldm%?ia\t%0, %M0";
|
||||
}
|
||||
else
|
||||
|
@ -5105,6 +5104,7 @@ int_log2 (power)
|
|||
|
||||
/* Output a .ascii pseudo-op, keeping track of lengths. This is because
|
||||
/bin/as is horribly restrictive. */
|
||||
#define MAX_ASCII_LEN 51
|
||||
|
||||
void
|
||||
output_ascii_pseudo_op (stream, p, len)
|
||||
|
@ -5113,40 +5113,72 @@ output_ascii_pseudo_op (stream, p, len)
|
|||
int len;
|
||||
{
|
||||
int i;
|
||||
int len_so_far = 1000;
|
||||
int chars_so_far = 0;
|
||||
int len_so_far = 0;
|
||||
|
||||
fputs ("\t.ascii\t\"", stream);
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
register int c = p[i];
|
||||
|
||||
if (len_so_far > 50)
|
||||
if (len_so_far >= MAX_ASCII_LEN)
|
||||
{
|
||||
if (chars_so_far)
|
||||
fputs ("\"\n", stream);
|
||||
fputs ("\t.ascii\t\"", stream);
|
||||
fputs ("\"\n\t.ascii\t\"", stream);
|
||||
len_so_far = 0;
|
||||
chars_so_far = 0;
|
||||
}
|
||||
|
||||
if (c == '\"' || c == '\\')
|
||||
switch (c)
|
||||
{
|
||||
putc('\\', stream);
|
||||
len_so_far++;
|
||||
}
|
||||
case TARGET_TAB:
|
||||
fputs ("\\t", stream);
|
||||
len_so_far += 2;
|
||||
break;
|
||||
|
||||
case TARGET_FF:
|
||||
fputs ("\\f", stream);
|
||||
len_so_far += 2;
|
||||
break;
|
||||
|
||||
case TARGET_BS:
|
||||
fputs ("\\b", stream);
|
||||
len_so_far += 2;
|
||||
break;
|
||||
|
||||
case TARGET_CR:
|
||||
fputs ("\\r", stream);
|
||||
len_so_far += 2;
|
||||
break;
|
||||
|
||||
case TARGET_NEWLINE:
|
||||
fputs ("\\n", stream);
|
||||
c = p [i + 1];
|
||||
if ((c >= ' ' && c <= '~')
|
||||
|| c == TARGET_TAB)
|
||||
/* This is a good place for a line break. */
|
||||
len_so_far = MAX_ASCII_LEN;
|
||||
else
|
||||
len_so_far += 2;
|
||||
break;
|
||||
|
||||
case '\"':
|
||||
case '\\':
|
||||
putc ('\\', stream);
|
||||
len_so_far ++;
|
||||
/* drop through. */
|
||||
|
||||
if (c >= ' ' && c < 0177)
|
||||
{
|
||||
putc (c, stream);
|
||||
len_so_far++;
|
||||
default:
|
||||
if (c >= ' ' && c <= '~')
|
||||
{
|
||||
putc (c, stream);
|
||||
len_so_far ++;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (stream, "\\%03o", c);
|
||||
len_so_far += 4;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (stream, "\\%03o", c);
|
||||
len_so_far +=4;
|
||||
}
|
||||
|
||||
chars_so_far++;
|
||||
}
|
||||
|
||||
fputs ("\"\n", stream);
|
||||
|
@ -5376,13 +5408,13 @@ output_return_instruction (operand, really_return, reverse)
|
|||
strcat (instr, reg_names[13]);
|
||||
strcat (instr, ", ");
|
||||
strcat (instr, "%|");
|
||||
strcat (instr, TARGET_THUMB_INTERWORK || (! really_return)
|
||||
strcat (instr, TARGET_INTERWORK || (! really_return)
|
||||
? reg_names[LR_REGNUM] : reg_names[PC_REGNUM] );
|
||||
}
|
||||
else
|
||||
{
|
||||
strcat (instr, "%|");
|
||||
if (TARGET_THUMB_INTERWORK && really_return)
|
||||
if (TARGET_INTERWORK && really_return)
|
||||
strcat (instr, reg_names[IP_REGNUM]);
|
||||
else
|
||||
strcat (instr, really_return ? reg_names[PC_REGNUM] : reg_names[LR_REGNUM]);
|
||||
|
@ -5390,7 +5422,7 @@ output_return_instruction (operand, really_return, reverse)
|
|||
strcat (instr, (TARGET_APCS_32 || !really_return) ? "}" : "}^");
|
||||
output_asm_insn (instr, &operand);
|
||||
|
||||
if (TARGET_THUMB_INTERWORK && really_return)
|
||||
if (TARGET_INTERWORK && really_return)
|
||||
{
|
||||
strcpy (instr, "bx%?");
|
||||
strcat (instr, reverse ? "%D0" : "%d0");
|
||||
|
@ -5402,7 +5434,7 @@ output_return_instruction (operand, really_return, reverse)
|
|||
}
|
||||
else if (really_return)
|
||||
{
|
||||
if (TARGET_THUMB_INTERWORK)
|
||||
if (TARGET_INTERWORK)
|
||||
sprintf (instr, "bx%%?%%%s0\t%%|lr", reverse ? "D" : "d");
|
||||
else
|
||||
sprintf (instr, "mov%%?%%%s0%s\t%%|pc, %%|lr",
|
||||
|
@ -5463,7 +5495,7 @@ arm_poke_function_name (stream, name)
|
|||
rtx x;
|
||||
|
||||
length = strlen (name);
|
||||
alignlength = (length + 1) + 3 & ~3;
|
||||
alignlength = NUM_INTS (length + 1);
|
||||
|
||||
ASM_OUTPUT_ASCII (stream, name, length + 1);
|
||||
ASM_OUTPUT_ALIGN (stream, 2);
|
||||
|
@ -5482,7 +5514,7 @@ arm_poke_function_name (stream, name)
|
|||
|
||||
void
|
||||
output_func_prologue (f, frame_size)
|
||||
FILE *f;
|
||||
FILE * f;
|
||||
int frame_size;
|
||||
{
|
||||
int reg, live_regs_mask = 0;
|
||||
|
@ -5551,8 +5583,8 @@ output_func_prologue (f, frame_size)
|
|||
|
||||
#ifdef AOF_ASSEMBLER
|
||||
if (flag_pic)
|
||||
fprintf (f, "\tmov\t%sip, %s%s\n", REGISTER_PREFIX, REGISTER_PREFIX,
|
||||
reg_names[PIC_OFFSET_TABLE_REGNUM]);
|
||||
asm_fprintf (f, "\tmov\t%R%s, %R%s\n", reg_names [IP_REGNUM],
|
||||
reg_names[PIC_OFFSET_TABLE_REGNUM]);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -5612,8 +5644,8 @@ output_func_epilogue (f, frame_size)
|
|||
if (regs_ever_live[reg] && ! call_used_regs[reg])
|
||||
{
|
||||
floats_offset += 12;
|
||||
fprintf (f, "\tldfe\t%s%s, [%sfp, #-%d]\n", REGISTER_PREFIX,
|
||||
reg_names[reg], REGISTER_PREFIX, floats_offset);
|
||||
asm_fprintf (f, "\tldfe\t%R%s, [%R%s, #-%d]\n",
|
||||
reg_names[reg], reg_names [FP_REGNUM], floats_offset);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -5625,38 +5657,38 @@ output_func_epilogue (f, frame_size)
|
|||
if (regs_ever_live[reg] && ! call_used_regs[reg])
|
||||
{
|
||||
floats_offset += 12;
|
||||
|
||||
/* We can't unstack more than four registers at once */
|
||||
if (start_reg - reg == 3)
|
||||
{
|
||||
fprintf (f, "\tlfm\t%s%s, 4, [%sfp, #-%d]\n",
|
||||
REGISTER_PREFIX, reg_names[reg],
|
||||
REGISTER_PREFIX, floats_offset);
|
||||
asm_fprintf (f, "\tlfm\t%R%s, 4, [%R%s, #-%d]\n",
|
||||
reg_names[reg], reg_names [FP_REGNUM],
|
||||
floats_offset);
|
||||
start_reg = reg - 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (reg != start_reg)
|
||||
fprintf (f, "\tlfm\t%s%s, %d, [%sfp, #-%d]\n",
|
||||
REGISTER_PREFIX, reg_names[reg + 1],
|
||||
start_reg - reg, REGISTER_PREFIX, floats_offset);
|
||||
|
||||
asm_fprintf (f, "\tlfm\t%R%s, %d, [%R%s, #-%d]\n",
|
||||
reg_names [reg + 1], start_reg - reg,
|
||||
reg_names [FP_REGNUM], floats_offset);
|
||||
start_reg = reg - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Just in case the last register checked also needs unstacking. */
|
||||
if (reg != start_reg)
|
||||
fprintf (f, "\tlfm\t%s%s, %d, [%sfp, #-%d]\n",
|
||||
REGISTER_PREFIX, reg_names[reg + 1],
|
||||
start_reg - reg, REGISTER_PREFIX, floats_offset);
|
||||
asm_fprintf (f, "\tlfm\t%R%s, %d, [%R%s, #-%d]\n",
|
||||
reg_names [reg + 1], start_reg - reg,
|
||||
reg_names [FP_REGNUM], floats_offset);
|
||||
}
|
||||
|
||||
if (TARGET_THUMB_INTERWORK)
|
||||
if (TARGET_INTERWORK)
|
||||
{
|
||||
live_regs_mask |= 0x6800;
|
||||
print_multi_reg (f, "ldmea\t%sfp", live_regs_mask, FALSE);
|
||||
fprintf (f, "\tbx\t%slr\n", REGISTER_PREFIX);
|
||||
asm_fprintf (f, "\tbx\t%R%s\n", reg_names [LR_REGNUM]);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5680,8 +5712,8 @@ output_func_epilogue (f, frame_size)
|
|||
{
|
||||
for (reg = 16; reg < 24; reg++)
|
||||
if (regs_ever_live[reg] && ! call_used_regs[reg])
|
||||
fprintf (f, "\tldfe\t%s%s, [%ssp], #12\n", REGISTER_PREFIX,
|
||||
reg_names[reg], REGISTER_PREFIX);
|
||||
asm_fprintf (f, "\tldfe\t%R%s, [%R%s], #12\n",
|
||||
reg_names[reg], reg_names [SP_REGNUM]);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5693,46 +5725,45 @@ output_func_epilogue (f, frame_size)
|
|||
{
|
||||
if (reg - start_reg == 3)
|
||||
{
|
||||
fprintf (f, "\tlfmfd\t%s%s, 4, [%ssp]!\n",
|
||||
REGISTER_PREFIX, reg_names[start_reg],
|
||||
REGISTER_PREFIX);
|
||||
asm_fprintf (f, "\tlfmfd\t%R%s, 4, [%R%s]!\n",
|
||||
reg_names[start_reg], reg_names [SP_REGNUM]);
|
||||
start_reg = reg + 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (reg != start_reg)
|
||||
fprintf (f, "\tlfmfd\t%s%s, %d, [%ssp]!\n",
|
||||
REGISTER_PREFIX, reg_names[start_reg],
|
||||
reg - start_reg, REGISTER_PREFIX);
|
||||
|
||||
asm_fprintf (f, "\tlfmfd\t%R%s, %d, [%R%s]!\n",
|
||||
reg_names [start_reg], reg - start_reg,
|
||||
reg_names [SP_REGNUM]);
|
||||
|
||||
start_reg = reg + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Just in case the last register checked also needs unstacking. */
|
||||
if (reg != start_reg)
|
||||
fprintf (f, "\tlfmfd\t%s%s, %d, [%ssp]!\n",
|
||||
REGISTER_PREFIX, reg_names[start_reg],
|
||||
reg - start_reg, REGISTER_PREFIX);
|
||||
asm_fprintf (f, "\tlfmfd\t%R%s, %d, [%R%s]!\n",
|
||||
reg_names [start_reg], reg - start_reg,
|
||||
reg_names [SP_REGNUM]);
|
||||
}
|
||||
|
||||
if (current_function_pretend_args_size == 0 && regs_ever_live[LR_REGNUM])
|
||||
{
|
||||
if (TARGET_THUMB_INTERWORK)
|
||||
if (TARGET_INTERWORK)
|
||||
{
|
||||
if (! lr_save_eliminated)
|
||||
live_regs_mask |= 1 << LR_REGNUM;
|
||||
|
||||
if (live_regs_mask != 0)
|
||||
print_multi_reg (f, "ldmfd\t%ssp!", live_regs_mask, FALSE);
|
||||
|
||||
fprintf (f, "\tbx\t%slr\n", REGISTER_PREFIX);
|
||||
|
||||
asm_fprintf (f, "\tbx\t%R%s\n", reg_names [LR_REGNUM]);
|
||||
}
|
||||
else if (lr_save_eliminated)
|
||||
fprintf (f, (TARGET_APCS_32 ? "\tmov\t%spc, %slr\n"
|
||||
: "\tmovs\t%spc, %slr\n"),
|
||||
REGISTER_PREFIX, REGISTER_PREFIX, f);
|
||||
asm_fprintf (f, "\tmov%c\t%r, %r\n",
|
||||
TARGET_APCS_32 ? ' ' : 's',
|
||||
reg_names [PC_REGNUM], reg_names [LR_REGNUM]);
|
||||
else
|
||||
print_multi_reg (f, "ldmfd\t%ssp!", live_regs_mask | 0x8000,
|
||||
TARGET_APCS_32 ? FALSE : TRUE);
|
||||
|
@ -5757,12 +5788,12 @@ output_func_epilogue (f, frame_size)
|
|||
output_add_immediate (operands);
|
||||
}
|
||||
/* And finally, go home */
|
||||
if (TARGET_THUMB_INTERWORK)
|
||||
fprintf (f, "\tbx\t%slr\n", REGISTER_PREFIX);
|
||||
if (TARGET_INTERWORK)
|
||||
asm_fprintf (f, "\tbx\t%R%s\n", reg_names [LR_REGNUM]);
|
||||
else if (TARGET_APCS_32)
|
||||
fprintf (f, "\tmov\t%spc, %slr\n", REGISTER_PREFIX, REGISTER_PREFIX );
|
||||
asm_fprintf (f, "\tmov\t%R%s, %R%s\n", reg_names [PC_REGNUM], reg_names [LR_REGNUM]);
|
||||
else
|
||||
fprintf (f, "\tmovs\t%spc, %slr\n", REGISTER_PREFIX, REGISTER_PREFIX );
|
||||
asm_fprintf (f, "\tmovs\t%R%s, %R%s\n", reg_names [PC_REGNUM], reg_names [LR_REGNUM]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6071,11 +6102,9 @@ arm_print_operand (stream, x, code)
|
|||
return;
|
||||
|
||||
case 'M':
|
||||
fprintf (stream, "{%s%s-%s%s}", REGISTER_PREFIX, reg_names[REGNO (x)],
|
||||
REGISTER_PREFIX, reg_names[REGNO (x) - 1
|
||||
+ ((GET_MODE_SIZE (GET_MODE (x))
|
||||
+ GET_MODE_SIZE (SImode) - 1)
|
||||
/ GET_MODE_SIZE (SImode))]);
|
||||
asm_fprintf (stream, "{%R%s-%R%s}",
|
||||
reg_names[REGNO (x)],
|
||||
reg_names[REGNO (x) + NUM_INTS (GET_MODE (x)) - 1]);
|
||||
return;
|
||||
|
||||
case 'd':
|
||||
|
@ -6116,7 +6145,6 @@ arm_print_operand (stream, x, code)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* A finite state machine takes care of noticing whether or not instructions
|
||||
can be conditionally executed, and thus decrease execution time and code
|
||||
|
@ -6643,9 +6671,9 @@ aof_dump_pic_table (f)
|
|||
if (aof_pic_chain == NULL)
|
||||
return;
|
||||
|
||||
fprintf (f, "\tAREA |%s$$adcons|, BASED %s%s\n",
|
||||
reg_names[PIC_OFFSET_TABLE_REGNUM], REGISTER_PREFIX,
|
||||
reg_names[PIC_OFFSET_TABLE_REGNUM]);
|
||||
asm_fprintf (f, "\tAREA |%R%s$$adcons|, BASED %R%s\n",
|
||||
reg_names[PIC_OFFSET_TABLE_REGNUM],
|
||||
reg_names[PIC_OFFSET_TABLE_REGNUM]);
|
||||
fputs ("|x$adcons|\n", f);
|
||||
|
||||
for (chain = aof_pic_chain; chain; chain = chain->next)
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
|
||||
and Martin Simmons (@harleqn.co.uk).
|
||||
More major hacks by Richard Earnshaw (rwe11@cl.cam.ac.uk)
|
||||
|
||||
Minor hacks by Nick Clifton (nickc@cygnus.com)
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC is free software; you can redistribute it and/or modify
|
||||
|
@ -64,13 +65,22 @@ enum arm_cond_code
|
|||
ARM_EQ = 0, ARM_NE, ARM_CS, ARM_CC, ARM_MI, ARM_PL, ARM_VS, ARM_VC,
|
||||
ARM_HI, ARM_LS, ARM_GE, ARM_LT, ARM_GT, ARM_LE, ARM_AL, ARM_NV
|
||||
};
|
||||
|
||||
extern enum arm_cond_code arm_current_cc;
|
||||
extern char * arm_condition_codes[];
|
||||
|
||||
#define ARM_INVERSE_CONDITION_CODE(X) ((enum arm_cond_code) (((int)X) ^ 1))
|
||||
|
||||
extern int arm_target_label;
|
||||
extern int arm_ccfsm_state;
|
||||
extern struct rtx_def * arm_target_insn;
|
||||
extern int lr_save_eliminated;
|
||||
/* This is needed by the tail-calling peepholes */
|
||||
extern int frame_pointer_needed;
|
||||
/* Run-time compilation parameters selecting different hardware subsets. */
|
||||
extern int target_flags;
|
||||
/* The floating point instruction architecture, can be 2 or 3 */
|
||||
extern const char * target_fp_name;
|
||||
|
||||
|
||||
/* Just in case configure has failed to define anything. */
|
||||
|
@ -206,11 +216,11 @@ Unrecognized value in TARGET_CPU_DEFAULT.
|
|||
#define CPP_FLOAT_DEFAULT_SPEC ""
|
||||
|
||||
#define CPP_ENDIAN_SPEC "\
|
||||
%{mbig-endian: \
|
||||
%{mlittle-endian: \
|
||||
%e-mbig-endian and -mlittle-endian may not be used together} \
|
||||
-D__ARMEB__ %{mwords-little-endian:-D__ARMWEL__}} \
|
||||
%{!mlittle-endian:%{!mbig-endian:%(cpp_endian_default)}} \
|
||||
%{mbig-endian: \
|
||||
%{mlittle-endian: \
|
||||
%e-mbig-endian and -mlittle-endian may not be used together} \
|
||||
-D__ARMEB__ %{mwords-little-endian:-D__ARMWEL__}} \
|
||||
%{!mlittle-endian:%{!mbig-endian:%(cpp_endian_default)}} \
|
||||
"
|
||||
|
||||
/* Default is little endian, which doesn't define anything. */
|
||||
|
@ -240,79 +250,74 @@ Unrecognized value in TARGET_CPU_DEFAULT.
|
|||
SUBTARGET_EXTRA_SPECS
|
||||
|
||||
#define SUBTARGET_EXTRA_SPECS
|
||||
#ifndef SUBTARGET_CPP_SPEC
|
||||
#define SUBTARGET_CPP_SPEC ""
|
||||
#endif
|
||||
|
||||
|
||||
/* Run-time Target Specification. */
|
||||
#ifndef TARGET_VERSION
|
||||
#define TARGET_VERSION \
|
||||
fputs (" (ARM/generic)", stderr);
|
||||
#define TARGET_VERSION fputs (" (ARM/generic)", stderr);
|
||||
#endif
|
||||
|
||||
/* Run-time compilation parameters selecting different hardware subsets. */
|
||||
extern int target_flags;
|
||||
|
||||
/* The floating point instruction architecture, can be 2 or 3 */
|
||||
extern const char * target_fp_name;
|
||||
|
||||
/* Nonzero if the function prologue (and epilogue) should obey
|
||||
the ARM Procedure Call Standard. */
|
||||
#define ARM_FLAG_APCS_FRAME (0x0001)
|
||||
#define ARM_FLAG_APCS_FRAME (1 << 0)
|
||||
|
||||
/* Nonzero if the function prologue should output the function name to enable
|
||||
the post mortem debugger to print a backtrace (very useful on RISCOS,
|
||||
unused on RISCiX). Specifying this flag also enables
|
||||
-fno-omit-frame-pointer.
|
||||
XXX Must still be implemented in the prologue. */
|
||||
#define ARM_FLAG_POKE (0x0002)
|
||||
#define ARM_FLAG_POKE (1 << 1)
|
||||
|
||||
/* Nonzero if floating point instructions are emulated by the FPE, in which
|
||||
case instruction scheduling becomes very uninteresting. */
|
||||
#define ARM_FLAG_FPE (0x0004)
|
||||
#define ARM_FLAG_FPE (1 << 2)
|
||||
|
||||
/* Nonzero if destined for a processor in 32-bit program mode. Takes out bit
|
||||
that assume restoration of the condition flags when returning from a
|
||||
branch and link (ie a function). */
|
||||
#define ARM_FLAG_APCS_32 (0x0020)
|
||||
#define ARM_FLAG_APCS_32 (1 << 3)
|
||||
|
||||
/* FLAGS 0x0008 and 0x0010 are now spare (used to be arm3/6 selection). */
|
||||
|
||||
/* Nonzero if stack checking should be performed on entry to each function
|
||||
which allocates temporary variables on the stack. */
|
||||
#define ARM_FLAG_APCS_STACK (0x0040)
|
||||
#define ARM_FLAG_APCS_STACK (1 << 4)
|
||||
|
||||
/* Nonzero if floating point parameters should be passed to functions in
|
||||
floating point registers. */
|
||||
#define ARM_FLAG_APCS_FLOAT (0x0080)
|
||||
#define ARM_FLAG_APCS_FLOAT (1 << 5)
|
||||
|
||||
/* Nonzero if re-entrant, position independent code should be generated.
|
||||
This is equivalent to -fpic. */
|
||||
#define ARM_FLAG_APCS_REENT (0x0100)
|
||||
#define ARM_FLAG_APCS_REENT (1 << 6)
|
||||
|
||||
/* Nonzero if the MMU will trap unaligned word accesses, so shorts must be
|
||||
loaded byte-at-a-time. */
|
||||
#define ARM_FLAG_SHORT_BYTE (0x0200)
|
||||
#define ARM_FLAG_SHORT_BYTE (1 << 7)
|
||||
|
||||
/* Nonzero if all floating point instructions are missing (and there is no
|
||||
emulator either). Generate function calls for all ops in this case. */
|
||||
#define ARM_FLAG_SOFT_FLOAT (0x0400)
|
||||
#define ARM_FLAG_SOFT_FLOAT (1 << 8)
|
||||
|
||||
/* Nonzero if we should compile with BYTES_BIG_ENDIAN set to 1. */
|
||||
#define ARM_FLAG_BIG_END (0x0800)
|
||||
#define ARM_FLAG_BIG_END (1 << 9)
|
||||
|
||||
/* Nonzero if we should compile for Thumb interworking. */
|
||||
#define ARM_FLAG_THUMB (0x1000)
|
||||
#define ARM_FLAG_INTERWORK (1 << 10)
|
||||
|
||||
/* Nonzero if we should have little-endian words even when compiling for
|
||||
big-endian (for backwards compatibility with older versions of GCC). */
|
||||
#define ARM_FLAG_LITTLE_WORDS (0x2000)
|
||||
#define ARM_FLAG_LITTLE_WORDS (1 << 11)
|
||||
|
||||
/* Nonzero if we need to protect the prolog from scheduling */
|
||||
#define ARM_FLAG_NO_SCHED_PRO (0x4000)
|
||||
#define ARM_FLAG_NO_SCHED_PRO (1 << 12)
|
||||
|
||||
/* Nonzero if a call to abort should be generated if a noreturn
|
||||
function tries to return. */
|
||||
#define ARM_FLAG_ABORT_NORETURN (0x8000)
|
||||
#define ARM_FLAG_ABORT_NORETURN (1 << 13)
|
||||
|
||||
#define TARGET_APCS (target_flags & ARM_FLAG_APCS_FRAME)
|
||||
#define TARGET_POKE_FUNCTION_NAME (target_flags & ARM_FLAG_POKE)
|
||||
|
@ -332,7 +337,7 @@ function tries to return. */
|
|||
#define TARGET_SOFT_FLOAT (target_flags & ARM_FLAG_SOFT_FLOAT)
|
||||
#define TARGET_HARD_FLOAT (! TARGET_SOFT_FLOAT)
|
||||
#define TARGET_BIG_END (target_flags & ARM_FLAG_BIG_END)
|
||||
#define TARGET_THUMB_INTERWORK (target_flags & ARM_FLAG_THUMB)
|
||||
#define TARGET_INTERWORK (target_flags & ARM_FLAG_INTERWORK)
|
||||
#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)
|
||||
|
@ -343,55 +348,55 @@ function tries to return. */
|
|||
#define SUBTARGET_SWITCHES
|
||||
#endif
|
||||
|
||||
#define TARGET_SWITCHES \
|
||||
{ \
|
||||
{"apcs", ARM_FLAG_APCS_FRAME, "" }, \
|
||||
{"apcs-frame", ARM_FLAG_APCS_FRAME, \
|
||||
"Generate APCS conformant stack frames" }, \
|
||||
{"no-apcs-frame", -ARM_FLAG_APCS_FRAME, "" }, \
|
||||
{"poke-function-name", ARM_FLAG_POKE, \
|
||||
"Store function names in object code" }, \
|
||||
{"no-poke-function-name", -ARM_FLAG_POKE, "" }, \
|
||||
{"fpe", ARM_FLAG_FPE, "" }, \
|
||||
{"apcs-32", ARM_FLAG_APCS_32, \
|
||||
"Use the 32bit version of the APCS" }, \
|
||||
{"apcs-26", -ARM_FLAG_APCS_32, \
|
||||
"Use the 26bit version of the APCS" }, \
|
||||
{"apcs-stack-check", ARM_FLAG_APCS_STACK, "" }, \
|
||||
{"no-apcs-stack-check", -ARM_FLAG_APCS_STACK, "" }, \
|
||||
{"apcs-float", ARM_FLAG_APCS_FLOAT, \
|
||||
"Pass FP arguments in FP registers" }, \
|
||||
{"no-apcs-float", -ARM_FLAG_APCS_FLOAT, "" }, \
|
||||
{"apcs-reentrant", ARM_FLAG_APCS_REENT, \
|
||||
"Generate re-entrant, PIC code" }, \
|
||||
{"no-apcs-reentrant", -ARM_FLAG_APCS_REENT, "" }, \
|
||||
{"short-load-bytes", ARM_FLAG_SHORT_BYTE, \
|
||||
"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" }, \
|
||||
{"no-short-load-words", ARM_FLAG_SHORT_BYTE, "" }, \
|
||||
{"soft-float", ARM_FLAG_SOFT_FLOAT, \
|
||||
"Use library calls to perform FP operations" }, \
|
||||
{"hard-float", -ARM_FLAG_SOFT_FLOAT, \
|
||||
"Use hardware floating point instructions" }, \
|
||||
{"big-endian", ARM_FLAG_BIG_END, \
|
||||
"Assume target CPU is configured as big endian" }, \
|
||||
{"little-endian", -ARM_FLAG_BIG_END, \
|
||||
"Assume target CPU is configured as little endian" }, \
|
||||
{"words-little-endian", ARM_FLAG_LITTLE_WORDS, \
|
||||
"Assume big endian bytes, little endian words" }, \
|
||||
{"thumb-interwork", ARM_FLAG_THUMB, \
|
||||
#define TARGET_SWITCHES \
|
||||
{ \
|
||||
{"apcs", ARM_FLAG_APCS_FRAME, "" }, \
|
||||
{"apcs-frame", ARM_FLAG_APCS_FRAME, \
|
||||
"Generate APCS conformant stack frames" }, \
|
||||
{"no-apcs-frame", -ARM_FLAG_APCS_FRAME, "" }, \
|
||||
{"poke-function-name", ARM_FLAG_POKE, \
|
||||
"Store function names in object code" }, \
|
||||
{"no-poke-function-name", -ARM_FLAG_POKE, "" }, \
|
||||
{"fpe", ARM_FLAG_FPE, "" }, \
|
||||
{"apcs-32", ARM_FLAG_APCS_32, \
|
||||
"Use the 32bit version of the APCS" }, \
|
||||
{"apcs-26", -ARM_FLAG_APCS_32, \
|
||||
"Use the 26bit version of the APCS" }, \
|
||||
{"apcs-stack-check", ARM_FLAG_APCS_STACK, "" }, \
|
||||
{"no-apcs-stack-check", -ARM_FLAG_APCS_STACK, "" }, \
|
||||
{"apcs-float", ARM_FLAG_APCS_FLOAT, \
|
||||
"Pass FP arguments in FP registers" }, \
|
||||
{"no-apcs-float", -ARM_FLAG_APCS_FLOAT, "" }, \
|
||||
{"apcs-reentrant", ARM_FLAG_APCS_REENT, \
|
||||
"Generate re-entrant, PIC code" }, \
|
||||
{"no-apcs-reentrant", -ARM_FLAG_APCS_REENT, "" }, \
|
||||
{"short-load-bytes", ARM_FLAG_SHORT_BYTE, \
|
||||
"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" }, \
|
||||
{"no-short-load-words", ARM_FLAG_SHORT_BYTE, "" }, \
|
||||
{"soft-float", ARM_FLAG_SOFT_FLOAT, \
|
||||
"Use library calls to perform FP operations" }, \
|
||||
{"hard-float", -ARM_FLAG_SOFT_FLOAT, \
|
||||
"Use hardware floating point instructions" }, \
|
||||
{"big-endian", ARM_FLAG_BIG_END, \
|
||||
"Assume target CPU is configured as big endian" }, \
|
||||
{"little-endian", -ARM_FLAG_BIG_END, \
|
||||
"Assume target CPU is configured as little endian" }, \
|
||||
{"words-little-endian", ARM_FLAG_LITTLE_WORDS, \
|
||||
"Assume big endian bytes, little endian words" }, \
|
||||
{"thumb-interwork", ARM_FLAG_INTERWORK, \
|
||||
"Support calls between THUMB and ARM instructions sets" }, \
|
||||
{"no-thumb-interwork", -ARM_FLAG_THUMB, "" }, \
|
||||
{"abort-on-noreturn", ARM_FLAG_ABORT_NORETURN, \
|
||||
"Generate a call to abort if a noreturn function returns"}, \
|
||||
{"no-abort-on-noreturn", -ARM_FLAG_ABORT_NORETURN, ""}, \
|
||||
{"sched-prolog", -ARM_FLAG_NO_SCHED_PRO, \
|
||||
"Do not move instructions into a function's prologue" }, \
|
||||
{"no-sched-prolog", ARM_FLAG_NO_SCHED_PRO, "" }, \
|
||||
SUBTARGET_SWITCHES \
|
||||
{"", TARGET_DEFAULT } \
|
||||
{"no-thumb-interwork", -ARM_FLAG_INTERWORK, "" }, \
|
||||
{"abort-on-noreturn", ARM_FLAG_ABORT_NORETURN, \
|
||||
"Generate a call to abort if a noreturn function returns"}, \
|
||||
{"no-abort-on-noreturn", -ARM_FLAG_ABORT_NORETURN, ""}, \
|
||||
{"sched-prolog", -ARM_FLAG_NO_SCHED_PRO, \
|
||||
"Do not move instructions into a function's prologue" }, \
|
||||
{"no-sched-prolog", ARM_FLAG_NO_SCHED_PRO, "" }, \
|
||||
SUBTARGET_SWITCHES \
|
||||
{"", TARGET_DEFAULT } \
|
||||
}
|
||||
|
||||
#define TARGET_OPTIONS \
|
||||
|
@ -518,7 +523,7 @@ extern int arm_is_6_or_7;
|
|||
|
||||
/* It is far faster to zero extend chars than to sign extend them */
|
||||
|
||||
#define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE) \
|
||||
#define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \
|
||||
if (GET_MODE_CLASS (MODE) == MODE_INT \
|
||||
&& GET_MODE_SIZE (MODE) < 4) \
|
||||
{ \
|
||||
|
@ -743,6 +748,26 @@ extern const char * structure_size_string;
|
|||
SUBTARGET_CONDITIONAL_REGISTER_USAGE \
|
||||
}
|
||||
|
||||
/* Convert fron bytes to ints. */
|
||||
#define NUM_INTS(X) (((X) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
|
||||
|
||||
/* The number of (integer) registers required to hold a quantity of type MODE. */
|
||||
#define NUM_REGS(MODE) \
|
||||
NUM_INTS (GET_MODE_SIZE (MODE))
|
||||
|
||||
/* The number of (integer) registers required to hold a quantity of TYPE MODE. */
|
||||
#define NUM_REGS2(MODE, TYPE) \
|
||||
NUM_INTS ((MODE) == BLKmode ? int_size_in_bytes (TYPE) : GET_MODE_SIZE (MODE))
|
||||
|
||||
/* The number of (integer) argument register available. */
|
||||
#define NUM_ARG_REGS 4
|
||||
|
||||
/* Return the regiser number of the N'th (integer) argument. */
|
||||
#define ARG_REGISTER(N) (N - 1)
|
||||
|
||||
/* The number of the last argument register. */
|
||||
#define LAST_ARG_REGNUM ARG_REGISTER (NUM_ARG_REGS)
|
||||
|
||||
/* Return number of consecutive hard regs needed starting at reg REGNO
|
||||
to hold something of mode MODE.
|
||||
This is ordinarily the length in words of a value of mode MODE
|
||||
|
@ -750,10 +775,11 @@ extern const char * structure_size_string;
|
|||
|
||||
On the ARM regs are UNITS_PER_WORD bits wide; FPU regs can hold any FP
|
||||
mode. */
|
||||
#define HARD_REGNO_NREGS(REGNO, MODE) \
|
||||
(((REGNO) >= 16 && REGNO != FRAME_POINTER_REGNUM \
|
||||
&& (REGNO) != ARG_POINTER_REGNUM) ? 1 \
|
||||
: ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
|
||||
#define HARD_REGNO_NREGS(REGNO, MODE) \
|
||||
(( REGNO >= 16 \
|
||||
&& REGNO != FRAME_POINTER_REGNUM \
|
||||
&& REGNO != ARG_POINTER_REGNUM) \
|
||||
? 1 : NUM_REGS (MODE))
|
||||
|
||||
/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
|
||||
This is TRUE for ARM regs since they can hold anything, and TRUE for FPU
|
||||
|
@ -779,6 +805,7 @@ extern const char * structure_size_string;
|
|||
|
||||
/* Register to use for pushing function arguments. */
|
||||
#define STACK_POINTER_REGNUM 13
|
||||
#define SP_REGNUM STACK_POINTER_REGNUM
|
||||
|
||||
/* Base register for access to local variables of the function. */
|
||||
#define FRAME_POINTER_REGNUM 25
|
||||
|
@ -788,6 +815,7 @@ extern const char * structure_size_string;
|
|||
until after register allocation has taken place. FRAME_POINTER_REGNUM
|
||||
should point to a special register that we will make sure is eliminated. */
|
||||
#define HARD_FRAME_POINTER_REGNUM 11
|
||||
#define FP_REGNUM HARD_FRAME_POINTER_REGNUM
|
||||
|
||||
/* Register which holds return address from a subroutine call. */
|
||||
#define LR_REGNUM 14
|
||||
|
@ -1006,8 +1034,7 @@ enum reg_class
|
|||
needed to represent mode MODE in a register of class CLASS.
|
||||
ARM regs are UNITS_PER_WORD bits while FPU regs can hold any FP mode */
|
||||
#define CLASS_MAX_NREGS(CLASS, MODE) \
|
||||
((CLASS) == FPU_REGS ? 1 \
|
||||
: ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
|
||||
((CLASS) == FPU_REGS ? 1 : NUM_REGS (MODE))
|
||||
|
||||
/* Moves between FPU_REGS and GENERAL_REGS are two memory insns. */
|
||||
#define REGISTER_MOVE_COST(CLASS1, CLASS2) \
|
||||
|
@ -1041,7 +1068,7 @@ enum reg_class
|
|||
/* Define this if the maximum size of all the outgoing args is to be
|
||||
accumulated and pushed during the prologue. The amount can be
|
||||
found in the variable current_function_outgoing_args_size. */
|
||||
#define ACCUMULATE_OUTGOING_ARGS
|
||||
#define ACCUMULATE_OUTGOING_ARGS 1
|
||||
|
||||
/* Offset of first parameter from the argument pointer register value. */
|
||||
#define FIRST_PARM_OFFSET(FNDECL) 4
|
||||
|
@ -1055,16 +1082,7 @@ enum reg_class
|
|||
|
||||
On the ARM, the caller does not pop any of its arguments that were passed
|
||||
on the stack. */
|
||||
#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0
|
||||
|
||||
/* Define how to find the value returned by a function.
|
||||
VALTYPE is the data type of the value (as a tree).
|
||||
If the precise function being called is known, FUNC is its FUNCTION_DECL;
|
||||
otherwise, FUNC is 0. */
|
||||
#define FUNCTION_VALUE(VALTYPE, FUNC) \
|
||||
(GET_MODE_CLASS (TYPE_MODE (VALTYPE)) == MODE_FLOAT && TARGET_HARD_FLOAT \
|
||||
? gen_rtx_REG (TYPE_MODE (VALTYPE), 16) \
|
||||
: gen_rtx_REG (TYPE_MODE (VALTYPE), 0))
|
||||
#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, SIZE) 0
|
||||
|
||||
/* Define how to find the value returned by a library function
|
||||
assuming the value has mode MODE. */
|
||||
|
@ -1073,6 +1091,13 @@ enum reg_class
|
|||
? gen_rtx_REG (MODE, 16) \
|
||||
: gen_rtx_REG (MODE, 0))
|
||||
|
||||
/* Define how to find the value returned by a function.
|
||||
VALTYPE is the data type of the value (as a tree).
|
||||
If the precise function being called is known, FUNC is its FUNCTION_DECL;
|
||||
otherwise, FUNC is 0. */
|
||||
#define FUNCTION_VALUE(VALTYPE, FUNC) \
|
||||
LIBCALL_VALUE (TYPE_MODE (VALTYPE))
|
||||
|
||||
/* 1 if N is a possible register number for a function value.
|
||||
On the ARM, only r0 and f0 can return results. */
|
||||
#define FUNCTION_VALUE_REGNO_P(REGNO) \
|
||||
|
@ -1106,19 +1131,18 @@ enum reg_class
|
|||
only in assign_parms, since SETUP_INCOMING_VARARGS is defined), say it is
|
||||
passed in the stack (function_prologue will indeed make it pass in the
|
||||
stack if necessary). */
|
||||
#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
|
||||
#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
|
||||
((NAMED) \
|
||||
? ((CUM) >= 16 ? 0 : gen_rtx_REG (MODE, (CUM) / 4)) \
|
||||
? ((CUM) >= NUM_ARG_REGS ? 0 : gen_rtx_REG (MODE, CUM))\
|
||||
: 0)
|
||||
|
||||
/* For an arg passed partly in registers and partly in memory,
|
||||
this is the number of registers used.
|
||||
For args passed entirely in registers or entirely in memory, zero. */
|
||||
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
|
||||
((CUM) < 16 && 16 < (CUM) + ((MODE) != BLKmode \
|
||||
? GET_MODE_SIZE (MODE) \
|
||||
: int_size_in_bytes (TYPE)) \
|
||||
? 4 - (CUM) / 4 : 0)
|
||||
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
|
||||
( NUM_ARG_REGS > (CUM) \
|
||||
&& (NUM_ARG_REGS < ((CUM) + NUM_REGS2 (MODE, TYPE))) \
|
||||
? NUM_ARG_REGS - (CUM) : 0)
|
||||
|
||||
/* A C type for declaring a variable that is used as the first argument of
|
||||
`FUNCTION_ARG' and other related values. For some target machines, the
|
||||
|
@ -1132,15 +1156,13 @@ enum reg_class
|
|||
For a library call, FNTYPE is 0.
|
||||
On the ARM, the offset starts at 0. */
|
||||
#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT) \
|
||||
((CUM) = (((FNTYPE) && aggregate_value_p (TREE_TYPE ((FNTYPE)))) ? 4 : 0))
|
||||
((CUM) = (((FNTYPE) && aggregate_value_p (TREE_TYPE ((FNTYPE)))) ? 1 : 0))
|
||||
|
||||
/* Update the data in CUM to advance over an argument
|
||||
of mode MODE and data type TYPE.
|
||||
(TYPE is null for libcalls where that information may not be available.) */
|
||||
#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
|
||||
(CUM) += ((MODE) != BLKmode \
|
||||
? (GET_MODE_SIZE (MODE) + 3) & ~3 \
|
||||
: (int_size_in_bytes (TYPE) + 3) & ~3) \
|
||||
#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
|
||||
(CUM) += NUM_REGS2 (MODE, TYPE)
|
||||
|
||||
/* 1 if N is a possible register number for function argument passing.
|
||||
On the ARM, r0-r3 are used to pass args. */
|
||||
|
@ -1160,12 +1182,12 @@ enum reg_class
|
|||
named arg and all anonymous args onto the stack.
|
||||
XXX I know the prologue shouldn't be pushing registers, but it is faster
|
||||
that way. */
|
||||
#define SETUP_INCOMING_VARARGS(CUM, MODE, TYPE, PRETEND_SIZE, NO_RTL) \
|
||||
#define SETUP_INCOMING_VARARGS(CUM, MODE, TYPE, PRETEND_SIZE, NO_RTL) \
|
||||
{ \
|
||||
extern int current_function_anonymous_args; \
|
||||
current_function_anonymous_args = 1; \
|
||||
if ((CUM) < 16) \
|
||||
(PRETEND_SIZE) = 16 - (CUM); \
|
||||
if ((CUM) < NUM_ARG_REGS) \
|
||||
(PRETEND_SIZE) = (NUM_ARG_REGS - (CUM)) * UNITS_PER_WORD; \
|
||||
}
|
||||
|
||||
/* Generate assembly output for the start of a function. */
|
||||
|
@ -1195,19 +1217,19 @@ enum reg_class
|
|||
|
||||
The ``mov ip,lr'' seems like a good idea to stick with cc convention.
|
||||
``prof'' doesn't seem to mind about this! */
|
||||
#define FUNCTION_PROFILER(STREAM,LABELNO) \
|
||||
{ \
|
||||
char temp[20]; \
|
||||
rtx sym; \
|
||||
\
|
||||
fprintf ((STREAM), "\tmov\t%s%s, %s%s\n\tbl\t", \
|
||||
REGISTER_PREFIX, reg_names[IP_REGNUM] /* ip */, \
|
||||
REGISTER_PREFIX, reg_names[LR_REGNUM] /* lr */); \
|
||||
assemble_name ((STREAM), ARM_MCOUNT_NAME); \
|
||||
fputc ('\n', (STREAM)); \
|
||||
ASM_GENERATE_INTERNAL_LABEL (temp, "LP", (LABELNO)); \
|
||||
sym = gen_rtx (SYMBOL_REF, Pmode, temp); \
|
||||
ASM_OUTPUT_INT ((STREAM), sym); \
|
||||
#define FUNCTION_PROFILER(STREAM, LABELNO) \
|
||||
{ \
|
||||
char temp[20]; \
|
||||
rtx sym; \
|
||||
\
|
||||
asm_fprintf (STREAM, "\tmov\t%R%s, %R%s\n\tbl\t", \
|
||||
reg_names[IP_REGNUM] /* ip */, \
|
||||
reg_names[LR_REGNUM] /* lr */); \
|
||||
assemble_name (STREAM, ARM_MCOUNT_NAME); \
|
||||
fputc ('\n', STREAM); \
|
||||
ASM_GENERATE_INTERNAL_LABEL (temp, "LP", LABELNO); \
|
||||
sym = gen_rtx (SYMBOL_REF, Pmode, temp); \
|
||||
ASM_OUTPUT_INT (STREAM, sym); \
|
||||
}
|
||||
|
||||
/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
|
||||
|
@ -1221,7 +1243,7 @@ enum reg_class
|
|||
|
||||
/* Generate the assembly code for function exit. */
|
||||
#define FUNCTION_EPILOGUE(STREAM, SIZE) \
|
||||
output_func_epilogue ((STREAM), (SIZE))
|
||||
output_func_epilogue (STREAM, SIZE)
|
||||
|
||||
/* Determine if the epilogue should be output as RTL.
|
||||
You should override this if you define FUNCTION_EXTRA_EPILOGUE. */
|
||||
|
@ -1241,10 +1263,10 @@ enum reg_class
|
|||
pointer. */
|
||||
|
||||
#define ELIMINABLE_REGS \
|
||||
{{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
|
||||
{ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
|
||||
{FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
|
||||
{FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
|
||||
{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
|
||||
{ ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }, \
|
||||
{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
|
||||
{ FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }}
|
||||
|
||||
/* Given FROM and TO register numbers, say whether this elimination is allowed.
|
||||
Frame pointer elimination is automatically handled.
|
||||
|
@ -1266,7 +1288,7 @@ enum reg_class
|
|||
else if ((FROM) == FRAME_POINTER_REGNUM \
|
||||
&& (TO) == STACK_POINTER_REGNUM) \
|
||||
(OFFSET) = (current_function_outgoing_args_size \
|
||||
+ ((get_frame_size () + 3) & ~3)); \
|
||||
+ NUM_INTS (get_frame_size ())); \
|
||||
else \
|
||||
{ \
|
||||
int regno; \
|
||||
|
@ -1295,7 +1317,7 @@ enum reg_class
|
|||
&& (regs_ever_live[LR_REGNUM] || saved_hard_reg)) \
|
||||
offset += 4; \
|
||||
offset += current_function_outgoing_args_size; \
|
||||
(OFFSET) = ((get_frame_size () + 3) & ~3) + offset; \
|
||||
(OFFSET) = NUM_INTS (get_frame_size ()) + offset; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
@ -1343,9 +1365,9 @@ enum reg_class
|
|||
/* Addressing modes, and classification of registers for them. */
|
||||
|
||||
#define HAVE_POST_INCREMENT 1
|
||||
#define HAVE_PRE_INCREMENT 1
|
||||
#define HAVE_PRE_INCREMENT 1
|
||||
#define HAVE_POST_DECREMENT 1
|
||||
#define HAVE_PRE_DECREMENT 1
|
||||
#define HAVE_PRE_DECREMENT 1
|
||||
|
||||
/* Macros to check register numbers against specific register classes. */
|
||||
|
||||
|
@ -1780,7 +1802,7 @@ enum reg_class
|
|||
|| (X) == arg_pointer_rtx)
|
||||
|
||||
#define DEFAULT_RTX_COSTS(X, CODE, OUTER_CODE) \
|
||||
return arm_rtx_costs (X, CODE);
|
||||
return arm_rtx_costs (X, CODE);
|
||||
|
||||
/* Moves to and from memory are quite expensive */
|
||||
#define MEMORY_MOVE_COST(MODE,CLASS,IN) 10
|
||||
|
@ -1804,8 +1826,6 @@ enum reg_class
|
|||
|| GET_RTX_CLASS (GET_CODE (XEXP (X, 1))) == 'c') \
|
||||
? 1 : 0)) \
|
||||
: 4)))))
|
||||
|
||||
|
||||
|
||||
/* Try to generate sequences that don't involve branches, we can then use
|
||||
conditional instructions */
|
||||
|
@ -1813,8 +1833,8 @@ enum reg_class
|
|||
|
||||
/* A C statement to update the variable COST based on the relationship
|
||||
between INSN that is dependent on DEP through dependence LINK. */
|
||||
#define ADJUST_COST(INSN,LINK,DEP,COST) \
|
||||
(COST) = arm_adjust_cost ((INSN), (LINK), (DEP), (COST))
|
||||
#define ADJUST_COST(INSN, LINK, DEP, COST) \
|
||||
(COST) = arm_adjust_cost (INSN, LINK, DEP, COST)
|
||||
|
||||
/* Position Independent Code. */
|
||||
/* We decide which register to use based on the compilation options and
|
||||
|
@ -1932,8 +1952,6 @@ extern struct rtx_def * arm_compare_op1;
|
|||
do \
|
||||
{ \
|
||||
char * s = (char *) alloca (40 + strlen (PREFIX)); \
|
||||
extern int arm_target_label, arm_ccfsm_state; \
|
||||
extern rtx arm_target_insn; \
|
||||
\
|
||||
if (arm_ccfsm_state == 3 && arm_target_label == (NUM) \
|
||||
&& !strcmp (PREFIX, "L")) \
|
||||
|
@ -1948,13 +1966,21 @@ extern struct rtx_def * arm_compare_op1;
|
|||
#endif
|
||||
|
||||
/* Output a push or a pop instruction (only used when profiling). */
|
||||
#define ASM_OUTPUT_REG_PUSH(STREAM,REGNO) \
|
||||
fprintf (STREAM,"\tstmfd\t%ssp!,{%s%s}\n", \
|
||||
REGISTER_PREFIX, REGISTER_PREFIX, reg_names [REGNO])
|
||||
#define ASM_OUTPUT_REG_PUSH(STREAM, REGNO) \
|
||||
asm_fprintf (STREAM,"\tstmfd\t%Rsp!,{%R%s}\n", \
|
||||
reg_names [REGNO])
|
||||
|
||||
#define ASM_OUTPUT_REG_POP(STREAM,REGNO) \
|
||||
fprintf (STREAM,"\tldmfd\t%ssp!,{%s%s}\n", \
|
||||
REGISTER_PREFIX, REGISTER_PREFIX, reg_names [REGNO])
|
||||
#define ASM_OUTPUT_REG_POP(STREAM, REGNO) \
|
||||
asm_fprintf (STREAM,"\tldmfd\t%Rsp!,{%R%s}\n", \
|
||||
reg_names [REGNO])
|
||||
|
||||
#define ARM_DECLARE_FUNCTION_NAME(STREAM, NAME, DECL) \
|
||||
do \
|
||||
{ \
|
||||
if (TARGET_POKE_FUNCTION_NAME) \
|
||||
arm_poke_function_name (STREAM, NAME); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* Target characters. */
|
||||
#define TARGET_BELL 007
|
||||
|
@ -1973,6 +1999,7 @@ extern struct rtx_def * arm_compare_op1;
|
|||
|
||||
#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \
|
||||
((CODE) == '?' || (CODE) == '|' || (CODE) == '@')
|
||||
|
||||
/* Output an operand of an instruction. */
|
||||
#define PRINT_OPERAND(STREAM, X, CODE) \
|
||||
arm_print_operand (STREAM, X, CODE)
|
||||
|
@ -1991,8 +2018,7 @@ extern struct rtx_def * arm_compare_op1;
|
|||
int is_minus = GET_CODE (X) == MINUS; \
|
||||
\
|
||||
if (GET_CODE (X) == REG) \
|
||||
fprintf (STREAM, "[%s%s, #0]", REGISTER_PREFIX, \
|
||||
reg_names[REGNO (X)]); \
|
||||
asm_fprintf (STREAM, "[%R%s, #0]", reg_names[REGNO (X)]); \
|
||||
else if (GET_CODE (X) == PLUS || is_minus) \
|
||||
{ \
|
||||
rtx base = XEXP (X, 0); \
|
||||
|
@ -2013,14 +2039,13 @@ extern struct rtx_def * arm_compare_op1;
|
|||
offset = INTVAL (index); \
|
||||
if (is_minus) \
|
||||
offset = -offset; \
|
||||
fprintf (STREAM, "[%s%s, #%d]", REGISTER_PREFIX, \
|
||||
base_reg_name, offset); \
|
||||
asm_fprintf (STREAM, "[%R%s, #%d]", base_reg_name, offset); \
|
||||
break; \
|
||||
\
|
||||
case REG: \
|
||||
fprintf (STREAM, "[%s%s, %s%s%s]", REGISTER_PREFIX, \
|
||||
base_reg_name, is_minus ? "-" : "", \
|
||||
REGISTER_PREFIX, reg_names[REGNO (index)] ); \
|
||||
asm_fprintf (STREAM, "[%R%s, %s%R%s]", \
|
||||
base_reg_name, is_minus ? "-" : "", \
|
||||
reg_names[REGNO (index)] ); \
|
||||
break; \
|
||||
\
|
||||
case MULT: \
|
||||
|
@ -2029,9 +2054,9 @@ extern struct rtx_def * arm_compare_op1;
|
|||
case ASHIFT: \
|
||||
case ROTATERT: \
|
||||
{ \
|
||||
fprintf (STREAM, "[%s%s, %s%s%s", REGISTER_PREFIX, \
|
||||
base_reg_name, is_minus ? "-" : "", REGISTER_PREFIX,\
|
||||
reg_names[REGNO (XEXP (index, 0))]); \
|
||||
asm_fprintf (STREAM, "[%R%s, %s%R%s", \
|
||||
base_reg_name, is_minus ? "-" : "", \
|
||||
reg_names[REGNO (XEXP (index, 0))]); \
|
||||
arm_print_operand (STREAM, index, 'S'); \
|
||||
fputs ("]", STREAM); \
|
||||
break; \
|
||||
|
@ -2050,15 +2075,15 @@ extern struct rtx_def * arm_compare_op1;
|
|||
abort (); \
|
||||
\
|
||||
if (GET_CODE (X) == PRE_DEC || GET_CODE (X) == PRE_INC) \
|
||||
fprintf (STREAM, "[%s%s, #%s%d]!", REGISTER_PREFIX, \
|
||||
reg_names[REGNO (XEXP (X, 0))], \
|
||||
GET_CODE (X) == PRE_DEC ? "-" : "", \
|
||||
GET_MODE_SIZE (output_memory_reference_mode)); \
|
||||
asm_fprintf (STREAM, "[%R%s, #%s%d]!", \
|
||||
reg_names[REGNO (XEXP (X, 0))], \
|
||||
GET_CODE (X) == PRE_DEC ? "-" : "", \
|
||||
GET_MODE_SIZE (output_memory_reference_mode)); \
|
||||
else \
|
||||
fprintf (STREAM, "[%s%s], #%s%d", REGISTER_PREFIX, \
|
||||
reg_names[REGNO (XEXP (X, 0))], \
|
||||
GET_CODE (X) == POST_DEC ? "-" : "", \
|
||||
GET_MODE_SIZE (output_memory_reference_mode)); \
|
||||
asm_fprintf (STREAM, "[%R%s], #%s%d", \
|
||||
reg_names[REGNO (XEXP (X, 0))], \
|
||||
GET_CODE (X) == POST_DEC ? "-" : "", \
|
||||
GET_MODE_SIZE (output_memory_reference_mode)); \
|
||||
} \
|
||||
else output_addr_const (STREAM, X); \
|
||||
}
|
||||
|
@ -2106,10 +2131,10 @@ extern struct rtx_def * arm_compare_op1;
|
|||
shift += 2; \
|
||||
else \
|
||||
{ \
|
||||
fprintf (FILE, "\t%s\t%s%s, %s%s, #%d\n", \
|
||||
mi_op, REGISTER_PREFIX, reg_names[this_regno], \
|
||||
REGISTER_PREFIX, reg_names[this_regno], \
|
||||
mi_delta & (0xff << shift)); \
|
||||
asm_fprintf (FILE, "\t%s\t%R%s, %R%s, #%d\n", \
|
||||
mi_op, reg_names[this_regno], \
|
||||
reg_names[this_regno], \
|
||||
mi_delta & (0xff << shift)); \
|
||||
mi_delta &= ~(0xff << shift); \
|
||||
shift += 8; \
|
||||
} \
|
||||
|
@ -2168,11 +2193,13 @@ struct rtx_def;
|
|||
#ifndef HOST_WIDE_INT
|
||||
#include "hwint.h"
|
||||
#endif
|
||||
|
||||
#define Hint HOST_WIDE_INT
|
||||
|
||||
#ifndef HAVE_MACHINE_MODES
|
||||
#include "machmode.h"
|
||||
#endif
|
||||
|
||||
#define Mmode enum machine_mode
|
||||
|
||||
#ifdef RTX_CODE
|
||||
|
@ -2180,6 +2207,7 @@ struct rtx_def;
|
|||
#else
|
||||
#define RTX_CODE_PROTO(ARGS) ()
|
||||
#endif
|
||||
|
||||
#define Rcode enum rtx_code
|
||||
|
||||
void arm_override_options PROTO ((void));
|
||||
|
|
|
@ -79,6 +79,7 @@ extern int arm_structure_size_boundary;
|
|||
extern char * version_string; \
|
||||
fprintf (STREAM, "%s Generated by gcc %s for ARM/coff\n", \
|
||||
ASM_COMMENT_START, version_string); \
|
||||
fprintf (STREAM, ASM_APP_OFF); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
|
|
|
@ -32,8 +32,8 @@ Boston, MA 02111-1307, USA. */
|
|||
#define USER_LABEL_PREFIX ""
|
||||
#endif
|
||||
|
||||
#ifndef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES "-Darm -Darm_elf -Acpu(arm) -Amachine(arm) -D__ELF__"
|
||||
#ifndef SUBTARGET_CPP_SPEC
|
||||
#define SUBTARGET_CPP_SPEC "-Darm_elf -D__ELF__"
|
||||
#endif
|
||||
|
||||
/* The following macro defines the format used to output the second
|
||||
|
@ -63,8 +63,7 @@ Boston, MA 02111-1307, USA. */
|
|||
#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
|
||||
do \
|
||||
{ \
|
||||
if (TARGET_POKE_FUNCTION_NAME) \
|
||||
arm_poke_function_name (FILE, NAME); \
|
||||
ARM_DECLARE_FUNCTION_NAME (FILE, NAME, DECL); \
|
||||
fprintf (FILE, "\t%s\t ", TYPE_ASM_OP); \
|
||||
assemble_name (FILE, NAME); \
|
||||
putc (',', FILE); \
|
||||
|
@ -211,7 +210,8 @@ extern int arm_structure_size_boundary;
|
|||
extern char * version_string; \
|
||||
fprintf (STREAM, "%s Generated by gcc %s for ARM/elf\n", \
|
||||
ASM_COMMENT_START, version_string); \
|
||||
output_file_directive ((STREAM), main_input_filename); \
|
||||
output_file_directive (STREAM, main_input_filename); \
|
||||
fprintf (STREAM, ASM_APP_OFF); \
|
||||
} \
|
||||
while (0)
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue