Commit dfa69feb by Tom Wood

entered into RCS

From-SVN: r1122
parent fe751ebf
......@@ -46,7 +46,7 @@ extern char *ctime ();
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 */
......@@ -840,25 +840,45 @@ mostly_false_jump (jump_insn, condition)
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. */
......@@ -883,7 +903,8 @@ mostly_false_jump (jump_insn, condition)
/* 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:
......@@ -895,11 +916,15 @@ mostly_false_jump (jump_insn, condition)
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;
......@@ -908,51 +933,6 @@ mostly_false_jump (jump_insn, condition)
return 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. */
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'");
}
}
/* 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). */
......@@ -1709,9 +1689,12 @@ m88k_layout_frame ()
/* 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;
......@@ -1872,7 +1855,6 @@ eligible_for_epilogue_delay (insn)
case TYPE_LOADA:
case TYPE_ARITH:
case TYPE_MARITH:
case TYPE_MSTORE:
return ok_for_epilogue_p (PATTERN (insn));
default:
return 0;
......@@ -2625,8 +2607,7 @@ m88k_builtin_saveregs (arglist)
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,
......@@ -2635,7 +2616,10 @@ m88k_builtin_saveregs (arglist)
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);
}
/* If cmpsi has not been generated, emit code to do the test. Return the
......
......@@ -104,7 +104,6 @@ extern void m88k_handle_pragma_token ();
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 ();
......@@ -204,9 +203,9 @@ extern char * reg_names[];
/* 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. */
......@@ -425,10 +424,10 @@ extern char * reg_names[];
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 */
......@@ -571,7 +570,7 @@ extern char * reg_names[];
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}
......@@ -687,13 +686,36 @@ extern char * reg_names[];
#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)); \
}
/*** Register Classes ***/
......@@ -1365,6 +1387,11 @@ enum reg_class { NO_REGS, AP_REG, XRF_REGS, GENERAL_REGS, AGRF_REGS,
{"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
......@@ -1933,11 +1960,6 @@ enum reg_class { NO_REGS, AP_REG, XRF_REGS, GENERAL_REGS, AGRF_REGS,
#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. */
......
......@@ -28,7 +28,7 @@
(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; }")
;; Attribute specifications
......@@ -45,22 +45,22 @@
; 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")
......@@ -69,7 +69,7 @@
; 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)))
......@@ -88,7 +88,7 @@
(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)
......@@ -97,7 +97,7 @@
; 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)])
; An abstract block diagram of the function units for the m88100.
......@@ -145,7 +145,7 @@
; 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
......@@ -202,13 +202,13 @@
; 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)
;; 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
......@@ -3063,13 +3063,13 @@
[(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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment