aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/mn10300/mn10300.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/mn10300/mn10300.h')
-rw-r--r--gcc/config/mn10300/mn10300.h93
1 files changed, 71 insertions, 22 deletions
diff --git a/gcc/config/mn10300/mn10300.h b/gcc/config/mn10300/mn10300.h
index a7686ca..8e77acc 100644
--- a/gcc/config/mn10300/mn10300.h
+++ b/gcc/config/mn10300/mn10300.h
@@ -32,6 +32,8 @@ Boston, MA 02111-1307, USA. */
#define CPP_PREDEFINES "-D__mn10300__ -D__MN10300__"
+#define CPP_SPEC "%{mam33:-D__AM33__}"
+
/* Run-time compilation parameters selecting different hardware subsets. */
extern int target_flags;
@@ -46,9 +48,16 @@ extern int target_flags;
/* Generate code to work around mul/mulq bugs on the mn10300. */
#define TARGET_MULT_BUG (target_flags & 0x1)
+
+/* Generate code for the AM33 processor. */
+#define TARGET_AM33 (target_flags & 0x2)
+
#define TARGET_SWITCHES \
{{ "mult-bug", 0x1, "Work around hardware multiply bug"}, \
{ "no-mult-bug", -0x1, "Do not work around hardware multiply bug"},\
+ { "am33", 0x2}, \
+ { "am33", -(0x1)},\
+ { "no-am33", -0x2}, \
{ "", TARGET_DEFAULT, NULL}}
#ifndef TARGET_DEFAULT
@@ -134,13 +143,13 @@ extern int target_flags;
All registers that the compiler knows about must be given numbers,
even those that are not normally considered general registers. */
-#define FIRST_PSEUDO_REGISTER 10
+#define FIRST_PSEUDO_REGISTER 18
/* 1 for registers that have pervasive standard uses
and are not available for the register allocator. */
#define FIXED_REGISTERS \
- { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1}
+ { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}
/* 1 for registers not available across function calls.
These must include the FIXED_REGISTERS and also any
@@ -151,10 +160,19 @@ extern int target_flags;
like. */
#define CALL_USED_REGISTERS \
- { 1, 1, 0, 0, 1, 1, 0, 0, 1, 1}
+ { 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0}
#define REG_ALLOC_ORDER \
- { 0, 1, 4, 5, 2, 3, 6, 7, 8, 9}
+ { 0, 1, 4, 5, 2, 3, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 8, 9}
+
+#define CONDITIONAL_REGISTER_USAGE \
+{ \
+ if (!TARGET_AM33) \
+ { \
+ for (i = 10; i < 18; i++) \
+ fixed_regs[i] = call_used_regs[i] = 1; \
+ } \
+}
/* Return number of consecutive hard regs needed starting at reg REGNO
to hold something of mode MODE.
@@ -169,7 +187,9 @@ extern int target_flags;
MODE. */
#define HARD_REGNO_MODE_OK(REGNO, MODE) \
- (REGNO_REG_CLASS (REGNO) == DATA_REGS \
+ ((REGNO_REG_CLASS (REGNO) == DATA_REGS \
+ || (TARGET_AM33 && REGNO_REG_CLASS (REGNO) == ADDRESS_REGS) \
+ || REGNO_REG_CLASS (REGNO) == EXTENDED_REGS) \
? ((REGNO) & 1) == 0 || GET_MODE_SIZE (MODE) <= 4 \
: ((REGNO) & 1) == 0 || GET_MODE_SIZE (MODE) == 4)
@@ -178,7 +198,9 @@ extern int target_flags;
If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
for any hard reg, then this must be 0 for correct output. */
#define MODES_TIEABLE_P(MODE1, MODE2) \
- (MODE1 == MODE2 || (GET_MODE_SIZE (MODE1) <= 4 && GET_MODE_SIZE (MODE2) <= 4))
+ (TARGET_AM33 \
+ || MODE1 == MODE2 \
+ || (GET_MODE_SIZE (MODE1) <= 4 && GET_MODE_SIZE (MODE2) <= 4))
/* 4 data, and effectively 3 address registers is small as far as I'm
concerned. */
@@ -207,6 +229,8 @@ extern int target_flags;
enum reg_class {
NO_REGS, DATA_REGS, ADDRESS_REGS, SP_REGS,
DATA_OR_ADDRESS_REGS, SP_OR_ADDRESS_REGS,
+ EXTENDED_REGS, DATA_OR_EXTENDED_REGS, ADDRESS_OR_EXTENDED_REGS,
+ SP_OR_EXTENDED_REGS, SP_OR_ADDRESS_OR_EXTENDED_REGS,
GENERAL_REGS, ALL_REGS, LIM_REG_CLASSES
};
@@ -217,6 +241,9 @@ enum reg_class {
#define REG_CLASS_NAMES \
{ "NO_REGS", "DATA_REGS", "ADDRESS_REGS", \
"SP_REGS", "DATA_OR_ADDRESS_REGS", "SP_OR_ADDRESS_REGS", \
+ "EXTENDED_REGS", \
+ "DATA_OR_EXTENDED_REGS", "ADDRESS_OR_EXTENDED_REGS", \
+ "SP_OR_EXTENDED_REGS", "SP_OR_ADDRESS_OR_EXTENDED_REGS", \
"GENERAL_REGS", "ALL_REGS", "LIM_REGS" }
/* Define which registers fit in which classes.
@@ -225,13 +252,18 @@ enum reg_class {
#define REG_CLASS_CONTENTS \
{ 0, /* No regs */ \
- 0x00f, /* DATA_REGS */ \
- 0x1f0, /* ADDRESS_REGS */ \
- 0x200, /* SP_REGS */ \
- 0x1ff, /* DATA_OR_ADDRESS_REGS */\
- 0x1f0, /* SP_OR_ADDRESS_REGS */\
- 0x1ff, /* GENERAL_REGS */ \
- 0x3ff, /* ALL_REGS */ \
+ 0x0000f, /* DATA_REGS */ \
+ 0x001f0, /* ADDRESS_REGS */ \
+ 0x00200, /* SP_REGS */ \
+ 0x001ff, /* DATA_OR_ADDRESS_REGS */\
+ 0x003f0, /* SP_OR_ADDRESS_REGS */\
+ 0x2fc00, /* EXTENDED_REGS */ \
+ 0x2fc0f, /* DATA_OR_EXTENDED_REGS */ \
+ 0x2fdf0, /* ADDRESS_OR_EXTENDED_REGS */ \
+ 0x2fe00, /* SP_OR_EXTENDED_REGS */ \
+ 0x2fff0, /* SP_OR_ADDRESS_OR_EXTENDED_REGS */ \
+ 0x2fdff, /* GENERAL_REGS */ \
+ 0x2ffff, /* ALL_REGS */ \
}
/* The same information, inverted:
@@ -242,10 +274,11 @@ enum reg_class {
#define REGNO_REG_CLASS(REGNO) \
((REGNO) < 4 ? DATA_REGS : \
(REGNO) < 9 ? ADDRESS_REGS : \
- (REGNO) == 9 ? SP_REGS : 0)
+ (REGNO) == 9 ? SP_REGS : \
+ (REGNO) < 18 ? EXTENDED_REGS : 0)
/* The class value for index registers, and the one for base regs. */
-#define INDEX_REG_CLASS DATA_REGS
+#define INDEX_REG_CLASS DATA_OR_EXTENDED_REGS
#define BASE_REG_CLASS SP_OR_ADDRESS_REGS
/* Get reg_class from a letter such as appears in the machine description. */
@@ -253,6 +286,7 @@ enum reg_class {
#define REG_CLASS_FROM_LETTER(C) \
((C) == 'd' ? DATA_REGS : \
(C) == 'a' ? ADDRESS_REGS : \
+ (C) == 'x' ? EXTENDED_REGS : \
(C) == 'y' ? SP_REGS : NO_REGS)
/* Macros to check register numbers against specific register classes. */
@@ -273,6 +307,8 @@ enum reg_class {
#define REGNO_OK_FOR_INDEX_P(regno) \
(((regno) >= 0 && regno < 4) \
+ || ((regno) >= 10 && regno < 18) \
+ || (reg_renumber[regno] >= 10 && reg_renumber[regno] < 18) \
|| (reg_renumber[regno] >= 0 && reg_renumber[regno] < 4))
@@ -282,13 +318,15 @@ enum reg_class {
in some cases it is preferable to use a more restrictive class. */
#define PREFERRED_RELOAD_CLASS(X,CLASS) \
- (X == stack_pointer_rtx && CLASS != SP_REGS ? ADDRESS_REGS : CLASS)
+ (X == stack_pointer_rtx && CLASS != SP_REGS \
+ ? ADDRESS_OR_EXTENDED_REGS : CLASS)
#define PREFERRED_OUTPUT_RELOAD_CLASS(X,CLASS) \
- (X == stack_pointer_rtx && CLASS != SP_REGS ? ADDRESS_REGS : CLASS)
+ (X == stack_pointer_rtx && CLASS != SP_REGS \
+ ? ADDRESS_OR_EXTENDED_REGS : CLASS)
#define LIMIT_RELOAD_CLASS(MODE, CLASS) \
- ((MODE == QImode || MODE == HImode) ? DATA_REGS : CLASS)
+ (!TARGET_AM33 && (MODE == QImode || MODE == HImode) ? DATA_REGS : CLASS)
#define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \
secondary_reload_class(CLASS,MODE,IN)
@@ -645,6 +683,8 @@ extern struct rtx_def *mn10300_va_arg();
#endif
+#define HAVE_POST_INCREMENT (TARGET_AM33)
+
/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
that is a valid memory address for an instruction.
The MODE argument is the machine mode for the MEM expression
@@ -678,6 +718,11 @@ extern struct rtx_def *mn10300_va_arg();
goto ADDR; \
if (RTX_OK_FOR_BASE_P (X)) \
goto ADDR; \
+ if (TARGET_AM33 \
+ && GET_CODE (X) == POST_INC \
+ && RTX_OK_FOR_BASE_P (XEXP (X, 0)) \
+ && (MODE == SImode || MODE == SFmode || MODE == HImode))\
+ goto ADDR; \
if (GET_CODE (X) == PLUS) \
{ \
rtx base = 0, index = 0; \
@@ -719,7 +764,9 @@ extern struct rtx_def *legitimize_address ();
/* Go to LABEL if ADDR (a legitimate address expression)
has an effect that depends on the machine mode it is used for. */
-#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) {}
+#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) \
+ if (GET_CODE (ADDR) == POST_INC) \
+ goto LABEL
/* Nonzero if the constant value X is a legitimate general operand.
It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
@@ -772,8 +819,9 @@ extern struct rtx_def *legitimize_address ();
case CONST_DOUBLE: \
return 8;
-
-#define REGISTER_MOVE_COST(CLASS1, CLASS2) (CLASS1 != CLASS2 ? 4 : 2)
+#define REGISTER_MOVE_COST(CLASS1, CLASS2) \
+ ((CLASS1 == CLASS2 && (CLASS1 == ADDRESS_REGS || CLASS1 == DATA_REGS)) ? 2 :\
+ CLASS1 == CLASS2 && CLASS1 == EXTENDED_REGS ? 6 : 4)
/* A crude cut at RTX_COSTS for the MN10300. */
@@ -923,7 +971,8 @@ do { char dstr[30]; \
This sequence is indexed by compiler's hard-register-number (see above). */
#define REGISTER_NAMES \
-{ "d0", "d1", "d2", "d3", "a0", "a1", "a2", "a3", "ap", "sp" }
+{ "d0", "d1", "d2", "d3", "a0", "a1", "a2", "a3", "ap", "sp", \
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" }
/* Print an instruction operand X on file FILE.
look in mn10300.c for details */