summaryrefslogtreecommitdiff
path: root/gcc/config/arm
diff options
context:
space:
mode:
authornickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4>1999-07-17 13:44:35 +0000
committernickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4>1999-07-17 13:44:35 +0000
commit96576951fb9a51dea2470932eed1c2d8458a7e07 (patch)
tree3b52d8d7c13371005d2b44baaab9abe49e1622a1 /gcc/config/arm
parentf7eeddb63877cd633b2acb3b2319b82432cc4c93 (diff)
downloadgcc-96576951fb9a51dea2470932eed1c2d8458a7e07.tar.gz
General tidyup of header files.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@28138 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/arm')
-rw-r--r--gcc/config/arm/aout.h230
-rw-r--r--gcc/config/arm/arm.c210
-rw-r--r--gcc/config/arm/arm.h362
-rw-r--r--gcc/config/arm/coff.h1
-rw-r--r--gcc/config/arm/elf.h10
5 files changed, 450 insertions, 363 deletions
diff --git a/gcc/config/arm/aout.h b/gcc/config/arm/aout.h
index df1694aa9ca..1f3ee79596b 100644
--- a/gcc/config/arm/aout.h
+++ b/gcc/config/arm/aout.h
@@ -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_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_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_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); \
- }
-
-#define ASM_OUTPUT_SHORT(STREAM, EXP) \
- (fprintf (STREAM, "\t.short\t"), \
- output_addr_const (STREAM, (EXP)), \
- fputc ('\n', STREAM))
-
-#define ASM_OUTPUT_CHAR(STREAM, EXP) \
- (fprintf (STREAM, "\t.byte\t"), \
- output_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) \
+ do \
+ { \
+ fprintf (STREAM, "\t.short\t"); \
+ output_addr_const (STREAM, EXP); \
+ 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) \
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
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index be1fa62dd5a..a0945b302ef 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -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++;
- }
- else
- {
- fprintf (stream, "\\%03o", c);
- len_so_far +=4;
+ default:
+ if (c >= ' ' && c <= '~')
+ {
+ putc (c, stream);
+ len_so_far ++;
+ }
+ else
+ {
+ fprintf (stream, "\\%03o", c);
+ len_so_far += 4;
+ }
+ break;
}
-
- 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)
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 1fd92079612..6cabbb45844 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -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) \
+ asm_fprintf (STREAM,"\tldmfd\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 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));
diff --git a/gcc/config/arm/coff.h b/gcc/config/arm/coff.h
index 478ae620226..cb4bd9b597c 100644
--- a/gcc/config/arm/coff.h
+++ b/gcc/config/arm/coff.h
@@ -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)
diff --git a/gcc/config/arm/elf.h b/gcc/config/arm/elf.h
index eb2a4a7e602..37645355235 100644
--- a/gcc/config/arm/elf.h
+++ b/gcc/config/arm/elf.h
@@ -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