diff options
author | Nick Clifton <nickc@cygnus.com> | 1999-07-17 13:44:35 +0000 |
---|---|---|
committer | Nick Clifton <nickc@gcc.gnu.org> | 1999-07-17 13:44:35 +0000 |
commit | 6cfc7210fa88997c7b22415241c1b325b25bcb7b (patch) | |
tree | 3b52d8d7c13371005d2b44baaab9abe49e1622a1 /gcc/config/arm | |
parent | 8f7cbf16355cc9550397eb949f2d1ecbf8791040 (diff) | |
download | gcc-6cfc7210fa88997c7b22415241c1b325b25bcb7b.tar.gz |
General tidyup of header files.
From-SVN: r28138
Diffstat (limited to 'gcc/config/arm')
-rw-r--r-- | gcc/config/arm/aout.h | 230 | ||||
-rw-r--r-- | gcc/config/arm/arm.c | 210 | ||||
-rw-r--r-- | gcc/config/arm/arm.h | 362 | ||||
-rw-r--r-- | gcc/config/arm/coff.h | 1 | ||||
-rw-r--r-- | gcc/config/arm/elf.h | 10 |
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, <ext_label_name[1]); \ - text_section (); \ - ASM_OUTPUT_INTERNAL_LABEL (STREAM, "Ltext", 0); \ -} while (0) +#define DBX_OUTPUT_MAIN_SOURCE_FILENAME(STREAM, NAME) \ + do \ + { \ + fprintf (STREAM, ".stabs "); \ + output_quoted_string (STREAM, NAME); \ + fprintf (STREAM, ",%d,0,315,%s\n", N_SO, <ext_label_name[1]); \ + text_section (); \ + ASM_OUTPUT_INTERNAL_LABEL (STREAM, "Ltext", 0); \ + } \ + while (0) /* Output a function label definition. */ #ifndef ASM_DECLARE_FUNCTION_NAME -#define ASM_DECLARE_FUNCTION_NAME(STREAM,NAME,DECL) \ -{ \ - if (TARGET_POKE_FUNCTION_NAME) \ - arm_poke_function_name ((STREAM), (NAME)); \ - ASM_OUTPUT_LABEL (STREAM, NAME); \ -} +#define ASM_DECLARE_FUNCTION_NAME(STREAM, NAME, DECL) \ + do \ + { \ + ARM_DECLARE_FUNCTION_NAME (STREAM, NAME, DECL); \ + ASM_OUTPUT_LABEL (STREAM, NAME); \ + } \ + while (0) #endif #ifndef ASM_OUTPUT_LABEL -#define ASM_OUTPUT_LABEL(STREAM,NAME) \ -do { \ - assemble_name (STREAM,NAME); \ - fputs (":\n", STREAM); \ -} while (0) +#define ASM_OUTPUT_LABEL(STREAM, NAME) \ + do \ + { \ + assemble_name (STREAM,NAME); \ + fputs (":\n", STREAM); \ + } \ + while (0) #endif /* Output a globalising directive for a label. */ #ifndef ASM_GLOBALIZE_LABEL -#define ASM_GLOBALIZE_LABEL(STREAM,NAME) \ - (fprintf (STREAM, "\t.global\t"), \ - assemble_name (STREAM, NAME), \ - fputc ('\n',STREAM)) +#define ASM_GLOBALIZE_LABEL(STREAM, NAME) \ + do \ + { \ + fprintf (STREAM, "\t.global\t"); \ + assemble_name (STREAM, NAME); \ + fputc ('\n',STREAM); \ + } \ + while (0) #endif /* Make an internal label into a string. */ @@ -159,103 +168,122 @@ do { \ sprintf (STRING, "*%s%s%u", LOCAL_LABEL_PREFIX, PREFIX, (unsigned int)(NUM)) #endif -/* Nothing special is done about jump tables */ -/* #define ASM_OUTPUT_CASE_LABEL(STREAM,PREFIX,NUM,TABLE) */ -/* #define ASM_OUTPUT_CASE_END(STREAM,NUM,TABLE) */ - /* Construct a private name. */ -#define ASM_FORMAT_PRIVATE_NAME(OUTVAR,NAME,NUMBER) \ +#define ASM_FORMAT_PRIVATE_NAME(OUTVAR, NAME, NUMBER) \ ((OUTVAR) = (char *) alloca (strlen (NAME) + 10), \ - sprintf ((OUTVAR), "%s.%d", (NAME), (NUMBER))) + sprintf (OUTVAR, "%s.%d", NAME, NUMBER)) /* Output an element of a dispatch table. */ -#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM,VALUE) \ - fprintf (STREAM, "\t.word\t%sL%d\n", LOCAL_LABEL_PREFIX, VALUE) +#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \ + asm_fprintf (STREAM, "\t.word\t%LL%d\n", VALUE) -#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM,BODY,VALUE,REL) \ - fprintf (STREAM, "\tb\t%sL%d\n", LOCAL_LABEL_PREFIX, (VALUE)) +#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, BODY, VALUE, REL) \ + asm_fprintf (STREAM, "\tb\t%LL%d\n", VALUE) /* Output various types of constants. For real numbers we output hex, with a comment containing the "human" value, this allows us to pass NaN's which the riscix assembler doesn't understand (it also makes cross-assembling less likely to fail). */ -#define ASM_OUTPUT_LONG_DOUBLE(STREAM,VALUE) \ -do { char dstr[30]; \ - long l[3]; \ - REAL_VALUE_TO_TARGET_LONG_DOUBLE (VALUE, l); \ - REAL_VALUE_TO_DECIMAL (VALUE, "%.20g", dstr); \ - fprintf (STREAM, "\t.long 0x%lx,0x%lx,0x%lx\t%s long double %s\n", \ - l[0], l[1], l[2], ASM_COMMENT_START, dstr); \ - } while (0) - - -#define ASM_OUTPUT_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 |