Commit 6cfc7210 by Nick Clifton Committed by Nick Clifton

General tidyup of header files.

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