General tidyup of header files.

From-SVN: r28138
This commit is contained in:
Nick Clifton 1999-07-17 13:44:35 +00:00 committed by Nick Clifton
parent 8f7cbf1635
commit 6cfc7210fa
6 changed files with 485 additions and 359 deletions

View File

@ -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

View File

@ -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, &ltext_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, &ltext_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

View File

@ -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)

View File

@ -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));

View File

@ -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)

View File

@ -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