extern int flag_traditional;
extern FILE *asm_out_file;
-static char out_sccs_id[] = "@(#)m88k.c 2.1.11.5 19 May 1992 08:15:15";
+static char out_sccs_id[] = "@(#)m88k.c 2.1.11.11 29 May 1992 11:12:23";
static char tm_sccs_id [] = TM_SCCS_ID;
char *m88k_pound_sign = ""; /* Either # for SVR4 or empty for SVR3 */
for (insnt = NEXT_INSN (target_label);
insnt;
insnt = NEXT_INSN (insnt))
- if (GET_CODE (insnt) == JUMP_INSN
- || (GET_CODE (insnt) == SEQUENCE
- && GET_CODE (XVECEXP (insnt, 0, 0)) == JUMP_INSN))
- break;
- if (insnt && GET_CODE (PATTERN (insnt)) == RETURN)
+ {
+ if (GET_CODE (insnt) == JUMP_INSN)
+ break;
+ else if (GET_CODE (insnt) == SEQUENCE
+ && GET_CODE (XVECEXP (insnt, 0, 0)) == JUMP_INSN)
+ {
+ insnt = XVECEXP (insnt, 0, 0);
+ break;
+ }
+ }
+ if (insnt
+ && (GET_CODE (PATTERN (insnt)) == RETURN
+ || (GET_CODE (PATTERN (insnt)) == SET
+ && GET_CODE (SET_SRC (PATTERN (insnt))) == REG
+ && REGNO (SET_SRC (PATTERN (insnt))) == 1)))
insnt = 0;
for (insnj = NEXT_INSN (jump_insn);
insnj;
insnj = NEXT_INSN (insnj))
- if (GET_CODE (insnj) == JUMP_INSN
- || (GET_CODE (insnj) == SEQUENCE
- && GET_CODE (XVECEXP (insnj, 0, 0)) == JUMP_INSN))
- break;
- if (insnj && GET_CODE (PATTERN (insnj)) == RETURN)
- insnj = 0;
+ {
+ if (GET_CODE (insnj) == JUMP_INSN)
+ break;
+ else if (GET_CODE (insnj) == SEQUENCE
+ && GET_CODE (XVECEXP (insnj, 0, 0)) == JUMP_INSN)
+ {
+ insnj = XVECEXP (insnj, 0, 0);
+ break;
+ }
+ }
+ if (insnj
+ && (GET_CODE (PATTERN (insnj)) == RETURN
+ || (GET_CODE (PATTERN (insnj)) == SET
+ && GET_CODE (SET_SRC (PATTERN (insnj))) == REG
+ && REGNO (SET_SRC (PATTERN (insnj))) == 1)))
+ insnt = 0;
/* Predict to not return. */
- if (insnt != insnj)
+ if ((insnt == 0) != (insnj == 0))
return (insnt == 0);
/* Predict loops to loop. */
/* EQ tests are usually false and NE tests are usually true. Also,
most quantities are positive, so we can make the appropriate guesses
- about signed comparisons against zero. */
+ about signed comparisons against zero. Consider unsigned comparsions
+ to be a range check and assume quantities to be in range. */
switch (GET_CODE (condition))
{
case CONST_INT:
return 0;
case LE:
case LT:
+ case GEU:
+ case GTU: /* Must get casesi right at least. */
if (XEXP (condition, 1) == const0_rtx)
return 1;
break;
case GE:
case GT:
+ case LEU:
+ case LTU:
if (XEXP (condition, 1) == const0_rtx)
return 0;
break;
return 0;
}
\f
-/* Report errors on floating point, if we are given NaN's, or such. Leave
- the number as is, though, since we output the number in hex, and the
- assembler won't choke on it. */
-
-void
-check_float_value (mode, value)
- enum machine_mode mode;
- REAL_VALUE_TYPE value;
-{
- union {
- REAL_VALUE_TYPE d;
- struct {
- unsigned sign : 1;
- unsigned exponent : 11;
- unsigned mantissa1 : 20;
- unsigned mantissa2;
- } s;
- } u;
-
- if (mode == DFmode)
- {
- u.d = value;
- if (u.s.mantissa1 != 0 || u.s.mantissa2 != 0)
- {
- if (u.s.exponent == 0x7ff) /* Not a Number */
- warning ("floating point number is not valid for IEEE double precision");
- else if (u.s.exponent == 0)
- warning ("denormalized double precision floating point number");
- }
- }
- else if (mode == SFmode)
- {
- u.d = REAL_VALUE_TRUNCATE (mode, value);
- if (u.s.mantissa1 != 0 || u.s.mantissa2 != 0)
- {
- if (u.s.exponent == 0x7ff) /* Not a Number */
- warning ("floating point number is not valid for IEEE double precision");
- else if (u.s.exponent == 0)
- warning ("denormalized single precision floating point number");
- }
- else if (u.s.exponent == 0x7ff) /* Infinity */
- warning ("floating point number exceeds range of `float'");
- }
-}
-\f
/* Return true if the operand is a power of two and is a floating
point type (to optimize division by power of two into multiplication). */
/* If a frame is requested, save the previous FP, and the return
address (r1), so that a traceback can be done without using tdesc
- information. */
+ information. Otherwise, simply save the FP if it is used as
+ a preserve register. */
if (frame_pointer_needed)
save_regs[FRAME_POINTER_REGNUM] = save_regs[1] = 1;
+ else if (regs_ever_live[FRAME_POINTER_REGNUM])
+ save_regs[FRAME_POINTER_REGNUM] = 1;
/* Figure out which extended register(s) needs to be saved. */
for (regno = FIRST_EXTENDED_REGISTER + 1; regno < FIRST_PSEUDO_REGISTER;
case TYPE_LOADA:
case TYPE_ARITH:
case TYPE_MARITH:
- case TYPE_MSTORE:
return ok_for_epilogue_p (PATTERN (insn));
default:
return 0;
2 * UNITS_PER_WORD)),
copy_to_reg (XEXP (addr, 0)));
- /* Now store the incoming registers and return the address of the
- va_list constructor. */
+ /* Now store the incoming registers. */
if (fixed < 8)
move_block_from_reg
(2 + fixed,
fixed * UNITS_PER_WORD)),
8 - fixed);
- return copy_to_reg (XEXP (block, 0));
+ /* Return the address of the va_list constructor, but don't put it in a
+ register. This fails when not optimizing and produces worse code when
+ optimizing. */
+ return XEXP (block, 0);
}
\f
/* If cmpsi has not been generated, emit code to do the test. Return the
extern void emit_bcnd ();
extern void expand_block_move ();
-extern void check_float_value ();
extern void m88k_layout_frame ();
extern void m88k_output_prologue ();
extern void m88k_output_epilogue ();
/* Print subsidiary information on the compiler version in use.
Redefined in m88kv4.h, and m88kluna.h. */
#define VERSION_INFO1 "88open OCS/BCS, "
-#define VERSION_INFO2 "19 May 1992"
+#define VERSION_INFO2 "29 May 1992"
#define VERSION_STRING version_string
-#define TM_SCCS_ID "@(#)m88k.h 2.1.11.5 19 May 1992 09:28:04"
+#define TM_SCCS_ID "@(#)m88k.h 2.1.11.11 29 May 1992 13:20:31"
/* Run-time compilation parameters selecting different hardware subsets. */
replaces a BLKmode type. */
/* #define MAX_FIXED_MODE_SIZE 0 */
-/* Report errors on floating point, if we are given NaN's, or such. Leave
- the number as is, though, since we output the number in hex, and the
- assembler won't choke on it. */
-#define CHECK_FLOAT_VALUE(MODE,VALUE) check_float_value (MODE, VALUE)
+/* Check a `double' value for validity for a particular machine mode.
+ This is defined to avoid crashes outputting certain constants.
+ Since we output the number in hex, the assembler won't choke on it. */
+/* #define CHECK_FLOAT_VALUE(MODE,VALUE) */
/* A code distinguishing the floating point format of the target machine. */
/* #define TARGET_FLOAT_FORMAT IEEE_FLOAT_FORMAT */
that almost all registers be saved across calls anyway. */
#define FIXED_REGISTERS \
- {1, 1, 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, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 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, 1, 1}
#define REG_ALLOC_ORDER \
{ \
13, 12, 11, 10, 29, 28, 27, 26, \
- 1, 62, 63, 9, 8, 7, 6, 5, \
- 4, 3, 2, 53, 52, 51, 50, 49, \
+ 62, 63, 9, 8, 7, 6, 5, 4, \
+ 3, 2, 1, 53, 52, 51, 50, 49, \
48, 47, 46, 45, 44, 43, 42, 41, \
40, 39, 38, 37, 36, 35, 34, 33, \
25, 24, 23, 22, 21, 20, 19, 18, \
17, 16, 15, 14, 61, 60, 59, 58, \
57, 56, 55, 54, 30, 31, 0, 32}
+
+/* Order for leaf functions. */
+#define REG_LEAF_ALLOC_ORDER \
+ { \
+ 9, 8, 7, 6, 13, 12, 11, 10, \
+ 29, 28, 27, 26, 62, 63, 5, 4, \
+ 3, 2, 0, 53, 52, 51, 50, 49, \
+ 48, 47, 46, 45, 44, 43, 42, 41, \
+ 40, 39, 38, 37, 36, 35, 34, 33, \
+ 25, 24, 23, 22, 21, 20, 19, 18, \
+ 17, 16, 15, 14, 61, 60, 59, 58, \
+ 57, 56, 55, 54, 30, 31, 1, 32}
+
+/* Switch between the leaf and non-leaf orderings. The purpose is to avoid
+ write-over scoreboard delays between caller and callee. */
+#define ORDER_REGS_FOR_LOCAL_ALLOC \
+{ \
+ static int leaf[] = REG_LEAF_ALLOC_ORDER; \
+ static int nonleaf[] = REG_ALLOC_ORDER; \
+ \
+ bcopy (regs_ever_live[1] ? nonleaf : leaf, reg_alloc_order, \
+ FIRST_PSEUDO_REGISTER * sizeof (int)); \
+}
\f
/*** Register Classes ***/
{"equality_op", {EQ, NE}}, \
{"pc_or_label_ref", {PC, LABEL_REF}},
+/* The case table contains either words or branch instructions. This says
+ which. We always claim that the vector is PC-relative. It is position
+ independent when -fpic is used. */
+#define CASE_VECTOR_INSNS (TARGET_88100 || flag_pic)
+
/* An alias for a machine mode name. This is the machine mode that
elements of a jump-table should have. */
#define CASE_VECTOR_MODE SImode
#define ASM_OUTPUT_ASCII(FILE, P, SIZE) \
output_ascii (FILE, ASCII_DATA_ASM_OP, 48, P, SIZE)
-/* The case table contains either words or branch instructions. This says
- which. We always claim that the vector is PC-relative. It is position
- independent when -fpic is used. */
-#define CASE_VECTOR_INSNS (TARGET_88100 || flag_pic)
-
/* Epilogue for case labels. This jump instruction is called by casesi
to transfer to the appropriate branch instruction within the table.
The label `@L<n>e' is coined to mark the end of the table. */
(define_expand "m88k_sccs_id"
[(match_operand:SI 0 "" "")]
""
- "{ static char sccs_id[] = \"@(#)m88k.md 2.1.11.3 19 May 1992 08:44:52\";
+ "{ static char sccs_id[] = \"@(#)m88k.md 2.1.11.6 29 May 1992 10:55:49\";
FAIL; }")
\f
;; Attribute specifications
; spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv, ; FPU add instructions
; spmul,dpmul,imul, ; FPU multiply instructions
; arith,bit,mov ; integer unit instructions
-; marith,mbit,mstore,mfp,weird" ; multi-word instructions
+; marith,mbit,mfp,weird" ; multi-word instructions
; Classification of each insn. Some insns of TYPE_BRANCH are multi-word.
(define_attr "type"
- "branch,jump,call,load,store,loada,spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv,spmul,dpmul,imul,arith,bit,mov,marith,mbit,mstore,mfp,weird"
+ "branch,jump,call,load,store,loada,spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv,spmul,dpmul,imul,arith,bit,mov,marith,mbit,mfp,weird"
(const_string "arith"))
; Convenience attributes.
(define_attr "unit" "bit,memory,multiply,divide,fpadd,other"
(cond [(eq_attr "type" "bit,mbit") (const_string "bit")
- (eq_attr "type" "load,store,mstore") (const_string "memory")
+ (eq_attr "type" "load,store") (const_string "memory")
(eq_attr "type" "spmul,dpmul,imul") (const_string "multiply")
(eq_attr "type" "spdiv,dpdiv,idiv") (const_string "divide")
(eq_attr "type" "spadd,dpadd,spcmp,dpcmp,mfp") (const_string "fpadd")]
(const_string "other")))
-
+
(define_attr "fpu" "yes,no"
(if_then_else
(eq_attr "type" "spmul,dpmul,imul,spadd,dpadd,spcmp,dpcmp,spdiv,dpdiv,idiv,mfp")
; Length in # of instructions of each insn. The values are not exact, but
; are safe.
(define_attr "length" ""
- (cond [(eq_attr "type" "marith,mbit,mstore,mfp")
+ (cond [(eq_attr "type" "marith,mbit,mfp")
(const_int 2)]
(const_int 1)))
(define_delay (eq_attr "type" "branch,jump")
[(and
(and
- (eq_attr "type" "!branch,jump,call,marith,mbit,mstore,mfp,weird") ; required.
+ (eq_attr "type" "!branch,jump,call,marith,mbit,mfp,weird") ; required.
(eq_attr "type" "!load")) ; issue as-soon-as-possible.
(eq_attr "fpu" "no")) ; issue as-soon-as-possible.
(eq_attr "type" "!call,branch,jump") (nil)]) ; @@ was (const_int 1)
; a call. (@@ Support for this case is expected in reorg.c soon.)
(define_delay (eq_attr "type" "call")
- [(eq_attr "type" "!branch,call,marith,mbit,mstore,mfp,weird") ; required.
+ [(eq_attr "type" "!branch,call,marith,mbit,mfp,weird") ; required.
(nil) (nil)])
\f
; An abstract block diagram of the function units for the m88100.
; Describing the alu is currently not useful.
;(define_function_unit "alu" 1 0 (eq_attr "type"
-; "!store,mstore,marith,mbit,mfp,weird") 1 0)
+; "!store,marith,mbit,mfp,weird") 1 0)
;(define_function_unit "alu" 1 0 (eq_attr "type" "marith,mbit,weird") 2 0)
(define_function_unit "alu" 1 0
; Describing writeback contention is currently not useful.
;(define_function_unit "writeback" 1 1
-; (eq_attr "type" "!store,mstore,branch,jump,call") 0 1)
+; (eq_attr "type" "!store,branch,jump,call") 0 1)
; Describing stores is currently not useful. The suggestion here is that the
; function unit ordering has already been established (writeback is last) and
; that store insns use the units in an unusual order.
-;(define_function_unit "writeback" 1 1 (eq_attr "type" "store,mstore") 0 1)
-;(define_function_unit "memory" 1 3 (eq_attr "type" "store,mstore") 1 2)
+;(define_function_unit "writeback" 1 1 (eq_attr "type" "store") 0 1)
+;(define_function_unit "memory" 1 3 (eq_attr "type" "store") 1 2)
\f
;; This rich set of complex patterns are mostly due to Torbjorn Granlund
;; (tege@sics.se). They've changed since then, so don't complain to him
[(return)]
"null_epilogue ()"
"jmp%. %#r1"
- [(set_attr "type" "branch")])
+ [(set_attr "type" "jump")])
(define_insn "indirect_jump"
[(set (pc) (match_operand:SI 0 "register_operand" "r"))]
""
"jmp%. %0"
- [(set_attr "type" "branch")])
+ [(set_attr "type" "jump")])
(define_insn "jump"
[(set (pc)