aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1992-10-13 19:07:51 -0400
committerRichard Kenner <kenner@gcc.gnu.org>1992-10-13 19:07:51 -0400
commit100fcf4cb386189e5d352bcce2770d8e778773fc (patch)
tree04c4394cee59ac31ed47bdd4e85faf57d21fe933 /gcc
parentfba942c46dad90bc02695e422b89c4145b59419e (diff)
downloadgcc-100fcf4cb386189e5d352bcce2770d8e778773fc.zip
gcc-100fcf4cb386189e5d352bcce2770d8e778773fc.tar.gz
gcc-100fcf4cb386189e5d352bcce2770d8e778773fc.tar.bz2
(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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/a29k/a29k.h77
1 files changed, 57 insertions, 20 deletions
diff --git a/gcc/config/a29k/a29k.h b/gcc/config/a29k/a29k.h
index d80b824..882a5bd 100644
--- a/gcc/config/a29k/a29k.h
+++ b/gcc/config/a29k/a29k.h
@@ -1,5 +1,5 @@
/* 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)
This file is part of GNU CC.
@@ -122,6 +122,17 @@ extern int target_flags;
#define WCHAR_TYPE "char"
#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
in instructions that operate on numbered bit-fields.
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 \
{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, \
@@ -383,7 +394,8 @@ extern int target_flags;
/* 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
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.
DImode and larger values should start at an even register just like
@@ -396,7 +408,9 @@ extern int target_flags;
(((REGNO) >= R_ACC (0) \
&& (GET_MODE_CLASS (MODE) == MODE_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_COMPLEX_FLOAT) \
|| ((REGNO) < R_BP \
@@ -413,12 +427,11 @@ extern int target_flags;
the special register's restriction to non-floating and the floating-point
accumulator's restriction to only floating. This probably won't
cause any great inefficiencies in practice. */
+
#define MODES_TIEABLE_P(MODE1, MODE2) \
((MODE1) == (MODE2) \
- || (GET_MODE_CLASS (MODE1) != MODE_FLOAT \
- && GET_MODE_CLASS (MODE1) != MODE_COMPLEX_FLOAT \
- && GET_MODE_CLASS (MODE2) != MODE_FLOAT \
- && GET_MODE_CLASS (MODE2) != MODE_COMPLEX_FLOAT))
+ || (GET_MODE_CLASS (MODE1) == MODE_INT \
+ && GET_MODE_CLASS (MODE2) == MODE_INT))
/* Specify the registers used for certain standard purposes.
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
class that represents their union.
- The 29k has six registers classes: GENERAL_REGS, SPECIAL_REGS,
- BP_REGS, Q_REGS, ACCUM_REGS, and ACCUM0_REGS. BP_REGS contains just BP and
- is used for the extract and insert operations to allow combinations; Q
- contains just the Q register. The latter two classes are used to represent
- the floating-point accumulator registers in the 29050. We also define the
- union class FLOAT_REGS to represent any register that can be used to hold a
+ The 29k has nine registers classes: LR0_REGS, GENERAL_REGS, SPECIAL_REGS,
+ BP_REGS, FC_REGS, CR_REGS, Q_REGS, ACCUM_REGS, and ACCUM0_REGS.
+ LR0_REGS, BP_REGS, FC_REGS, CR_REGS, and Q_REGS contain just the single
+ register. The latter two classes are used to represent the floating-point
+ accumulator registers in the 29050. We also define the union class
+ 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
useful as the former cannot contain floating-point and the latter can only
contain floating-point. */
-enum reg_class { NO_REGS, GENERAL_REGS, BP_REGS, Q_REGS, SPECIAL_REGS,
- ACCUM0_REGS, ACCUM_REGS, FLOAT_REGS, ALL_REGS,
- LIM_REG_CLASSES };
+enum reg_class { NO_REGS, LR0_REGS, GENERAL_REGS, BP_REGS, FC_REGS, CR_REGS,
+ Q_REGS, SPECIAL_REGS, ACCUM0_REGS, ACCUM_REGS, FLOAT_REGS,
+ ALL_REGS, LIM_REG_CLASSES };
#define N_REG_CLASSES (int) LIM_REG_CLASSES
/* Give names of register classes as strings for dump file. */
#define REG_CLASS_NAMES \
- {"NO_REGS", "GENERAL_REGS", "BP_REGS", "Q_REGS", "SPECIAL_REGS", \
- "ACCUM0_REGS", "ACCUM_REGS", "FLOAT_REGS", "ALL_REGS" }
+ {"NO_REGS", "LR0_REGS", "GENERAL_REGS", "BP_REGS", "FC_REGS", "CR_REGS", \
+ "Q_REGS", "SPECIAL_REGS", "ACCUM0_REGS", "ACCUM_REGS", "FLOAT_REGS", \
+ "ALL_REGS" }
/* Define which registers fit in which classes.
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 \
{ {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, 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, 0xfffe0000, 0xff}, \
{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) \
((REGNO) == R_BP ? BP_REGS \
+ : (REGNO) == R_FC ? FC_REGS \
+ : (REGNO) == R_CR ? CR_REGS \
: (REGNO) == R_Q ? Q_REGS \
: (REGNO) > R_BP && (REGNO) <= R_EXO ? SPECIAL_REGS \
: (REGNO) == R_ACC (0) ? ACCUM0_REGS \
: (REGNO) > R_ACC (0) ? ACCUM_REGS \
+ : (REGNO) == R_LR (0) ? LR0_REGS \
: GENERAL_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) \
((C) == 'r' ? GENERAL_REGS \
+ : (C) == 'l' ? LR0_REGS \
: (C) == 'b' ? BP_REGS \
+ : (C) == 'f' ? FC_REGS \
+ : (C) == 'c' ? CR_REGS \
: (C) == 'q' ? Q_REGS \
: (C) == 'h' ? SPECIAL_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) \
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
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) \
((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. */
@@ -1544,10 +1580,11 @@ extern int a29k_debug_reg_map[];
{"reg_or_u_short_operand", {SUBREG, REG, CONST_INT}}, \
{"and_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, \
LABEL_REF, CONST_DOUBLE}}, \
{"out_operand", {SUBREG, REG, MEM}}, \
- {"extend_operator", {ZERO_EXTEND, SIGN_EXTEND}}, \
+ {"reload_memory_operand", {SUBREG, REG, MEM}}, \
{"fp_comparison_operator", {EQ, GT, GE}}, \
{"branch_operator", {GE, LT}}, \
{"epilogue_operand", {CODE_LABEL}},