mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-01-12 07:24:32 +08:00
alpha.c (alpha_handle_trap_shadows): Remove do-nothing exit.
* alpha.c (alpha_handle_trap_shadows): Remove do-nothing exit. Tag trapb and next insn with TImode. (alphaev5_insn_pipe, alphaev5_next_group, alphaev5_align_insns): New. (alpha_reorg): Add conditional for alpha_handle_trap_shadows. Invoke alphaev5_align_insns as appropriate. * alpha.md (attr type): Add multi. (define_asm_attributes): New. (prologue_stack_probe_loop, builtin_setjmp_receiver): Set type multi. (arg_home): Likewise. (fnop, unop, realign): New. From-SVN: r22010
This commit is contained in:
parent
4bdc8810f6
commit
68aed21b05
@ -1,3 +1,22 @@
|
||||
Wed Aug 26 18:38:15 1998 Richard Henderson <rth@cygnus.com>
|
||||
|
||||
* haifa-sched.c (last_clock_var): New.
|
||||
(schedule_block): Initialize it.
|
||||
(schedule_insn): Use it to fill insn modes with issue information.
|
||||
|
||||
* alpha.c (alpha_handle_trap_shadows): Remove do-nothing exit.
|
||||
Tag trapb and next insn with TImode.
|
||||
(alphaev5_insn_pipe, alphaev5_next_group, alphaev5_align_insns): New.
|
||||
(alpha_reorg): Add conditional for alpha_handle_trap_shadows.
|
||||
Invoke alphaev5_align_insns as appropriate.
|
||||
* alpha.h (LABEL_ALIGN_AFTER_BARRIER): Was ALIGN_LABEL_AFTER_BARRIER.
|
||||
(MD_SCHED_VARIABLE_ISSUE): New.
|
||||
* alpha.md (attr type): Add multi.
|
||||
(define_asm_attributes): New.
|
||||
(prologue_stack_probe_loop, builtin_setjmp_receiver): Set type multi.
|
||||
(arg_home): Likewise.
|
||||
(fnop, unop, realign): New.
|
||||
|
||||
Wed Aug 26 15:55:41 1998 Jim Wilson <wilson@cygnus.com>
|
||||
|
||||
* iris5.h (PREFERRED_DEBUGGING_TYPE): Undef.
|
||||
|
@ -1416,7 +1416,7 @@ alpha_emit_conditional_move (cmp, mode)
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* ??? We mark the the branch mode to be CCmode to prevent the compare
|
||||
/* ??? We mark the branch mode to be CCmode to prevent the compare
|
||||
and cmov from being combined, since the compare insn follows IEEE
|
||||
rules that the cmov does not. */
|
||||
if (alpha_compare_fp_p && !flag_fast_math)
|
||||
@ -4090,10 +4090,7 @@ alpha_handle_trap_shadows (insns)
|
||||
{
|
||||
struct shadow_summary shadow;
|
||||
int trap_pending, exception_nesting;
|
||||
rtx i;
|
||||
|
||||
if (alpha_tp == ALPHA_TP_PROG && !flag_exceptions)
|
||||
return;
|
||||
rtx i, n;
|
||||
|
||||
trap_pending = 0;
|
||||
exception_nesting = 0;
|
||||
@ -4196,7 +4193,9 @@ alpha_handle_trap_shadows (insns)
|
||||
else
|
||||
{
|
||||
close_shadow:
|
||||
emit_insn_before (gen_trapb (), i);
|
||||
n = emit_insn_before (gen_trapb (), i);
|
||||
PUT_MODE (n, TImode);
|
||||
PUT_MODE (i, TImode);
|
||||
trap_pending = 0;
|
||||
shadow.used.i = 0;
|
||||
shadow.used.fp = 0;
|
||||
@ -4218,14 +4217,344 @@ alpha_handle_trap_shadows (insns)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAIFA
|
||||
/* Alpha can only issue instruction groups simultaneously if they are
|
||||
suitibly aligned. This is very processor-specific. */
|
||||
|
||||
enum alphaev5_pipe {
|
||||
EV5_STOP = 0,
|
||||
EV5_NONE = 1,
|
||||
EV5_E01 = 2,
|
||||
EV5_E0 = 4,
|
||||
EV5_E1 = 8,
|
||||
EV5_FAM = 16,
|
||||
EV5_FA = 32,
|
||||
EV5_FM = 64
|
||||
};
|
||||
|
||||
static enum alphaev5_pipe
|
||||
alphaev5_insn_pipe (insn)
|
||||
rtx insn;
|
||||
{
|
||||
if (recog_memoized (insn) < 0)
|
||||
return EV5_STOP;
|
||||
if (get_attr_length (insn) != 4)
|
||||
return EV5_STOP;
|
||||
|
||||
switch (get_attr_type (insn))
|
||||
{
|
||||
case TYPE_ILD:
|
||||
case TYPE_FLD:
|
||||
case TYPE_LDSYM:
|
||||
case TYPE_IADD:
|
||||
case TYPE_ILOG:
|
||||
case TYPE_ICMOV:
|
||||
case TYPE_ICMP:
|
||||
return EV5_E01;
|
||||
|
||||
case TYPE_IST:
|
||||
case TYPE_FST:
|
||||
case TYPE_SHIFT:
|
||||
case TYPE_IMUL:
|
||||
case TYPE_MISC:
|
||||
case TYPE_MVI:
|
||||
return EV5_E0;
|
||||
|
||||
case TYPE_IBR:
|
||||
case TYPE_JSR:
|
||||
return EV5_E1;
|
||||
|
||||
case TYPE_FCPYS:
|
||||
return EV5_FAM;
|
||||
|
||||
case TYPE_FBR:
|
||||
case TYPE_FCMOV:
|
||||
case TYPE_FADD:
|
||||
case TYPE_FDIV:
|
||||
return EV5_FA;
|
||||
|
||||
case TYPE_FMUL:
|
||||
return EV5_FM;
|
||||
}
|
||||
abort();
|
||||
}
|
||||
|
||||
/* IN_USE is a mask of the slots currently filled within the
|
||||
insn group. The mask bits come from alphaev5_pipe above.
|
||||
If EV5_E01 is set, then the insn in EV5_E0 can be swapp
|
||||
by the hardware into EV5_E1.
|
||||
|
||||
LEN is, of course, the length of the group in bytes. */
|
||||
|
||||
static rtx
|
||||
alphaev5_next_group (insn, pin_use, plen)
|
||||
rtx insn;
|
||||
int *pin_use, *plen;
|
||||
{
|
||||
int len, in_use;
|
||||
|
||||
len = in_use = 0;
|
||||
|
||||
if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
|
||||
goto next;
|
||||
|
||||
do
|
||||
{
|
||||
enum alphaev5_pipe pipe;
|
||||
rtx prev;
|
||||
|
||||
pipe = alphaev5_insn_pipe (insn);
|
||||
switch (pipe)
|
||||
{
|
||||
case EV5_STOP:
|
||||
/* Force complex instructions to start new groups. */
|
||||
if (in_use)
|
||||
goto done;
|
||||
|
||||
/* If this is a completely unrecognized insn, its an asm.
|
||||
We don't know how long it is, so record length as -1 to
|
||||
signal a needed realignment. */
|
||||
if (recog_memoized (insn) < 0)
|
||||
len = -1;
|
||||
else
|
||||
len = get_attr_length (insn);
|
||||
goto next;
|
||||
|
||||
/* ??? Most of the places below, we would like to abort, as
|
||||
it would indicate an error either in Haifa, or in the
|
||||
scheduling description. Unfortunately, Haifa never
|
||||
schedules the last instruction of the BB, so we don't
|
||||
have an accurate TI bit to go off. */
|
||||
case EV5_E01:
|
||||
if (in_use & EV5_E0)
|
||||
{
|
||||
if (in_use & EV5_E1)
|
||||
goto done;
|
||||
in_use |= EV5_E1;
|
||||
}
|
||||
else
|
||||
in_use |= EV5_E0 | EV5_E01;
|
||||
break;
|
||||
|
||||
case EV5_E0:
|
||||
if (in_use & EV5_E0)
|
||||
{
|
||||
if (!(in_use & EV5_E01) || in_use & EV5_E1)
|
||||
goto done;
|
||||
in_use |= EV5_E1;
|
||||
}
|
||||
in_use |= EV5_E0;
|
||||
break;
|
||||
|
||||
case EV5_E1:
|
||||
if (in_use & EV5_E1)
|
||||
goto done;
|
||||
in_use |= EV5_E1;
|
||||
break;
|
||||
|
||||
case EV5_FAM:
|
||||
if (in_use & EV5_FA)
|
||||
{
|
||||
if (in_use & EV5_FM)
|
||||
goto done;
|
||||
in_use |= EV5_FM;
|
||||
}
|
||||
else
|
||||
in_use |= EV5_FA | EV5_FAM;
|
||||
break;
|
||||
|
||||
case EV5_FA:
|
||||
if (in_use & EV5_FA)
|
||||
goto done;
|
||||
in_use |= EV5_FA;
|
||||
break;
|
||||
|
||||
case EV5_FM:
|
||||
if (in_use & EV5_FM)
|
||||
goto done;
|
||||
in_use |= EV5_FM;
|
||||
break;
|
||||
|
||||
case EV5_NONE:
|
||||
break;
|
||||
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
len += 4;
|
||||
|
||||
/* Haifa doesn't do well scheduling branches. */
|
||||
/* ??? If this is predicted not-taken, slotting continues, except
|
||||
that no more IBR, FBR, or JSR insns may be slotted. */
|
||||
if (GET_CODE (insn) == JUMP_INSN)
|
||||
goto next;
|
||||
|
||||
insn = next_nonnote_insn (insn);
|
||||
|
||||
if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
|
||||
goto done;
|
||||
|
||||
/* Let Haifa tell us where it thinks insn group boundaries are. */
|
||||
if (GET_MODE (insn) == TImode)
|
||||
goto done;
|
||||
|
||||
}
|
||||
while (insn);
|
||||
|
||||
done:
|
||||
*plen = len;
|
||||
*pin_use = in_use;
|
||||
return insn;
|
||||
|
||||
next:
|
||||
insn = next_nonnote_insn (insn);
|
||||
goto done;
|
||||
}
|
||||
|
||||
static void
|
||||
alphaev5_align_insns (insns)
|
||||
rtx insns;
|
||||
{
|
||||
/* ALIGN is the known alignment for the insn group. */
|
||||
int align;
|
||||
/* OFS is the offset of the current insn in the insn group. */
|
||||
int ofs;
|
||||
int prev_in_use, in_use, len;
|
||||
rtx i, next;
|
||||
|
||||
/* Let shorten branches care for assigning alignments to code labels. */
|
||||
shorten_branches (insns);
|
||||
|
||||
ofs = prev_in_use = 0;
|
||||
if (alpha_does_function_need_gp())
|
||||
{
|
||||
ofs = 8;
|
||||
prev_in_use = EV5_E01 | EV5_E0;
|
||||
}
|
||||
align = (FUNCTION_BOUNDARY/BITS_PER_UNIT < 16
|
||||
? FUNCTION_BOUNDARY/BITS_PER_UNIT : 16);
|
||||
|
||||
i = insns;
|
||||
if (GET_CODE (i) == NOTE)
|
||||
i = next_nonnote_insn (i);
|
||||
|
||||
while (i)
|
||||
{
|
||||
next = alphaev5_next_group (i, &in_use, &len);
|
||||
|
||||
/* When we see a label, resync alignment etc. */
|
||||
if (GET_CODE (i) == CODE_LABEL)
|
||||
{
|
||||
int new_align = 1 << label_to_alignment (i);
|
||||
if (new_align >= align)
|
||||
{
|
||||
align = new_align < 16 ? new_align : 16;
|
||||
ofs = 0;
|
||||
}
|
||||
else if (ofs & (new_align-1))
|
||||
ofs = (ofs | (new_align-1)) + 1;
|
||||
if (len != 0)
|
||||
abort();
|
||||
}
|
||||
|
||||
/* Handle complex instructions special. */
|
||||
else if (in_use == 0)
|
||||
{
|
||||
/* Asms will have length < 0. This is a signal that we have
|
||||
lost alignment knowledge. Assume, however, that the asm
|
||||
will not mis-align instructions. */
|
||||
if (len < 0)
|
||||
{
|
||||
ofs = 0;
|
||||
align = 4;
|
||||
len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the known alignment is smaller than the recognized insn group,
|
||||
realign the output. */
|
||||
else if (align < len)
|
||||
{
|
||||
int new_log_align = len > 8 ? 4 : 3;
|
||||
rtx where;
|
||||
|
||||
where = prev_nonnote_insn (i);
|
||||
if (!where || GET_CODE (where) != CODE_LABEL)
|
||||
where = i;
|
||||
|
||||
emit_insn_before (gen_realign (GEN_INT (new_log_align)), where);
|
||||
align = 1 << new_log_align;
|
||||
ofs = 0;
|
||||
}
|
||||
|
||||
/* If the group won't fit in the same INT16 as the previous,
|
||||
we need to add padding to keep the group together. Rather
|
||||
than simply leaving the insn filling to the assembler, we
|
||||
can make use of the knowledge of what sorts of instructions
|
||||
were issued in the previous group to make sure that all of
|
||||
the added nops are really free. */
|
||||
else if (ofs + len > align)
|
||||
{
|
||||
int nop_count = (align - ofs) / 4;
|
||||
rtx where;
|
||||
|
||||
where = prev_nonnote_insn (i);
|
||||
if (!where || GET_CODE (where) != CODE_LABEL)
|
||||
where = i;
|
||||
|
||||
do
|
||||
{
|
||||
if (!(prev_in_use & EV5_E1))
|
||||
{
|
||||
prev_in_use |= EV5_E1;
|
||||
emit_insn_before (gen_nop(), where);
|
||||
}
|
||||
else if (TARGET_FP && !(prev_in_use & EV5_FA))
|
||||
{
|
||||
prev_in_use |= EV5_FA;
|
||||
emit_insn_before (gen_fnop(), where);
|
||||
}
|
||||
else if (TARGET_FP && !(prev_in_use & EV5_FM))
|
||||
{
|
||||
prev_in_use |= EV5_FM;
|
||||
emit_insn_before (gen_fnop(), where);
|
||||
}
|
||||
else
|
||||
emit_insn_before (gen_unop(), where);
|
||||
}
|
||||
while (--nop_count);
|
||||
ofs = 0;
|
||||
}
|
||||
|
||||
ofs = (ofs + len) & (align - 1);
|
||||
prev_in_use = in_use;
|
||||
i = next;
|
||||
}
|
||||
}
|
||||
#endif /* HAIFA */
|
||||
|
||||
/* Machine dependant reorg pass. */
|
||||
|
||||
void
|
||||
alpha_reorg (insns)
|
||||
rtx insns;
|
||||
{
|
||||
alpha_handle_trap_shadows (insns);
|
||||
if (alpha_tp != ALPHA_TP_PROG || flag_exceptions)
|
||||
alpha_handle_trap_shadows (insns);
|
||||
|
||||
#ifdef HAIFA
|
||||
/* Due to the number of extra trapb insns, don't bother fixing up
|
||||
alignment when trap precision is instruction. Moreover, we can
|
||||
only do our job when sched2 is run and Haifa is our scheduler. */
|
||||
if (optimize && !optimize_size
|
||||
&& alpha_tp != ALPHA_TP_INSN
|
||||
&& flag_schedule_insns_after_reload)
|
||||
{
|
||||
if (alpha_cpu == PROCESSOR_EV5)
|
||||
alphaev5_align_insns (insns);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -38,6 +38,7 @@
|
||||
;; 3 builtin_longjmp
|
||||
;; 4 trapb
|
||||
;; 5 prologue_stack_probe_loop
|
||||
;; 6 realign
|
||||
|
||||
;; Processor type -- this attribute must exactly match the processor_type
|
||||
;; enumeration in alpha.h.
|
||||
@ -51,9 +52,13 @@
|
||||
;; separately.
|
||||
|
||||
(define_attr "type"
|
||||
"ild,fld,ldsym,ist,fst,ibr,fbr,jsr,iadd,ilog,shift,icmov,fcmov,icmp,imul,fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof"
|
||||
"ild,fld,ldsym,ist,fst,ibr,fbr,jsr,iadd,ilog,shift,icmov,fcmov,icmp,imul,fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
|
||||
(const_string "iadd"))
|
||||
|
||||
;; Describe a user's asm statement.
|
||||
(define_asm_attributes
|
||||
[(set_attr "type" "multi")])
|
||||
|
||||
;; Define the operand size an insn operates on. Used primarily by mul
|
||||
;; and div operations that have size dependant timings.
|
||||
|
||||
@ -3833,12 +3838,6 @@
|
||||
"jmp $31,(%0),0"
|
||||
[(set_attr "type" "ibr")])
|
||||
|
||||
(define_insn "nop"
|
||||
[(const_int 0)]
|
||||
""
|
||||
"nop"
|
||||
[(set_attr "type" "ilog")])
|
||||
|
||||
(define_expand "tablejump"
|
||||
[(use (match_operand:SI 0 "register_operand" ""))
|
||||
(use (match_operand:SI 1 "" ""))]
|
||||
@ -5124,7 +5123,8 @@
|
||||
|
||||
return \"\";
|
||||
}"
|
||||
[(set_attr "length" "16")])
|
||||
[(set_attr "length" "16")
|
||||
(set_attr "type" "multi")])
|
||||
|
||||
(define_expand "prologue"
|
||||
[(clobber (const_int 0))]
|
||||
@ -5171,13 +5171,15 @@
|
||||
[(unspec_volatile [(match_operand 0 "" "")] 2)]
|
||||
"! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT && TARGET_AS_CAN_SUBTRACT_LABELS"
|
||||
"\\n$LSJ%=:\;ldgp $29,$LSJ%=-%l0($27)"
|
||||
[(set_attr "length" "8")])
|
||||
[(set_attr "length" "8")
|
||||
(set_attr "type" "multi")])
|
||||
|
||||
(define_insn ""
|
||||
[(unspec_volatile [(match_operand 0 "" "")] 2)]
|
||||
"! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
|
||||
"br $27,$LSJ%=\\n$LSJ%=:\;ldgp $29,0($27)"
|
||||
[(set_attr "length" "12")])
|
||||
[(set_attr "length" "12")
|
||||
(set_attr "type" "multi")])
|
||||
|
||||
(define_expand "nonlocal_goto_receiver"
|
||||
[(unspec_volatile [(const_int 0)] 1)
|
||||
@ -5209,7 +5211,8 @@
|
||||
(clobber (reg:DI 0))]
|
||||
"TARGET_OPEN_VMS"
|
||||
"lda $0,OTS$HOME_ARGS\;ldq $0,8($0)\;jsr $0,OTS$HOME_ARGS"
|
||||
[(set_attr "length" "16")])
|
||||
[(set_attr "length" "16")
|
||||
(set_attr "type" "multi")])
|
||||
|
||||
;; Close the trap shadow of preceeding instructions. This is generated
|
||||
;; by alpha_reorg.
|
||||
@ -5219,6 +5222,31 @@
|
||||
""
|
||||
"trapb"
|
||||
[(set_attr "type" "misc")])
|
||||
|
||||
;; No-op instructions used by machine-dependant reorg to preserve
|
||||
;; alignment for instruction issue.
|
||||
|
||||
(define_insn "nop"
|
||||
[(const_int 0)]
|
||||
""
|
||||
"nop"
|
||||
[(set_attr "type" "ilog")])
|
||||
|
||||
(define_insn "fnop"
|
||||
[(const_int 1)]
|
||||
"TARGET_FP"
|
||||
"fnop"
|
||||
[(set_attr "type" "fcpys")])
|
||||
|
||||
(define_insn "unop"
|
||||
[(const_int 2)]
|
||||
""
|
||||
"unop")
|
||||
|
||||
(define_insn "realign"
|
||||
[(unspec_volatile [(match_operand 0 "immediate_operand" "i")] 6)]
|
||||
""
|
||||
".align %0 #realign")
|
||||
|
||||
;; Peepholes go at the end.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user