Commit aec3cfba by Nick Clifton Committed by Nick Clifton

Fix compile time warnings.

Improve target CPU selection.

From-SVN: r25824
parent 13bb79d4
Wed Mar 17 14:41:41 1999 Nick Clifton <nickc@cygnus.com>
* config/arm/aout.h (ASM_GENERATE_INTERNAL_LABEL): Fix compile
time warning.
* config/arm/arm.md: Fix various compile time warnings.
* config/arm/arm.h: Fix various compile time warnings. Add
function prototypes.
* config/arm/arm.c: Fix various compile time warnings.
(arm_override_options): Reorganise to seperate tuning from
targetting.
(bit_count): New function: Return a count of the number of bits
set in a word.
Wed Mar 17 21:29:12 1999 J"orn Rennecke <amylaar@cygnus.co.uk> Wed Mar 17 21:29:12 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
* reload1.c (eliminate_regs): Don't keep REG_DEAD notes around for * reload1.c (eliminate_regs): Don't keep REG_DEAD notes around for
......
...@@ -148,7 +148,7 @@ do { \ ...@@ -148,7 +148,7 @@ do { \
/* Make an internal label into a string. */ /* Make an internal label into a string. */
#ifndef ASM_GENERATE_INTERNAL_LABEL #ifndef ASM_GENERATE_INTERNAL_LABEL
#define ASM_GENERATE_INTERNAL_LABEL(STRING, PREFIX, NUM) \ #define ASM_GENERATE_INTERNAL_LABEL(STRING, PREFIX, NUM) \
sprintf (STRING, "*%s%s%d", LOCAL_LABEL_PREFIX, PREFIX, NUM) sprintf (STRING, "*%s%s%u", LOCAL_LABEL_PREFIX, PREFIX, (unsigned int)(NUM))
#endif #endif
/* Nothing special is done about jump tables */ /* Nothing special is done about jump tables */
......
...@@ -37,6 +37,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -37,6 +37,7 @@ Boston, MA 02111-1307, USA. */
#include "tree.h" #include "tree.h"
#include "expr.h" #include "expr.h"
#include "toplev.h" #include "toplev.h"
#include "recog.h"
/* The maximum number of insns skipped which will be conditionalised if /* The maximum number of insns skipped which will be conditionalised if
possible. */ possible. */
...@@ -70,7 +71,6 @@ static enum arm_cond_code get_arm_condition_code PROTO ((rtx)); ...@@ -70,7 +71,6 @@ static enum arm_cond_code get_arm_condition_code PROTO ((rtx));
/* Define the information needed to generate branch insns. This is /* Define the information needed to generate branch insns. This is
stored from the compare operation. */ stored from the compare operation. */
rtx arm_compare_op0, arm_compare_op1; rtx arm_compare_op0, arm_compare_op1;
int arm_compare_fp; int arm_compare_fp;
...@@ -90,13 +90,34 @@ char * target_fp_name = NULL; ...@@ -90,13 +90,34 @@ char * target_fp_name = NULL;
char * structure_size_string = NULL; char * structure_size_string = NULL;
int arm_structure_size_boundary = 32; /* Used to be 8 */ int arm_structure_size_boundary = 32; /* Used to be 8 */
/* Bit values used to identify processor capabilities. */
#define FL_CO_PROC 0x01 /* Has external co-processor bus */
#define FL_FAST_MULT 0x02 /* Fast multiply */
#define FL_MODE26 0x04 /* 26-bit mode support */
#define FL_MODE32 0x08 /* 32-bit mode support */
#define FL_ARCH4 0x10 /* Architecture rel 4 */
#define FL_THUMB 0x20 /* Thumb aware */
#define FL_LDSCHED 0x40 /* Load scheduling necessary */
#define FL_STRONG 0x80 /* StrongARM */
/* The bits in this mask specify which instructions we are allowed to generate. */
static int insn_flags = 0;
/* The bits in this mask specify which instruction scheduling options should
be used. Note - there is an overlap with the FL_FAST_MULT. For some
hardware we want to be able to generate the multiply instructions, but to
tune as if they were not present in the architecture. */
static int tune_flags = 0;
/* The following are used in the arm.md file as equivalents to bits
in the above two flag variables. */
/* Nonzero if this is an "M" variant of the processor. */ /* Nonzero if this is an "M" variant of the processor. */
int arm_fast_multiply = 0; int arm_fast_multiply = 0;
/* Nonzero if this chip supports the ARM Architecture 4 extensions */ /* Nonzero if this chip supports the ARM Architecture 4 extensions */
int arm_arch4 = 0; int arm_arch4 = 0;
/* Nonzero if this chip can benefit from laod scheduling. */ /* Nonzero if this chip can benefit from load scheduling. */
int arm_ld_sched = 0; int arm_ld_sched = 0;
/* Nonzero if this chip is a StrongARM. */ /* Nonzero if this chip is a StrongARM. */
...@@ -125,11 +146,13 @@ int lr_save_eliminated; ...@@ -125,11 +146,13 @@ int lr_save_eliminated;
/* Set to 1 when a return insn is output, this means that the epilogue /* Set to 1 when a return insn is output, this means that the epilogue
is not needed. */ is not needed. */
static int return_used_this_function; static int return_used_this_function;
/* Set to 1 after arm_reorg has started. Reset to start at the start of
the next function. */
static int after_arm_reorg = 0; static int after_arm_reorg = 0;
/* The maximum number of insns to be used when loading a constant. */
static int arm_constant_limit = 3; static int arm_constant_limit = 3;
/* For an explanation of these variables, see final_prescan_insn below. */ /* For an explanation of these variables, see final_prescan_insn below. */
...@@ -151,15 +174,6 @@ static enum arm_cond_code get_arm_condition_code (); ...@@ -151,15 +174,6 @@ static enum arm_cond_code get_arm_condition_code ();
/* Initialization code */ /* Initialization code */
#define FL_CO_PROC 0x01 /* Has external co-processor bus */
#define FL_FAST_MULT 0x02 /* Fast multiply */
#define FL_MODE26 0x04 /* 26-bit mode support */
#define FL_MODE32 0x08 /* 32-bit mode support */
#define FL_ARCH4 0x10 /* Architecture rel 4 */
#define FL_THUMB 0x20 /* Thumb aware */
#define FL_LDSCHED 0x40 /* Load scheduling necessary */
#define FL_STRONG 0x80 /* StrongARM */
struct processors struct processors
{ {
char * name; char * name;
...@@ -233,14 +247,28 @@ struct arm_cpu_select arm_select[] = ...@@ -233,14 +247,28 @@ struct arm_cpu_select arm_select[] =
{ NULL, "-mtune=", all_cores } { NULL, "-mtune=", all_cores }
}; };
/* Return the number of bits set in value' */
static unsigned int
bit_count (value)
signed int value;
{
unsigned int count = 0;
while (value)
{
value &= ~(value & - value);
++ count;
}
return count;
}
/* Fix up any incompatible options that the user has specified. /* Fix up any incompatible options that the user has specified.
This has now turned into a maze. */ This has now turned into a maze. */
void void
arm_override_options () arm_override_options ()
{ {
unsigned int flags = 0;
unsigned i; unsigned i;
struct arm_cpu_select * ptr;
/* Set up the flags based on the cpu/architecture selected by the user. */ /* Set up the flags based on the cpu/architecture selected by the user. */
for (i = sizeof (arm_select) / sizeof (arm_select[0]); i--;) for (i = sizeof (arm_select) / sizeof (arm_select[0]); i--;)
...@@ -254,23 +282,20 @@ arm_override_options () ...@@ -254,23 +282,20 @@ arm_override_options ()
for (sel = ptr->processors; sel->name != NULL; sel ++) for (sel = ptr->processors; sel->name != NULL; sel ++)
if (streq (ptr->string, sel->name)) if (streq (ptr->string, sel->name))
{ {
if (flags != 0) if (i == 2)
tune_flags = sel->flags;
else
{ {
/* We scan the arm_select array in the order: /* If we have been given an architecture and a processor
tune -> arch -> cpu make sure that they are compatible. We only generate
So if we have been asked to tune for, say, an ARM8, a warning though, and we prefer the CPU over the
but we are told that the cpu is only an ARM6, then architecture. */
we have problems. We detect this by seeing if the if (insn_flags != 0 && (insn_flags ^ sel->flags))
flags bits accumulated so far can be supported by the warning ("switch -mcpu=%s conflicts with -mtune= switch",
cpu/architecture type now being parsed. If they can, ptr->string);
then OR in any new bits. If they cannot then report
an error. */ insn_flags = sel->flags;
if ((flags & sel->flags) != flags)
error ("switch %s%s overridden by another switch",
ptr->string, sel->name );
} }
flags = sel->flags;
break; break;
} }
...@@ -279,97 +304,148 @@ arm_override_options () ...@@ -279,97 +304,148 @@ arm_override_options ()
error ("bad value (%s) for %s switch", ptr->string, ptr->name); error ("bad value (%s) for %s switch", ptr->string, ptr->name);
} }
} }
/* If the user did not specify a processor, choose one for them. */ /* If the user did not specify a processor, choose one for them. */
if (flags == 0) if (insn_flags == 0)
{ {
struct processors * sel; struct processors * sel;
int sought = 0; unsigned int sought;
static struct cpu_default
{
int cpu;
char * name;
}
cpu_defaults[] =
{
{ TARGET_CPU_arm2, "arm2" },
{ TARGET_CPU_arm6, "arm6" },
{ TARGET_CPU_arm610, "arm610" },
{ TARGET_CPU_arm7m, "arm7m" },
{ TARGET_CPU_arm7500fe, "arm7500fe" },
{ TARGET_CPU_arm7tdmi, "arm7tdmi" },
{ TARGET_CPU_arm8, "arm8" },
{ TARGET_CPU_arm810, "arm810" },
{ TARGET_CPU_arm9, "arm9" },
{ TARGET_CPU_strongarm, "strongarm" },
{ TARGET_CPU_generic, "arm" },
{ 0, 0 }
};
struct cpu_default * def;
/* Find the default. */
for (def = cpu_defaults; def->name; def ++)
if (def->cpu == TARGET_CPU_DEFAULT)
break;
/* Make sure we found the default CPU. */
if (def->name == NULL)
abort ();
/* Find the default CPU's flags. */
for (sel = all_cores; sel->name != NULL; sel ++)
if (streq (def->name, sel->name))
break;
if (sel->name == NULL)
abort ();
insn_flags = sel->flags;
/* Now check to see if the user has specified some command line
switch that require certain abilities from the cpu. */
sought = 0;
if (TARGET_THUMB_INTERWORK) if (TARGET_THUMB_INTERWORK)
{ {
sought |= FL_THUMB; sought |= (FL_THUMB | FL_MODE32);
/* Force apcs-32 to be used for Thumb targets. */ /* Force apcs-32 to be used for interworking. */
target_flags |= ARM_FLAG_APCS_32; target_flags |= ARM_FLAG_APCS_32;
/* There are no ARM processor that supports both APCS-26 and
interworking. Therefore we force FL_MODE26 to be removed
from insn_flags here (if it was set), so that the search
below will always be able to find a compatible processor. */
insn_flags &= ~ FL_MODE26;
} }
if (! TARGET_APCS_32) if (! TARGET_APCS_32)
sought |= FL_MODE26; sought |= FL_MODE26;
if (sought != 0) if (sought != 0 && ((sought & insn_flags) != sought))
{ {
for (sel = all_cores; sel->name != NULL; sel++) /* Try to locate a CPU type that supports all of the abilities
if ((sel->flags & sought) == sought) of the default CPU, plus the extra abilities requested by
{ the user. */
flags = sel->flags;
break;
}
if (sel->name == NULL)
fatal ("Unable to select a cpu that matches command line specification");
}
else
{
/* The user did not specify any command line switches that require
a certain kind of CPU. Use TARGET_CPU_DEFAULT instead. */
static struct cpu_default
{
int cpu;
char * name;
}
cpu_defaults[] =
{
{ TARGET_CPU_arm2, "arm2" },
{ TARGET_CPU_arm6, "arm6" },
{ TARGET_CPU_arm610, "arm610" },
{ TARGET_CPU_arm7m, "arm7m" },
{ TARGET_CPU_arm7500fe, "arm7500fe" },
{ TARGET_CPU_arm7tdmi, "arm7tdmi" },
{ TARGET_CPU_arm8, "arm8" },
{ TARGET_CPU_arm810, "arm810" },
{ TARGET_CPU_arm9, "arm9" },
{ TARGET_CPU_strongarm, "strongarm" },
{ TARGET_CPU_generic, "arm" },
{ 0, 0 }
};
struct cpu_default * def;
/* Find the default. */
for (def = cpu_defaults; def->name; def ++)
if (def->cpu == TARGET_CPU_DEFAULT)
break;
if (def->name == NULL)
abort ();
/* Find the default CPU's flags. */
for (sel = all_cores; sel->name != NULL; sel ++) for (sel = all_cores; sel->name != NULL; sel ++)
if (streq (def->name, sel->name)) if ((sel->flags & sought) == (sought | insn_flags))
break; break;
if (sel->name == NULL) if (sel->name == NULL)
abort (); {
unsigned int current_bit_count = 0;
struct processors * best_fit = NULL;
/* Ideally we would like to issue an error message here
saying that it was not possible to find a CPU compatible
with the default CPU, but which also supports the command
line options specified by the programmer, and so they
ought to use the -mcpu=<name> command line option to
override the default CPU type.
Unfortunately this does not work with multilibing. We
need to be able to support multilibs for -mapcs-26 and for
-mthumb-interwork and there is no CPU that can support both
options. Instead if we cannot find a cpu that has both the
characteristics of the default cpu and the given command line
options we scan the array again looking for a best match. */
for (sel = all_cores; sel->name != NULL; sel ++)
if ((sel->flags & sought) == sought)
{
unsigned int count;
count = bit_count (sel->flags & insn_flags);
flags = sel->flags; if (count >= current_bit_count)
{
best_fit = sel;
current_bit_count = count;
}
}
if (best_fit == NULL)
abort ();
else
sel = best_fit;
}
insn_flags = sel->flags;
} }
} }
/* If tuning has not been specified, tune for whichever processor or
architecture has been selected. */
if (tune_flags == 0)
tune_flags = insn_flags;
/* Make sure that the processor choice does not conflict with any of the /* Make sure that the processor choice does not conflict with any of the
other command line choices. */ other command line choices. */
if (TARGET_APCS_32 && !(flags & FL_MODE32)) if (TARGET_APCS_32 && !(insn_flags & FL_MODE32))
{ {
warning ("target CPU does not support APCS-32" ); /* If APCS-32 was not the default then it must have been set by the
user, so issue a warning message. If the user has specified
"-mapcs-32 -mcpu=arm2" then we loose here. */
if ((TARGET_DEFAULT & ARM_FLAG_APCS_32) == 0)
warning ("target CPU does not support APCS-32" );
target_flags &= ~ ARM_FLAG_APCS_32; target_flags &= ~ ARM_FLAG_APCS_32;
} }
else if (! TARGET_APCS_32 && !(flags & FL_MODE26)) else if (! TARGET_APCS_32 && !(insn_flags & FL_MODE26))
{ {
warning ("target CPU does not support APCS-26" ); warning ("target CPU does not support APCS-26" );
target_flags |= ARM_FLAG_APCS_32; target_flags |= ARM_FLAG_APCS_32;
} }
if (TARGET_THUMB_INTERWORK && !(flags & FL_THUMB)) if (TARGET_THUMB_INTERWORK && !(insn_flags & FL_THUMB))
{ {
warning ("target CPU does not support interworking" ); warning ("target CPU does not support interworking" );
target_flags &= ~ARM_FLAG_THUMB; target_flags &= ~ARM_FLAG_THUMB;
...@@ -388,52 +464,49 @@ arm_override_options () ...@@ -388,52 +464,49 @@ arm_override_options ()
warning ("-mapcs-stack-check incompatible with -mno-apcs-frame"); warning ("-mapcs-stack-check incompatible with -mno-apcs-frame");
target_flags |= ARM_FLAG_APCS_FRAME; target_flags |= ARM_FLAG_APCS_FRAME;
} }
if (write_symbols != NO_DEBUG && flag_omit_frame_pointer) if (write_symbols != NO_DEBUG && flag_omit_frame_pointer)
warning ("-g with -fomit-frame-pointer may not give sensible debugging"); warning ("-g with -fomit-frame-pointer may not give sensible debugging");
if (TARGET_POKE_FUNCTION_NAME) if (TARGET_POKE_FUNCTION_NAME)
target_flags |= ARM_FLAG_APCS_FRAME; target_flags |= ARM_FLAG_APCS_FRAME;
if (TARGET_APCS_REENT && flag_pic) if (TARGET_APCS_REENT && flag_pic)
fatal ("-fpic and -mapcs-reent are incompatible"); fatal ("-fpic and -mapcs-reent are incompatible");
if (TARGET_APCS_REENT) if (TARGET_APCS_REENT)
warning ("APCS reentrant code not supported. Ignored"); warning ("APCS reentrant code not supported. Ignored");
/* If stack checking is disabled, we can use r10 as the PIC register, /* If stack checking is disabled, we can use r10 as the PIC register,
which keeps r9 available. */ which keeps r9 available. */
if (flag_pic && ! TARGET_APCS_STACK) if (flag_pic && ! TARGET_APCS_STACK)
arm_pic_register = 10; arm_pic_register = 10;
/* Well, I'm about to have a go, but pic is NOT going to be compatible /* Well, I'm about to have a go, but pic is NOT going to be compatible
with APCS reentrancy, since that requires too much support in the with APCS reentrancy, since that requires too much support in the
assembler and linker, and the ARMASM assembler seems to lack some assembler and linker, and the ARMASM assembler seems to lack some
required directives. */ required directives. */
if (flag_pic) if (flag_pic)
warning ("Position independent code not supported"); warning ("Position independent code not supported");
if (TARGET_APCS_FLOAT) if (TARGET_APCS_FLOAT)
warning ("Passing floating point arguments in fp regs not yet supported"); warning ("Passing floating point arguments in fp regs not yet supported");
/* Initialise booleans used elsewhere in this file, and in arm.md */
arm_fast_multiply = (flags & FL_FAST_MULT) != 0;
arm_arch4 = (flags & FL_ARCH4) != 0;
arm_ld_sched = (flags & FL_LDSCHED) != 0;
arm_is_strong = (flags & FL_STRONG);
/* The arm.md file needs to know if theprocessor is an ARM6 or an ARM7 */ /* Initialise boolean versions of the flags, for use in the arm.md file. */
arm_is_6_or_7 = ((flags & (FL_MODE26 | FL_MODE32)) && !(flags & FL_ARCH4)); arm_fast_multiply = insn_flags & FL_FAST_MULT;
arm_arch4 = insn_flags & FL_ARCH4;
arm_ld_sched = tune_flags & FL_LDSCHED;
arm_is_strong = tune_flags & FL_STRONG;
arm_is_6_or_7 = ((tune_flags & (FL_MODE26 | FL_MODE32))
&& !(tune_flags & FL_ARCH4));
/* Default value for floating point code... if no co-processor /* Default value for floating point code... if no co-processor
bus, then schedule for emulated floating point. Otherwise, bus, then schedule for emulated floating point. Otherwise,
assume the user has an FPA. assume the user has an FPA.
Note: this does not prevent use of floating point instructions, Note: this does not prevent use of floating point instructions,
-msoft-float does that. */ -msoft-float does that. */
if ((flags & FL_CO_PROC) == 0) arm_fpu = (tune_flags & FL_CO_PROC) ? FP_HARD : FP_SOFT3;
arm_fpu = FP_SOFT3;
else
arm_fpu = FP_HARD;
if (target_fp_name) if (target_fp_name)
{ {
...@@ -450,12 +523,12 @@ arm_override_options () ...@@ -450,12 +523,12 @@ arm_override_options ()
if (TARGET_FPE && arm_fpu != FP_HARD) if (TARGET_FPE && arm_fpu != FP_HARD)
arm_fpu = FP_SOFT2; arm_fpu = FP_SOFT2;
/* For arm2/3 there is no need to do any scheduling if there is only /* For arm2/3 there is no need to do any scheduling if there is only
a floating point emulator, or we are doing software floating-point. */ a floating point emulator, or we are doing software floating-point. */
if ((TARGET_SOFT_FLOAT || arm_fpu != FP_HARD) && (flags & FL_MODE32) == 0) if ((TARGET_SOFT_FLOAT || arm_fpu != FP_HARD) && (tune_flags & FL_MODE32) == 0)
flag_schedule_insns = flag_schedule_insns_after_reload = 0; flag_schedule_insns = flag_schedule_insns_after_reload = 0;
arm_prog_mode = TARGET_APCS_32 ? PROG_MODE_PROG32 : PROG_MODE_PROG26; arm_prog_mode = TARGET_APCS_32 ? PROG_MODE_PROG32 : PROG_MODE_PROG26;
if (structure_size_string != NULL) if (structure_size_string != NULL)
...@@ -471,9 +544,9 @@ arm_override_options () ...@@ -471,9 +544,9 @@ arm_override_options ()
/* If optimizing for space, don't synthesize constants. /* If optimizing for space, don't synthesize constants.
For processors with load scheduling, it never costs more than 2 cycles For processors with load scheduling, it never costs more than 2 cycles
to load a constant, and the load scheduler may well reduce that to 1. */ to load a constant, and the load scheduler may well reduce that to 1. */
if (optimize_size || (flags & FL_LDSCHED)) if (optimize_size || (tune_flags & FL_LDSCHED))
arm_constant_limit = 1; arm_constant_limit = 1;
/* If optimizing for size, bump the number of instructions that we /* If optimizing for size, bump the number of instructions that we
are prepared to conditionally execute (even on a StrongARM). are prepared to conditionally execute (even on a StrongARM).
Otherwise for the StrongARM, which has early execution of branches, Otherwise for the StrongARM, which has early execution of branches,
...@@ -611,7 +684,11 @@ arm_split_constant (code, mode, val, target, source, subtargets) ...@@ -611,7 +684,11 @@ arm_split_constant (code, mode, val, target, source, subtargets)
them in-line, regardless of the cost. This is only likely to them in-line, regardless of the cost. This is only likely to
be more costly on chips that have load delay slots and we are be more costly on chips that have load delay slots and we are
compiling without running the scheduler (so no splitting compiling without running the scheduler (so no splitting
occurred before the final instruction emission. */ occurred before the final instruction emission).
Ref: gcc -O1 -mcpu=strongarm gcc.c-torture/compile/980506-2.c
gcc -O0 -mcpu=strongarm plumhall/c/conform/exprtest/assign.c
*/
if (! after_arm_reorg if (! after_arm_reorg
&& (arm_gen_constant (code, mode, val, target, source, 1, 0) && (arm_gen_constant (code, mode, val, target, source, 1, 0)
> arm_constant_limit + (code != SET))) > arm_constant_limit + (code != SET)))
...@@ -1671,7 +1748,7 @@ arm_rtx_costs (x, code, outer_code) ...@@ -1671,7 +1748,7 @@ arm_rtx_costs (x, code, outer_code)
int add_cost = const_ok_for_arm (i) ? 4 : 8; int add_cost = const_ok_for_arm (i) ? 4 : 8;
int j; int j;
/* Tune as appropriate */ /* Tune as appropriate */
int booth_unit_size = (arm_fast_multiply ? 8 : 2); int booth_unit_size = ((tune_flags & FL_FAST_MULT) ? 8 : 2);
for (j = 0; i && j < 32; j += booth_unit_size) for (j = 0; i && j < 32; j += booth_unit_size)
{ {
...@@ -1682,7 +1759,7 @@ arm_rtx_costs (x, code, outer_code) ...@@ -1682,7 +1759,7 @@ arm_rtx_costs (x, code, outer_code)
return add_cost; return add_cost;
} }
return ((arm_fast_multiply ? 8 : 30) return (((tune_flags & FL_FAST_MULT) ? 8 : 30)
+ (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4) + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4)
+ (REG_OR_SUBREG_REG (XEXP (x, 1)) ? 0 : 4)); + (REG_OR_SUBREG_REG (XEXP (x, 1)) ? 0 : 4));
...@@ -2227,7 +2304,7 @@ shift_operator (x, mode) ...@@ -2227,7 +2304,7 @@ shift_operator (x, mode)
enum rtx_code code = GET_CODE (x); enum rtx_code code = GET_CODE (x);
if (code == MULT) if (code == MULT)
return power_of_two_operand (XEXP (x, 1)); return power_of_two_operand (XEXP (x, 1), mode);
return (code == ASHIFT || code == ASHIFTRT || code == LSHIFTRT return (code == ASHIFT || code == ASHIFTRT || code == LSHIFTRT
|| code == ROTATERT); || code == ROTATERT);
...@@ -4317,7 +4394,7 @@ output_mov_double_arm_from_fpu (operands) ...@@ -4317,7 +4394,7 @@ output_mov_double_arm_from_fpu (operands)
char * char *
output_move_double (operands) output_move_double (operands)
rtx *operands; rtx * operands;
{ {
enum rtx_code code0 = GET_CODE (operands[0]); enum rtx_code code0 = GET_CODE (operands[0]);
enum rtx_code code1 = GET_CODE (operands[1]); enum rtx_code code1 = GET_CODE (operands[1]);
...@@ -4328,6 +4405,7 @@ output_move_double (operands) ...@@ -4328,6 +4405,7 @@ output_move_double (operands)
int reg0 = REGNO (operands[0]); int reg0 = REGNO (operands[0]);
otherops[0] = gen_rtx_REG (SImode, 1 + reg0); otherops[0] = gen_rtx_REG (SImode, 1 + reg0);
if (code1 == REG) if (code1 == REG)
{ {
int reg1 = REGNO (operands[1]); int reg1 = REGNO (operands[1]);
...@@ -4430,7 +4508,8 @@ output_move_double (operands) ...@@ -4430,7 +4508,8 @@ output_move_double (operands)
break; break;
default: default:
if (arm_add_operand (XEXP (XEXP (operands[1], 0), 1))) if (arm_add_operand (XEXP (XEXP (operands[1], 0), 1),
GET_MODE (XEXP (XEXP (operands[1], 0), 1))))
{ {
otherops[0] = operands[0]; otherops[0] = operands[0];
otherops[1] = XEXP (XEXP (operands[1], 0), 0); otherops[1] = XEXP (XEXP (operands[1], 0), 0);
......
...@@ -823,12 +823,12 @@ enum reg_class ...@@ -823,12 +823,12 @@ enum reg_class
/* Define which registers fit in which classes. /* Define which registers fit in which classes.
This is an initializer for a vector of HARD_REG_SET This is an initializer for a vector of HARD_REG_SET
of length N_REG_CLASSES. */ of length N_REG_CLASSES. */
#define REG_CLASS_CONTENTS \ #define REG_CLASS_CONTENTS \
{ \ { \
0x0000000, /* NO_REGS */ \ { 0x0000000 }, /* NO_REGS */ \
0x0FF0000, /* FPU_REGS */ \ { 0x0FF0000 }, /* FPU_REGS */ \
0x200FFFF, /* GENERAL_REGS */ \ { 0x200FFFF }, /* GENERAL_REGS */ \
0x2FFFFFF /* ALL_REGS */ \ { 0x2FFFFFF } /* ALL_REGS */ \
} }
/* The same information, inverted: /* The same information, inverted:
...@@ -1037,7 +1037,7 @@ do { \ ...@@ -1037,7 +1037,7 @@ do { \
/* 1 if N is a possible register number for a function value. /* 1 if N is a possible register number for a function value.
On the ARM, only r0 and f0 can return results. */ On the ARM, only r0 and f0 can return results. */
#define FUNCTION_VALUE_REGNO_P(REGNO) \ #define FUNCTION_VALUE_REGNO_P(REGNO) \
((REGNO) == 0 || ((REGNO) == 16) && TARGET_HARD_FLOAT) ((REGNO) == 0 || (((REGNO) == 16) && TARGET_HARD_FLOAT))
/* How large values are returned */ /* How large values are returned */
/* A C expression which can inhibit the returning of certain function values /* A C expression which can inhibit the returning of certain function values
...@@ -1200,7 +1200,7 @@ do { \ ...@@ -1200,7 +1200,7 @@ do { \
else if ((FROM) == FRAME_POINTER_REGNUM \ else if ((FROM) == FRAME_POINTER_REGNUM \
&& (TO) == STACK_POINTER_REGNUM) \ && (TO) == STACK_POINTER_REGNUM) \
(OFFSET) = (current_function_outgoing_args_size \ (OFFSET) = (current_function_outgoing_args_size \
+ (get_frame_size () + 3 & ~3)); \ + ((get_frame_size () + 3) & ~3)); \
else \ else \
{ \ { \
int regno; \ int regno; \
...@@ -1226,7 +1226,7 @@ do { \ ...@@ -1226,7 +1226,7 @@ do { \
&& (regs_ever_live[14] || saved_hard_reg)) \ && (regs_ever_live[14] || saved_hard_reg)) \
offset += 4; \ offset += 4; \
offset += current_function_outgoing_args_size; \ offset += current_function_outgoing_args_size; \
(OFFSET) = (get_frame_size () + 3 & ~3) + offset; \ (OFFSET) = ((get_frame_size () + 3) & ~3) + offset; \
} \ } \
} \ } \
} }
...@@ -1784,12 +1784,10 @@ extern int arm_pic_register; ...@@ -1784,12 +1784,10 @@ extern int arm_pic_register;
"CC_DNE", "CC_DEQ", "CC_DLE", "CC_DLT", "CC_DGE", "CC_DGT", "CC_DLEU", \ "CC_DNE", "CC_DEQ", "CC_DLE", "CC_DLT", "CC_DGE", "CC_DGT", "CC_DLEU", \
"CC_DLTU", "CC_DGEU", "CC_DGTU", "CC_C" "CC_DLTU", "CC_DGEU", "CC_DGTU", "CC_C"
enum machine_mode arm_select_cc_mode ();
#define SELECT_CC_MODE(OP,X,Y) arm_select_cc_mode ((OP), (X), (Y)) #define SELECT_CC_MODE(OP,X,Y) arm_select_cc_mode ((OP), (X), (Y))
#define REVERSIBLE_CC_MODE(MODE) ((MODE) != CCFPEmode) #define REVERSIBLE_CC_MODE(MODE) ((MODE) != CCFPEmode)
enum rtx_code arm_canonicalize_comparison ();
#define CANONICALIZE_COMPARISON(CODE,OP0,OP1) \ #define CANONICALIZE_COMPARISON(CODE,OP0,OP1) \
do \ do \
{ \ { \
...@@ -2047,113 +2045,136 @@ do { \ ...@@ -2047,113 +2045,136 @@ do { \
when running in 32 bit mode. */ \ when running in 32 bit mode. */ \
((!TARGET_APCS_32) ? (GEN_INT (0x03fffffc)) : (GEN_INT (0xffffffff))) ((!TARGET_APCS_32) ? (GEN_INT (0x03fffffc)) : (GEN_INT (0xffffffff)))
/* Prototypes for arm.c -- actually, they aren't since the types aren't /* Prototypes for arm.c */
fully defined yet. */
#ifdef BUFSIZ /* stdio.h has been included, ok to use FILE * */
void arm_override_options PROTO ((void)); #define STDIO_PROTO(ARGS) PROTO (ARGS)
int use_return_insn PROTO ((int)); #else
int const_ok_for_arm (/* HOST_WIDE_INT */); #define STDIO_PROTO(ARGS) ()
int const_ok_for_op (/* HOST_WIDE_INT, enum rtx_code, #endif
enum machine_mode */);
int arm_split_constant (/* enum rtx_code, enum machine_mode, #ifndef TREE_CODE
HOST_WIDE_INT, struct rtx_def *, union tree_node;
struct rtx_def *, int */); #define Tree union tree_node *
enum rtx_code arm_canonicalize_comparison (/* enum rtx_code, #else
struct rtx_def ** */); #define Tree tree
int arm_return_in_memory (/* union tree_node * */); #endif
int legitimate_pic_operand_p (/* struct rtx_def * */);
struct rtx_def *legitimize_pic_address (/* struct rtx_def *, #ifndef RTX_CODE
enum machine_mode, struct rtx_def;
struct rtx_def * */); #define Rtx struct rtx_def *
int is_pic (/* struct rtx_def * */); #else
void arm_finalize_pic (/* void */); #define Rtx rtx
int arm_rtx_costs (/* struct rtx_def *, enum rtx_code, enum rtx_code */); #endif
int arm_adjust_cost (/* struct rtx_def *, struct rtx_def *,
struct rtx_def *, int */); #ifndef HOST_WIDE_INT
int const_double_rtx_ok_for_fpu (/* struct rtx_def * */); #include "hwint.h"
int neg_const_double_rtx_ok_for_fpu (/* struct rtx_def * */); #endif
int s_register_operand (/* struct rtx_def *, enum machine_mode */); #define Hint HOST_WIDE_INT
int f_register_operand (/* struct rtx_def *, enum machine_mode */);
int reg_or_int_operand (/* struct rtx_def *, enum machine_mode */); #ifndef HAVE_MACHINE_MODES
int reload_memory_operand (/* struct rtx_def *, enum machine_mode */); #include "machmode.h"
int arm_rhs_operand (/* struct rtx_def *, enum machine_mode */); #endif
int arm_rhsm_operand (/* struct rtx_def *, enum machine_mode */); #define Mmode enum machine_mode
int arm_add_operand (/* struct rtx_def *, enum machine_mode */);
int arm_not_operand (/* struct rtx_def *, enum machine_mode */); #ifdef RTX_CODE
int offsettable_memory_operand (/* struct rtx_def *, enum machine_mode */); #define RTX_CODE_PROTO(ARGS) PROTO (ARGS)
int alignable_memory_operand (/* struct rtx_def *, enum machine_mode */); #else
int bad_signed_byte_operand (/* struct rtx_def *, enum machine_mode */); #define RTX_CODE_PROTO(ARGS) ()
int fpu_rhs_operand (/* struct rtx_def *, enum machine_mode */); #endif
int fpu_add_operand (/* struct rtx_def *, enum machine_mode */); #define Rcode enum rtx_code
int power_of_two_operand (/* struct rtx_def *, enum machine_mode */);
int di_operand (/* struct rtx_def *, enum machine_mode */); void arm_override_options PROTO ((void));
int soft_df_operand (/* struct rtx_def *, enum machine_mode */); int use_return_insn PROTO ((int));
int index_operand (/* struct rtx_def *, enum machine_mode */); int const_ok_for_arm PROTO ((Hint));
int const_shift_operand (/* struct rtx_def *, enum machine_mode */); int const_ok_for_op RTX_CODE_PROTO ((Hint, Rcode, Mmode));
int shiftable_operator (/* struct rtx_def *, enum machine_mode */); int arm_split_constant RTX_CODE_PROTO ((Rcode, Mmode, Hint, Rtx, Rtx, int));
int shift_operator (/* struct rtx_def *, enum machine_mode */); Rcode arm_canonicalize_comparison RTX_CODE_PROTO ((Rcode, Rtx *));
int equality_operator (/* struct rtx_def *, enum machine_mode */); int arm_return_in_memory PROTO ((Tree));
int minmax_operator (/* struct rtx_def *, enum machine_mode */); int legitimate_pic_operand_p PROTO ((Rtx));
int cc_register (/* struct rtx_def *, enum machine_mode */); Rtx legitimize_pic_address PROTO ((Rtx, Mmode, Rtx));
int dominant_cc_register (/* struct rtx_def *, enum machine_mode */); int is_pic PROTO ((Rtx));
int symbol_mentioned_p (/* struct rtx_def * */); void arm_finalize_pic PROTO ((void));
int label_mentioned_p (/* struct rtx_def * */); int arm_rtx_costs RTX_CODE_PROTO ((Rtx, Rcode, Rcode));
enum rtx_code minmax_code (/* struct rtx_def * */); int arm_adjust_cost PROTO ((Rtx, Rtx, Rtx, int));
int adjacent_mem_locations (/* struct rtx_def *, struct rtx_def * */); int const_double_rtx_ok_for_fpu PROTO ((Rtx));
int load_multiple_operation (/* struct rtx_def *, enum machine_mode */); int neg_const_double_rtx_ok_for_fpu PROTO ((Rtx));
int store_multiple_operation (/* struct rtx_def *, enum machine_mode */); int s_register_operand PROTO ((Rtx, Mmode));
int load_multiple_sequence (/* struct rtx_def **, int, int *, int *, int f_register_operand PROTO ((Rtx, Mmode));
HOST_WIDE_INT * */); int reg_or_int_operand PROTO ((Rtx, Mmode));
char *emit_ldm_seq (/* struct rtx_def **, int */); int reload_memory_operand PROTO ((Rtx, Mmode));
int store_multiple_sequence (/* struct rtx_def **, int, int *, int *, int arm_rhs_operand PROTO ((Rtx, Mmode));
HOST_WIDE_INT * */); int arm_rhsm_operand PROTO ((Rtx, Mmode));
char *emit_stm_seq (/* struct rtx_def **, int */); int arm_add_operand PROTO ((Rtx, Mmode));
int multi_register_push (/* struct rtx_def *, enum machine_mode */); int arm_not_operand PROTO ((Rtx, Mmode));
int arm_valid_machine_decl_attribute (/* union tree_node *, union tree_node *, int offsettable_memory_operand PROTO ((Rtx, Mmode));
union tree_node *, int alignable_memory_operand PROTO ((Rtx, Mmode));
union tree_node * */); int bad_signed_byte_operand PROTO ((Rtx, Mmode));
struct rtx_def *arm_gen_load_multiple (/* int, int, struct rtx_def *, int fpu_rhs_operand PROTO ((Rtx, Mmode));
int, int, int, int, int */); int fpu_add_operand PROTO ((Rtx, Mmode));
struct rtx_def *arm_gen_store_multiple (/* int, int, struct rtx_def *, int power_of_two_operand PROTO ((Rtx, Mmode));
int, int, int, int, int */); int di_operand PROTO ((Rtx, Mmode));
int arm_gen_movstrqi (/* struct rtx_def ** */); int soft_df_operand PROTO ((Rtx, Mmode));
struct rtx_def *gen_rotated_half_load (/* struct rtx_def * */); int index_operand PROTO ((Rtx, Mmode));
enum machine_mode arm_select_cc_mode (/* enum rtx_code, struct rtx_def *, int const_shift_operand PROTO ((Rtx, Mmode));
struct rtx_def * */); int shiftable_operator PROTO ((Rtx, Mmode));
struct rtx_def *gen_compare_reg (/* enum rtx_code, struct rtx_def *, int shift_operator PROTO ((Rtx, Mmode));
struct rtx_def * */); int equality_operator PROTO ((Rtx, Mmode));
void arm_reload_in_hi (/* struct rtx_def ** */); int minmax_operator PROTO ((Rtx, Mmode));
void arm_reload_out_hi (/* struct rtx_def ** */); int cc_register PROTO ((Rtx, Mmode));
void arm_reorg (/* struct rtx_def * */); int dominant_cc_register PROTO ((Rtx, Mmode));
char *fp_immediate_constant (/* struct rtx_def * */); int symbol_mentioned_p PROTO ((Rtx));
void print_multi_reg (/* FILE *, char *, int, int */); int label_mentioned_p PROTO ((Rtx));
char *output_call (/* struct rtx_def ** */); Rcode minmax_code PROTO ((Rtx));
char *output_call_mem (/* struct rtx_def ** */); int adjacent_mem_locations PROTO ((Rtx, Rtx));
char *output_mov_long_double_fpu_from_arm (/* struct rtx_def ** */); int load_multiple_operation PROTO ((Rtx, Mmode));
char *output_mov_long_double_arm_from_fpu (/* struct rtx_def ** */); int store_multiple_operation PROTO ((Rtx, Mmode));
char *output_mov_long_double_arm_from_arm (/* struct rtx_def ** */); int load_multiple_sequence PROTO ((Rtx *, int, int *, int *, Hint *));
char *output_mov_double_fpu_from_arm (/* struct rtx_def ** */); char * emit_ldm_seq PROTO ((Rtx *, int));
char *output_mov_double_arm_from_fpu (/* struct rtx_def ** */); int store_multiple_sequence PROTO ((Rtx *, int, int *, int *, Hint *));
char *output_move_double (/* struct rtx_def ** */); char * emit_stm_seq PROTO ((Rtx *, int));
char *output_mov_immediate (/* struct rtx_def ** */); int arm_valid_machine_decl_attribute PROTO ((Tree, Tree, Tree, Tree));
char *output_add_immediate (/* struct rtx_def ** */); Rtx arm_gen_load_multiple PROTO ((int, int, Rtx, int, int, int, int, int));
char *arithmetic_instr (/* struct rtx_def *, int */); Rtx arm_gen_store_multiple PROTO ((int, int, Rtx, int, int, int, int, int));
void output_ascii_pseudo_op (/* FILE *, unsigned char *, int */); int arm_gen_movstrqi PROTO ((Rtx *));
char *output_return_instruction (/* struct rtx_def *, int, int */); Rtx gen_rotated_half_load PROTO ((Rtx));
int arm_volatile_func (/* void */); Mmode arm_select_cc_mode RTX_CODE_PROTO ((Rcode, Rtx, Rtx));
void output_func_prologue (/* FILE *, int */); Rtx gen_compare_reg RTX_CODE_PROTO ((Rcode, Rtx, Rtx, int));
void output_func_epilogue (/* FILE *, int */); void arm_reload_in_hi PROTO ((Rtx *));
void arm_expand_prologue (/* void */); void arm_reload_out_hi PROTO ((Rtx *));
void arm_print_operand (/* FILE *, struct rtx_def *, int */); void arm_reorg PROTO ((Rtx));
void final_prescan_insn (/* struct rtx_def *, struct rtx_def **, int */); char * fp_immediate_constant PROTO ((Rtx));
void print_multi_reg STDIO_PROTO ((FILE *, char *, int, int));
char * output_call PROTO ((Rtx *));
char * output_call_mem PROTO ((Rtx *));
char * output_mov_long_double_fpu_from_arm PROTO ((Rtx *));
char * output_mov_long_double_arm_from_fpu PROTO ((Rtx *));
char * output_mov_long_double_arm_from_arm PROTO ((Rtx *));
char * output_mov_double_fpu_from_arm PROTO ((Rtx *));
char * output_mov_double_arm_from_fpu PROTO ((Rtx *));
char * output_move_double PROTO ((Rtx *));
char * output_mov_immediate PROTO ((Rtx *));
char * output_add_immediate PROTO ((Rtx *));
char * arithmetic_instr PROTO ((Rtx, int));
void output_ascii_pseudo_op STDIO_PROTO ((FILE *, unsigned char *, int));
char * output_return_instruction PROTO ((Rtx, int, int));
int arm_volatile_func PROTO ((void));
void output_func_prologue STDIO_PROTO ((FILE *, int));
void output_func_epilogue STDIO_PROTO ((FILE *, int));
void arm_expand_prologue PROTO ((void));
void arm_print_operand STDIO_PROTO ((FILE *, Rtx, int));
void final_prescan_insn PROTO ((Rtx, Rtx *, int));
int short_branch PROTO ((int, int));
void assemble_align PROTO((int)); /* Used in arm.md, but defined in output.c */
int multi_register_push PROTO ((Rtx, Mmode));
#ifdef AOF_ASSEMBLER #ifdef AOF_ASSEMBLER
struct rtx_def *aof_pic_entry (/* struct rtx_def * */); Rtx aof_pic_entry PROTO ((Rtx));
void aof_dump_pic_table (/* FILE * */); void aof_dump_pic_table STDIO_PROTO ((FILE *));
char *aof_text_section (/* void */); char * aof_text_section PROTO ((void));
char *aof_data_section (/* void */); char * aof_data_section PROTO ((void));
void aof_add_import (/* char * */); void aof_add_import PROTO ((char *));
void aof_delete_import (/* char * */); void aof_delete_import PROTO ((char *));
void aof_dump_imports (/* FILE * */); void aof_dump_imports STDIO_PROTO ((FILE *));
#endif #endif
#endif /* __ARM_H__ */ #endif /* __ARM_H__ */
...@@ -2403,7 +2403,7 @@ ...@@ -2403,7 +2403,7 @@
"arm_arch4" "arm_arch4"
"* "*
/* If the address is invalid, this will split the instruction into two. */ /* If the address is invalid, this will split the instruction into two. */
if (bad_signed_byte_operand(operands[1], QImode)) if (bad_signed_byte_operand (operands[1], QImode))
return \"#\"; return \"#\";
return \"ldr%?sb\\t%0, %1\"; return \"ldr%?sb\\t%0, %1\";
" "
...@@ -2476,7 +2476,7 @@ ...@@ -2476,7 +2476,7 @@
"arm_arch4" "arm_arch4"
"* "*
/* If the address is invalid, this will split the instruction into two. */ /* If the address is invalid, this will split the instruction into two. */
if (bad_signed_byte_operand(operands[1], QImode)) if (bad_signed_byte_operand (operands[1], QImode))
return \"#\"; return \"#\";
return \"ldr%?sb\\t%0, %1\"; return \"ldr%?sb\\t%0, %1\";
" "
...@@ -2638,7 +2638,7 @@ ...@@ -2638,7 +2638,7 @@
(define_insn "*movsi_insn" (define_insn "*movsi_insn"
[(set (match_operand:SI 0 "general_operand" "=r,r,r,m") [(set (match_operand:SI 0 "general_operand" "=r,r,r,m")
(match_operand:SI 1 "general_operand" "rI,K,mi,r"))] (match_operand:SI 1 "general_operand" "rI,K,mi,r"))]
"register_operand (operands[0], SImode) "register_operand (operands[0], SImode)
|| register_operand (operands[1], SImode)" || register_operand (operands[1], SImode)"
"@ "@
...@@ -2852,8 +2852,6 @@ ...@@ -2852,8 +2852,6 @@
"" ""
" "
{ {
rtx insn;
if (! (reload_in_progress || reload_completed)) if (! (reload_in_progress || reload_completed))
{ {
if (GET_CODE (operands[0]) == MEM) if (GET_CODE (operands[0]) == MEM)
...@@ -3068,7 +3066,6 @@ ...@@ -3068,7 +3066,6 @@
") ")
;; Pattern to recognise insn generated default case above ;; Pattern to recognise insn generated default case above
(define_insn "*movhi_insn_arch4" (define_insn "*movhi_insn_arch4"
[(set (match_operand:HI 0 "general_operand" "=r,r,r,m") [(set (match_operand:HI 0 "general_operand" "=r,r,r,m")
(match_operand:HI 1 "general_operand" "rI,K,m,r"))] (match_operand:HI 1 "general_operand" "rI,K,m,r"))]
...@@ -3289,10 +3286,9 @@ ...@@ -3289,10 +3286,9 @@
|| register_operand (operands[1], DFmode))" || register_operand (operands[1], DFmode))"
"* "*
{ {
rtx ops[3];
switch (which_alternative) switch (which_alternative)
{ {
default:
case 0: return \"ldm%?ia\\t%m1, %M0\\t%@ double\"; case 0: return \"ldm%?ia\\t%m1, %M0\\t%@ double\";
case 1: return \"stm%?ia\\t%m0, %M1\\t%@ double\"; case 1: return \"stm%?ia\\t%m0, %M1\\t%@ double\";
case 2: case 3: case 4: return output_move_double (operands); case 2: case 3: case 4: return output_move_double (operands);
...@@ -3337,6 +3333,7 @@ ...@@ -3337,6 +3333,7 @@
"* "*
switch (which_alternative) switch (which_alternative)
{ {
default:
case 0: return \"mvf%?e\\t%0, %1\"; case 0: return \"mvf%?e\\t%0, %1\";
case 1: return \"mnf%?e\\t%0, #%N1\"; case 1: return \"mnf%?e\\t%0, #%N1\";
case 2: return \"ldf%?e\\t%0, %1\"; case 2: return \"ldf%?e\\t%0, %1\";
...@@ -6223,7 +6220,6 @@ ...@@ -6223,7 +6220,6 @@
"* "*
{ {
char pattern[100]; char pattern[100];
int i;
sprintf (pattern, \"sfmfd\\t%%1, %d, [%%m0]!\", XVECLEN (operands[2], 0)); sprintf (pattern, \"sfmfd\\t%%1, %d, [%%m0]!\", XVECLEN (operands[2], 0));
output_asm_insn (pattern, operands); output_asm_insn (pattern, operands);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment