(PROMOTE_MODE, ADJUST_COST): New macros.

(CALL_USED_REGISTERS): LR0 is call-used.
(HARD_REGNO_MODE_OK): Handle MODE_PARTIAL_INT and the special
registers that can only hold those modes.
(MODES_TIEABLE_P): Clean up and handle MODE_PARTIAL_INT modes.
(enum reg_class, REG_CLASS_NAMES, REG_CLASS_CONTENTS): Add new
classes LR0_REGS, FC_REGS, and CR_REGS.
(REGNO_REG_CLASS, REG_CLASS_FROM_LETTER): Likewise.
(PREDICATE_CODES): Update for new and deleted predicates.

From-SVN: r2444
This commit is contained in:
Richard Kenner 1992-10-13 19:07:51 -04:00
parent fba942c46d
commit 100fcf4cb3

View File

@ -1,5 +1,5 @@
/* Definitions of target machine for GNU compiler, for AMD Am29000 CPU. /* Definitions of target machine for GNU compiler, for AMD Am29000 CPU.
Copyright (C) 1988, 1990, 1991 Free Software Foundation, Inc. Copyright (C) 1988, 1990, 1991, 1992 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@nyu.edu) Contributed by Richard Kenner (kenner@nyu.edu)
This file is part of GNU CC. This file is part of GNU CC.
@ -122,6 +122,17 @@ extern int target_flags;
#define WCHAR_TYPE "char" #define WCHAR_TYPE "char"
#define WCHAR_TYPE_SIZE BITS_PER_UNIT #define WCHAR_TYPE_SIZE BITS_PER_UNIT
/* Define this macro if it is advisible to hold scalars in registers
in a wider mode than that declared by the program. In such cases,
the value is constrained to be within the bounds of the declared
type, but kept valid in the wider mode. The signedness of the
extension may differ from that of the type. */
#define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE) \
if (GET_MODE_CLASS (MODE) == MODE_INT \
&& GET_MODE_SIZE (MODE) < 4) \
(MODE) == SImode;
/* Define this if most significant bit is lowest numbered /* Define this if most significant bit is lowest numbered
in instructions that operate on numbered bit-fields. in instructions that operate on numbered bit-fields.
This is arbitrary on the 29k since it has no actual bit-field insns. This is arbitrary on the 29k since it has no actual bit-field insns.
@ -307,7 +318,7 @@ extern int target_flags;
#define CALL_USED_REGISTERS \ #define CALL_USED_REGISTERS \
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
@ -383,7 +394,8 @@ extern int target_flags;
/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
On 29k, the cpu registers can hold any mode. But a double-precision On 29k, the cpu registers can hold any mode. But a double-precision
floating-point value should start at an even register. The special floating-point value should start at an even register. The special
registers cannot hold floating-point values and the accumulators cannot registers cannot hold floating-point values, BP, CR, and FC cannot
hold integer or floating-point values, and the accumulators cannot
hold integer values. hold integer values.
DImode and larger values should start at an even register just like DImode and larger values should start at an even register just like
@ -396,7 +408,9 @@ extern int target_flags;
(((REGNO) >= R_ACC (0) \ (((REGNO) >= R_ACC (0) \
&& (GET_MODE_CLASS (MODE) == MODE_FLOAT \ && (GET_MODE_CLASS (MODE) == MODE_FLOAT \
|| GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT)) \ || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT)) \
|| ((REGNO) >= R_BP && (REGNO) < R_ACC (0) \ || ((REGNO) >= R_BP && (REGNO) <= R_CR \
&& GET_MODE_CLASS (MODE) == MODE_PARTIAL_INT) \
|| ((REGNO) >= R_Q && (REGNO) < R_ACC (0) \
&& GET_MODE_CLASS (MODE) != MODE_FLOAT \ && GET_MODE_CLASS (MODE) != MODE_FLOAT \
&& GET_MODE_CLASS (MODE) != MODE_COMPLEX_FLOAT) \ && GET_MODE_CLASS (MODE) != MODE_COMPLEX_FLOAT) \
|| ((REGNO) < R_BP \ || ((REGNO) < R_BP \
@ -413,12 +427,11 @@ extern int target_flags;
the special register's restriction to non-floating and the floating-point the special register's restriction to non-floating and the floating-point
accumulator's restriction to only floating. This probably won't accumulator's restriction to only floating. This probably won't
cause any great inefficiencies in practice. */ cause any great inefficiencies in practice. */
#define MODES_TIEABLE_P(MODE1, MODE2) \ #define MODES_TIEABLE_P(MODE1, MODE2) \
((MODE1) == (MODE2) \ ((MODE1) == (MODE2) \
|| (GET_MODE_CLASS (MODE1) != MODE_FLOAT \ || (GET_MODE_CLASS (MODE1) == MODE_INT \
&& GET_MODE_CLASS (MODE1) != MODE_COMPLEX_FLOAT \ && GET_MODE_CLASS (MODE2) == MODE_INT))
&& GET_MODE_CLASS (MODE2) != MODE_FLOAT \
&& GET_MODE_CLASS (MODE2) != MODE_COMPLEX_FLOAT))
/* Specify the registers used for certain standard purposes. /* Specify the registers used for certain standard purposes.
The values of these macros are register numbers. */ The values of these macros are register numbers. */
@ -468,27 +481,28 @@ extern int target_flags;
For any two classes, it is very desirable that there be another For any two classes, it is very desirable that there be another
class that represents their union. class that represents their union.
The 29k has six registers classes: GENERAL_REGS, SPECIAL_REGS, The 29k has nine registers classes: LR0_REGS, GENERAL_REGS, SPECIAL_REGS,
BP_REGS, Q_REGS, ACCUM_REGS, and ACCUM0_REGS. BP_REGS contains just BP and BP_REGS, FC_REGS, CR_REGS, Q_REGS, ACCUM_REGS, and ACCUM0_REGS.
is used for the extract and insert operations to allow combinations; Q LR0_REGS, BP_REGS, FC_REGS, CR_REGS, and Q_REGS contain just the single
contains just the Q register. The latter two classes are used to represent register. The latter two classes are used to represent the floating-point
the floating-point accumulator registers in the 29050. We also define the accumulator registers in the 29050. We also define the union class
union class FLOAT_REGS to represent any register that can be used to hold a FLOAT_REGS to represent any register that can be used to hold a
floating-point value. The union of SPECIAL_REGS and ACCUM_REGS isn't floating-point value. The union of SPECIAL_REGS and ACCUM_REGS isn't
useful as the former cannot contain floating-point and the latter can only useful as the former cannot contain floating-point and the latter can only
contain floating-point. */ contain floating-point. */
enum reg_class { NO_REGS, GENERAL_REGS, BP_REGS, Q_REGS, SPECIAL_REGS, enum reg_class { NO_REGS, LR0_REGS, GENERAL_REGS, BP_REGS, FC_REGS, CR_REGS,
ACCUM0_REGS, ACCUM_REGS, FLOAT_REGS, ALL_REGS, Q_REGS, SPECIAL_REGS, ACCUM0_REGS, ACCUM_REGS, FLOAT_REGS,
LIM_REG_CLASSES }; ALL_REGS, LIM_REG_CLASSES };
#define N_REG_CLASSES (int) LIM_REG_CLASSES #define N_REG_CLASSES (int) LIM_REG_CLASSES
/* Give names of register classes as strings for dump file. */ /* Give names of register classes as strings for dump file. */
#define REG_CLASS_NAMES \ #define REG_CLASS_NAMES \
{"NO_REGS", "GENERAL_REGS", "BP_REGS", "Q_REGS", "SPECIAL_REGS", \ {"NO_REGS", "LR0_REGS", "GENERAL_REGS", "BP_REGS", "FC_REGS", "CR_REGS", \
"ACCUM0_REGS", "ACCUM_REGS", "FLOAT_REGS", "ALL_REGS" } "Q_REGS", "SPECIAL_REGS", "ACCUM0_REGS", "ACCUM_REGS", "FLOAT_REGS", \
"ALL_REGS" }
/* 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
@ -496,8 +510,11 @@ enum reg_class { NO_REGS, GENERAL_REGS, BP_REGS, Q_REGS, SPECIAL_REGS,
#define REG_CLASS_CONTENTS \ #define REG_CLASS_CONTENTS \
{ {0, 0, 0, 0, 0, 0, 0}, \ { {0, 0, 0, 0, 0, 0, 0}, \
{0, 1, 0, 0, 0, 0, 0}, \
{~0, ~0, ~0, ~0, ~0, ~ 0xfffe0000, 0}, \ {~0, ~0, ~0, ~0, ~0, ~ 0xfffe0000, 0}, \
{0, 0, 0, 0, 0, 0x20000, 0}, \ {0, 0, 0, 0, 0, 0x20000, 0}, \
{0, 0, 0, 0, 0, 0x40000, 0}, \
{0, 0, 0, 0, 0, 0x80000, 0}, \
{0, 0, 0, 0, 0, 0x100000, 0}, \ {0, 0, 0, 0, 0, 0x100000, 0}, \
{0, 0, 0, 0, 0, 0xfffe0000, 0xff}, \ {0, 0, 0, 0, 0, 0xfffe0000, 0xff}, \
{0, 0, 0, 0, 0, 0, 0x100}, \ {0, 0, 0, 0, 0, 0, 0x100}, \
@ -512,10 +529,13 @@ enum reg_class { NO_REGS, GENERAL_REGS, BP_REGS, Q_REGS, SPECIAL_REGS,
#define REGNO_REG_CLASS(REGNO) \ #define REGNO_REG_CLASS(REGNO) \
((REGNO) == R_BP ? BP_REGS \ ((REGNO) == R_BP ? BP_REGS \
: (REGNO) == R_FC ? FC_REGS \
: (REGNO) == R_CR ? CR_REGS \
: (REGNO) == R_Q ? Q_REGS \ : (REGNO) == R_Q ? Q_REGS \
: (REGNO) > R_BP && (REGNO) <= R_EXO ? SPECIAL_REGS \ : (REGNO) > R_BP && (REGNO) <= R_EXO ? SPECIAL_REGS \
: (REGNO) == R_ACC (0) ? ACCUM0_REGS \ : (REGNO) == R_ACC (0) ? ACCUM0_REGS \
: (REGNO) > R_ACC (0) ? ACCUM_REGS \ : (REGNO) > R_ACC (0) ? ACCUM_REGS \
: (REGNO) == R_LR (0) ? LR0_REGS \
: GENERAL_REGS) : GENERAL_REGS)
/* The class value for index registers, and the one for base regs. */ /* The class value for index registers, and the one for base regs. */
@ -526,7 +546,10 @@ enum reg_class { NO_REGS, GENERAL_REGS, BP_REGS, Q_REGS, SPECIAL_REGS,
#define REG_CLASS_FROM_LETTER(C) \ #define REG_CLASS_FROM_LETTER(C) \
((C) == 'r' ? GENERAL_REGS \ ((C) == 'r' ? GENERAL_REGS \
: (C) == 'l' ? LR0_REGS \
: (C) == 'b' ? BP_REGS \ : (C) == 'b' ? BP_REGS \
: (C) == 'f' ? FC_REGS \
: (C) == 'c' ? CR_REGS \
: (C) == 'q' ? Q_REGS \ : (C) == 'q' ? Q_REGS \
: (C) == 'h' ? SPECIAL_REGS \ : (C) == 'h' ? SPECIAL_REGS \
: (C) == 'a' ? ACCUM_REGS \ : (C) == 'a' ? ACCUM_REGS \
@ -605,6 +628,10 @@ enum reg_class { NO_REGS, GENERAL_REGS, BP_REGS, Q_REGS, SPECIAL_REGS,
#define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \ #define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \
secondary_reload_class (CLASS, MODE, IN) secondary_reload_class (CLASS, MODE, IN)
/* This function is used to get the address of an object. */
extern struct rtx_def *a29k_get_reloaded_address ();
/* Return the maximum number of consecutive registers /* Return the maximum number of consecutive registers
needed to represent mode MODE in a register of class CLASS. needed to represent mode MODE in a register of class CLASS.
@ -621,6 +648,15 @@ enum reg_class { NO_REGS, GENERAL_REGS, BP_REGS, Q_REGS, SPECIAL_REGS,
#define REGISTER_MOVE_COST(CLASS1, CLASS2) \ #define REGISTER_MOVE_COST(CLASS1, CLASS2) \
((CLASS1) == GENERAL_REGS || (CLASS2) == GENERAL_REGS ? 2 : 4) ((CLASS1) == GENERAL_REGS || (CLASS2) == GENERAL_REGS ? 2 : 4)
/* A C statement (sans semicolon) to update the integer variable COST
based on the relationship between INSN that is dependent on
DEP_INSN through the dependence LINK. The default is to make no
adjustment to COST. On the a29k, ignore the cost of anti- and
output-dependencies. */
#define ADJUST_COST(INSN,LINK,DEP_INSN,COST) \
if (REG_NOTE_KIND (LINK) != 0) \
(COST) = 0; /* Anti or output dependence. */
/* Stack layout; function entry, exit and calling. */ /* Stack layout; function entry, exit and calling. */
@ -1544,10 +1580,11 @@ extern int a29k_debug_reg_map[];
{"reg_or_u_short_operand", {SUBREG, REG, CONST_INT}}, \ {"reg_or_u_short_operand", {SUBREG, REG, CONST_INT}}, \
{"and_operand", {SUBREG, REG, CONST_INT}}, \ {"and_operand", {SUBREG, REG, CONST_INT}}, \
{"add_operand", {SUBREG, REG, CONST_INT}}, \ {"add_operand", {SUBREG, REG, CONST_INT}}, \
{"call_operand", {SYMBOL_REF, CONST_INT}}, \
{"in_operand", {SUBREG, MEM, REG, CONST_INT, CONST, SYMBOL_REF, \ {"in_operand", {SUBREG, MEM, REG, CONST_INT, CONST, SYMBOL_REF, \
LABEL_REF, CONST_DOUBLE}}, \ LABEL_REF, CONST_DOUBLE}}, \
{"out_operand", {SUBREG, REG, MEM}}, \ {"out_operand", {SUBREG, REG, MEM}}, \
{"extend_operator", {ZERO_EXTEND, SIGN_EXTEND}}, \ {"reload_memory_operand", {SUBREG, REG, MEM}}, \
{"fp_comparison_operator", {EQ, GT, GE}}, \ {"fp_comparison_operator", {EQ, GT, GE}}, \
{"branch_operator", {GE, LT}}, \ {"branch_operator", {GE, LT}}, \
{"epilogue_operand", {CODE_LABEL}}, {"epilogue_operand", {CODE_LABEL}},