extern int flag_traditional;
extern FILE *asm_out_file;
-static char out_sccs_id[] = "@(#)m88k.c 2.1.4.6 20 Apr 1992 14:30:40";
+static char out_sccs_id[] = "@(#)m88k.c 2.1.11.5 19 May 1992 08:15:15";
static char tm_sccs_id [] = TM_SCCS_ID;
char *m88k_pound_sign = ""; /* Either # for SVR4 or empty for SVR3 */
pos = output_option (file, sep, "-traditional", "", indent, pos, max);
if (profile_flag)
pos = output_option (file, sep, "-p", "", indent, pos, max);
+ if (profile_block_flag)
+ pos = output_option (file, sep, "-a", "", indent, pos, max);
for (j = 0; j < f_len; j++)
if (*f_options[j].variable == f_options[j].on_value)
frame_size = get_frame_size ();
/* Since profiling requires a call, make sure r1 is saved. */
- if (profile_flag)
+ if (profile_flag || profile_block_flag)
save_regs[1] = 1;
/* If we are producing debug information, store r1 and r30 where the
/* The first two saved registers are placed above the new frame pointer
if any. In the only case this matters, they are r1 and r30. */
if (frame_pointer_needed || sp_size)
- {
- m88k_fp_offset = ROUND_CALL_BLOCK_SIZE (sp_size - STARTING_FRAME_OFFSET);
- m88k_stack_size = m88k_fp_offset + STARTING_FRAME_OFFSET;
- }
+ m88k_fp_offset = ROUND_CALL_BLOCK_SIZE (sp_size - STARTING_FRAME_OFFSET);
else
- {
- m88k_stack_size = m88k_fp_offset = 0;
- }
+ m88k_fp_offset = -STARTING_FRAME_OFFSET;
+ m88k_stack_size = m88k_fp_offset + STARTING_FRAME_OFFSET;
/* First, combine m88k_stack_size and size. If m88k_stack_size is
non-zero, align the frame size to 8 mod 16; otherwise align the
m88k_pound_sign, &block[1]);
fprintf (file, "\tbcnd\t %sne0,%s,%s\n",
m88k_pound_sign, reg_names[26], &label[1]);
+ fprintf (file, "\tsubu\t %s,%s,64\n", reg_names[31], reg_names[31]);
+ fprintf (file, "\tst.d\t %s,%s,32\n", reg_names[2], reg_names[31]);
+ fprintf (file, "\tst.d\t %s,%s,40\n", reg_names[4], reg_names[31]);
+ fprintf (file, "\tst.d\t %s,%s,48\n", reg_names[6], reg_names[31]);
+ fprintf (file, "\tst.d\t %s,%s,56\n", reg_names[8], reg_names[31]);
fputs ("\tbsr.n\t ", file);
ASM_OUTPUT_LABELREF (file, "__bb_init_func");
putc ('\n', file);
fprintf (file, "\tor\t %s,%s,%slo16(%s)\n", reg_names[2], reg_names[27],
m88k_pound_sign, &block[1]);
+ fprintf (file, "\tld.d\t %s,%s,32\n", reg_names[2], reg_names[31]);
+ fprintf (file, "\tld.d\t %s,%s,40\n", reg_names[4], reg_names[31]);
+ fprintf (file, "\tld.d\t %s,%s,48\n", reg_names[6], reg_names[31]);
+ fprintf (file, "\tld.d\t %s,%s,56\n", reg_names[8], reg_names[31]);
+ fprintf (file, "\taddu\t %s,%s,64\n", reg_names[31], reg_names[31]);
ASM_OUTPUT_INTERNAL_LABEL (file, "LPY", labelno);
}
{
char block[256];
- ASM_GENERATE_INTERNAL_LABEL (block, "LPBX", 0);
+ ASM_GENERATE_INTERNAL_LABEL (block, "LPBX", 2);
/* @@ Need to deal with PIC. I'm not sure what the requirements are on
register usage, so I used r26/r27 to be safe. */
/* 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 "27 Apr 1992"
+#define VERSION_INFO2 "19 May 1992"
#define VERSION_STRING version_string
-#define TM_SCCS_ID "@(#)m88k.h 2.1.4.6 27 Apr 1992 16:30:45"
+#define TM_SCCS_ID "@(#)m88k.h 2.1.11.5 19 May 1992 09:28:04"
/* Run-time compilation parameters selecting different hardware subsets. */
#define ASM_OUTPUT_BYTE(FILE,VALUE) \
fprintf (FILE, "\t%s\t 0x%x\n", CHAR_ASM_OP, (VALUE))
-/* The singl-byte pseudo-op is the default. Override svr[34].h. */
+/* The single-byte pseudo-op is the default. Override svr[34].h. */
#undef ASM_BYTE_OP
-#define ASM_BYTE_OP "\tbyte"
+#define ASM_BYTE_OP "byte"
#undef ASM_OUTPUT_ASCII
#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 ASM_OUTPUT_CASE_END(FILE, NUM, TABLE) \
do { \
- char label[256]; \
- ASM_GENERATE_INTERNAL_LABEL (label, "L", NUM); \
- fprintf (FILE, "%se:\n", &label[1]); \
- if (! flag_delayed_branch) \
- fprintf (FILE, "\tlda\t %s,%s[%s]\n", reg_names[1], reg_names[1], \
- reg_names[m88k_case_index]); \
- fprintf (FILE, "\tjmp\t %s\n", reg_names[1]); \
+ if (CASE_VECTOR_INSNS) \
+ { \
+ char label[256]; \
+ ASM_GENERATE_INTERNAL_LABEL (label, "L", NUM); \
+ fprintf (FILE, "%se:\n", &label[1]); \
+ if (! flag_delayed_branch) \
+ fprintf (FILE, "\tlda\t %s,%s[%s]\n", reg_names[1], \
+ reg_names[1], reg_names[m88k_case_index]); \
+ fprintf (FILE, "\tjmp\t %s\n", reg_names[1]); \
+ } \
} while (0)
/* This is how to output an element of a case-vector that is absolute. */
do { \
char buffer[256]; \
ASM_GENERATE_INTERNAL_LABEL (buffer, "L", VALUE); \
- fprintf (FILE, "\tbr\t %s\n", &buffer[1]); \
+ fprintf (FILE, CASE_VECTOR_INSNS ? "\tbr\t %s\n" : "\tword\t %s\n", \
+ &buffer[1]); \
} while (0)
/* This is how to output an element of a case-vector that is relative. */
(define_expand "m88k_sccs_id"
[(match_operand:SI 0 "" "")]
""
- "{ static char sccs_id[] = \"@(#)m88k.md 2.1.4.3 20 Apr 1992 10:42:47\";
+ "{ static char sccs_id[] = \"@(#)m88k.md 2.1.11.3 19 May 1992 08:44:52\";
FAIL; }")
\f
;; Attribute specifications
; "!store,mstore,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
+ (and (eq_attr "type" "loada,arith,bit,mov") (eq_attr "cpu" "!m88100")) 2 0)
+(define_function_unit "alu" 1 0
+ (and (eq_attr "type" "marith,mbit,weird") (eq_attr "cpu" "!m88100")) 4 0)
+
(define_function_unit "memory" 1 3
(and (eq_attr "type" "load") (eq_attr "cpu" "m88100")) 3 2)
(define_function_unit "memory" 1 3
- (and (eq_attr "type" "load") (eq_attr "cpu" "!m88100")) 2 2)
+ (and (eq_attr "type" "load") (eq_attr "cpu" "!m88100")) 4 2)
; The fp1 and fplast descriptions currently have no effect.
;(define_function_unit "fp1" 1 1 (eq_attr "fpu" "yes") 1 2)
(define_function_unit "fpmul" 1 4
(and (eq_attr "type" "imul,spmul,dpmul,mfp")
- (eq_attr "cpu" "!m88100")) 3 2) ; 3
+ (eq_attr "cpu" "!m88100")) 6 2) ; 3
(define_function_unit "fpadd" 1 3
(and (eq_attr "type" "spadd,spcmp") (eq_attr "cpu" "m88100")) 3 2) ; 5-6
(and (eq_attr "type" "idiv") (eq_attr "cpu" "m88100")) 38 2) ; 38
(define_function_unit "fpadd" 1 3
- (and (eq_attr "type" "spadd,dpadd") (eq_attr "cpu" "!m88100")) 3 2) ; 3
+ (and (eq_attr "type" "spadd,dpadd") (eq_attr "cpu" "!m88100")) 6 2) ; 3
(define_function_unit "fpadd" 1 3
- (and (eq_attr "type" "spcmp,dpcmp") (eq_attr "cpu" "!m88100")) 1 2) ; 3
+ (and (eq_attr "type" "spcmp,dpcmp") (eq_attr "cpu" "!m88100")) 2 2) ; 3
(define_function_unit "fpadd" 1 3
- (and (eq_attr "type" "spdiv") (eq_attr "cpu" "!m88100")) 13 2) ; 13
+ (and (eq_attr "type" "spdiv") (eq_attr "cpu" "!m88100")) 26 2) ; 13
(define_function_unit "fpadd" 1 3
- (and (eq_attr "type" "dpdiv") (eq_attr "cpu" "!m88100")) 23 2) ; 23
+ (and (eq_attr "type" "dpdiv") (eq_attr "cpu" "!m88100")) 46 2) ; 23
(define_function_unit "fpadd" 1 3
- (and (eq_attr "type" "idiv") (eq_attr "cpu" "!m88100")) 18 2) ; 18
+ (and (eq_attr "type" "idiv") (eq_attr "cpu" "!m88100")) 36 2) ; 18
;(define_function_unit "fplast" 1 1 (eq_attr "fpu" "yes") 1 2)
(use (match_dup 5))
(parallel [(call (mem:SI (match_operand 0 "" ""))
(const_int 0))
- (use (reg:SI 1))])]
+ (clobber (reg:SI 1))])]
""
"")
(use (reg:SI 6))
(parallel [(call (mem:SI (match_operand 0 "" ""))
(const_int 0))
- (use (reg:SI 1))])]
+ (clobber (reg:SI 1))])]
""
"")
\f
{
register rtx index_diff = gen_reg_rtx (SImode);
register rtx low = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[1]));
+ register rtx label = gen_rtx (LABEL_REF, VOIDmode, operands[3]);
+ register rtx base;
+
+ if (! CASE_VECTOR_INSNS)
+ /* These instructions are likely to be scheduled and made loop invariant.
+ This decreases the cost of the dispatch at the expense of the default
+ case. */
+ base = force_reg (SImode, memory_address_noforce (SImode, label));
/* Compute the index difference and handle the default case. */
emit_insn (gen_addsi3 (index_diff,
force_reg (SImode, operands[0]),
ADD_INT (low) ? low : force_reg (SImode, low)));
emit_insn (gen_cmpsi (index_diff, operands[2]));
+ /* It's possible to replace this branch with sgtu/iorsi3 and adding a -1
+ entry to the table. However, that doesn't seem to win on the m88110. */
emit_jump_insn (gen_bgtu (operands[4]));
- /* Call the jump that will branch to the appropriate case. */
- emit_jump_insn (gen_casesi_enter (gen_rtx (LABEL_REF, VOIDmode, operands[3]),
- index_diff,
- operands[3]));
- /* Claim that flow drops into the table so it will be adjacent. */
+ if (CASE_VECTOR_INSNS)
+ /* Call the jump that will branch to the appropriate case. */
+ emit_jump_insn (gen_casesi_enter (label, index_diff, operands[3]));
+ else
+ /* Load the table entry and jump to it. */
+ emit_jump_insn (gen_casesi_jump (gen_reg_rtx (SImode), base, index_diff));
+
+ /* Claim that flow drops into the table so it will be adjacent by not
+ emitting a barrier. */
DONE;
}")
+(define_expand "casesi_jump"
+ [(set (match_operand:SI 0 "" "")
+ (mem:SI (plus:SI (match_operand:SI 1 "" "")
+ (mult:SI (match_operand:SI 2 "" "")
+ (const_int 4)))))
+ (set (pc) (match_dup 0))]
+ ""
+ "")
+
;; The bsr.n instruction is directed to the END of the table. See
;; ASM_OUTPUT_CASE_END.
(define_expand "call"
[(parallel [(call (match_operand:SI 0 "" "")
(match_operand 1 "" ""))
- (use (reg:SI 1))])]
+ (clobber (reg:SI 1))])]
""
"
{
(define_insn ""
[(parallel [(call (mem:SI (match_operand:SI 0 "call_address_operand" "rQ"))
(match_operand 1 "" ""))
- (use (reg:SI 1))])]
+ (clobber (reg:SI 1))])]
""
"* return output_call (operands, operands[0]);"
[(set_attr "type" "call")])
[(parallel [(set (match_operand 0 "register_operand" "")
(call (match_operand:SI 1 "" "")
(match_operand 2 "" "")))
- (use (reg:SI 1))])]
+ (clobber (reg:SI 1))])]
""
"
{
(call (mem:SI
(match_operand:SI 1 "call_address_operand" "rQ"))
(match_operand 2 "" "")))
- (use (reg:SI 1))])]
+ (clobber (reg:SI 1))])]
""
"* return output_call (operands, operands[1]);"
[(set_attr "type" "call")])