aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/m68hc11/m68hc11.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/m68hc11/m68hc11.h')
-rw-r--r--gcc/config/m68hc11/m68hc11.h52
1 files changed, 35 insertions, 17 deletions
diff --git a/gcc/config/m68hc11/m68hc11.h b/gcc/config/m68hc11/m68hc11.h
index 2965fa5ddcf..e40e115d609 100644
--- a/gcc/config/m68hc11/m68hc11.h
+++ b/gcc/config/m68hc11/m68hc11.h
@@ -118,12 +118,15 @@ extern short *reg_renumber; /* def in local_alloc.c */
#define MASK_AUTO_INC_DEC 0004
#define MASK_M6811 0010
#define MASK_M6812 0020
+#define MASK_NO_DIRECT_MODE 0040
#define TARGET_OP_TIME (optimize && optimize_size == 0)
#define TARGET_SHORT (target_flags & MASK_SHORT)
#define TARGET_M6811 (target_flags & MASK_M6811)
#define TARGET_M6812 (target_flags & MASK_M6812)
#define TARGET_AUTO_INC_DEC (target_flags & MASK_AUTO_INC_DEC)
+#define TARGET_NO_DIRECT_MODE (target_flags & MASK_NO_DIRECT_MODE)
+#define TARGET_RELAX (TARGET_NO_DIRECT_MODE)
/* Default target_flags if no switches specified. */
#ifndef TARGET_DEFAULT
@@ -156,6 +159,8 @@ extern short *reg_renumber; /* def in local_alloc.c */
N_("Auto pre/post decrement increment allowed")}, \
{ "noauto-incdec", - MASK_AUTO_INC_DEC, \
N_("Auto pre/post decrement increment not allowed")}, \
+ { "relax", MASK_NO_DIRECT_MODE, \
+ N_("Do not use direct addressing mode for soft registers")},\
{ "68hc11", MASK_M6811, \
N_("Compile for a 68HC11")}, \
{ "68hc12", MASK_M6812, \
@@ -499,11 +504,12 @@ SOFT_REG_FIRST+28, SOFT_REG_FIRST+29,SOFT_REG_FIRST+30,SOFT_REG_FIRST+31
/* Value is 1 if it is a good idea to tie two pseudo registers when one has
mode MODE1 and one has mode MODE2. 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. */
+ 0 for correct output.
+
+ All modes are tieable except QImode. */
#define MODES_TIEABLE_P(MODE1, MODE2) \
(((MODE1) == (MODE2)) \
- || ((MODE1) == SImode && (MODE2) == HImode) \
- || ((MODE1) == HImode && (MODE2) == SImode))
+ || ((MODE1) != QImode && (MODE2) != QImode))
/* Define the classes of registers for register constraints in the
@@ -654,8 +660,8 @@ enum reg_class
/* SP_REGS */ { 0x00000008, 0x00000000 }, /* SP */ \
/* DA_REGS */ { 0x00000020, 0x00000000 }, /* A */ \
/* DB_REGS */ { 0x00000040, 0x00000000 }, /* B */ \
-/* D8_REGS */ { 0x00000060, 0x00000000 }, /* A B */ \
/* Z_REGS */ { 0x00000100, 0x00000000 }, /* Z */ \
+/* D8_REGS */ { 0x00000060, 0x00000000 }, /* A B */ \
/* Q_REGS */ { 0x00000062, 0x00000000 }, /* A B D */ \
/* D_OR_X_REGS */ { 0x00000003, 0x00000000 }, /* D X */ \
/* D_OR_Y_REGS */ { 0x00000006, 0x00000000 }, /* D Y */ \
@@ -824,30 +830,38 @@ extern enum reg_class m68hc11_tmp_regs_class;
C is the letter, and VALUE is a constant value.
Return 1 if VALUE is in the range specified by C.
+ `K' is for 0.
`L' is for range -65536 to 65536
`M' is for values whose 16-bit low part is 0
'N' is for +1 or -1.
'O' is for 16 (for rotate using swap).
'P' is for range -8 to 2 (used by addhi_sp)
- 'I', 'J', 'K' are not used. */
+ 'I', 'J' are not used. */
#define CONST_OK_FOR_LETTER_P(VALUE, C) \
- ((C) == 'L' ? (VALUE) >= -65536 && (VALUE) <= 65535 : \
+ ((C) == 'K' ? (VALUE) == 0 : \
+ (C) == 'L' ? ((VALUE) >= -65536 && (VALUE) <= 65535) : \
(C) == 'M' ? ((VALUE) & 0x0ffffL) == 0 : \
- (C) == 'N' ? ((VALUE) == 1 || (VALUE) == -1): \
+ (C) == 'N' ? ((VALUE) == 1 || (VALUE) == -1) : \
(C) == 'O' ? (VALUE) == 16 : \
- (C) == 'P' ? (VALUE) <= 2 && (VALUE) >= -8 : 0)
+ (C) == 'P' ? ((VALUE) <= 2 && (VALUE) >= -8) : 0)
/* Similar, but for floating constants, and defining letters G and H.
- No floating-point constants are valid on 68HC11. */
-#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) 0
+
+ `G' is for 0.0. */
+#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
+ ((C) == 'G' ? (GET_MODE_CLASS (GET_MODE (VALUE)) == MODE_FLOAT \
+ && VALUE == CONST0_RTX (GET_MODE (VALUE))) : 0)
/* 'U' represents certain kind of memory indexed operand for 68HC12.
and any memory operand for 68HC11. */
#define EXTRA_CONSTRAINT(OP, C) \
-((C) == 'U' ? m68hc11_small_indexed_indirect_p (OP, GET_MODE (OP)) : 0)
-
+((C) == 'U' ? m68hc11_small_indexed_indirect_p (OP, GET_MODE (OP)) \
+ : (C) == 'Q' ? m68hc11_symbolic_p (OP, GET_MODE (OP)) \
+ : (C) == 'R' ? m68hc11_indirect_p (OP, GET_MODE (OP)) \
+ : (C) == 'S' ? (memory_operand (OP, GET_MODE (OP)) \
+ && non_push_operand (OP, GET_MODE (OP))) : 0)
/* Stack layout; function entry, exit and calling. */
@@ -1294,10 +1308,14 @@ extern unsigned char m68hc11_reg_valid_for_index[FIRST_PSEUDO_REGISTER];
a mode offset to access the lowest part of the data.
(For example, for an SImode, the last valid offset is 252.) */
#define VALID_CONSTANT_OFFSET_P(X,MODE) \
-((GET_CODE (X) == CONST_INT) && \
- ((INTVAL (X) >= VALID_MIN_OFFSET) \
- && ((INTVAL (X) <= VALID_MAX_OFFSET \
- - (HOST_WIDE_INT) (GET_MODE_SIZE (MODE) + 1)))))
+(((GET_CODE (X) == CONST_INT) && \
+ ((INTVAL (X) >= VALID_MIN_OFFSET) \
+ && ((INTVAL (X) <= VALID_MAX_OFFSET \
+ - (HOST_WIDE_INT) (GET_MODE_SIZE (MODE) + 1))))) \
+|| (TARGET_M6812 \
+ && ((GET_CODE (X) == SYMBOL_REF) \
+ || GET_CODE (X) == LABEL_REF \
+ || GET_CODE (X) == CONST)))
/* This is included to allow stack push/pop operations. Special hacks in the
md and m6811.c files exist to support this. */
@@ -1442,7 +1460,7 @@ extern unsigned char m68hc11_reg_valid_for_index[FIRST_PSEUDO_REGISTER];
/* Move costs between classes of registers */
#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) \
- (m68hc11_register_move_cost (CLASS1, CLASS2))
+ (m68hc11_register_move_cost (MODE, CLASS1, CLASS2))
/* Move cost between register and memory.
- Move to a 16-bit register is reasonable,