|
Lines 6118-6123
Link Here
|
| 6118 |
} |
6118 |
} |
| 6119 |
} |
6119 |
} |
| 6120 |
|
6120 |
|
|
|
6121 |
/* Return TRUE if INSN, a jump insn, has an unfilled delay slot and |
| 6122 |
it branches into the delay slot. Otherwise, return FALSE. */ |
| 6123 |
|
| 6124 |
static bool |
| 6125 |
branch_to_delay_slot_p (rtx insn) |
| 6126 |
{ |
| 6127 |
rtx jump_insn; |
| 6128 |
|
| 6129 |
if (dbr_sequence_length ()) |
| 6130 |
return FALSE; |
| 6131 |
|
| 6132 |
jump_insn = next_active_insn (JUMP_LABEL (insn)); |
| 6133 |
while (insn) |
| 6134 |
{ |
| 6135 |
insn = next_active_insn (insn); |
| 6136 |
if (jump_insn == insn) |
| 6137 |
return TRUE; |
| 6138 |
|
| 6139 |
/* We can't rely on the length of asms. So, we return FALSE when |
| 6140 |
the branch is followed by an asm. */ |
| 6141 |
if (!insn |
| 6142 |
|| GET_CODE (PATTERN (insn)) == ASM_INPUT |
| 6143 |
|| asm_noperands (PATTERN (insn)) >= 0 |
| 6144 |
|| get_attr_length (insn) > 0) |
| 6145 |
break; |
| 6146 |
} |
| 6147 |
|
| 6148 |
return FALSE; |
| 6149 |
} |
| 6150 |
|
| 6151 |
/* Return TRUE if INSN, a forward jump insn, needs a nop in its delay slot. |
| 6152 |
|
| 6153 |
This occurs when INSN has an unfilled delay slot and is followed |
| 6154 |
by an asm. Disaster can occur if the asm is empty and the jump |
| 6155 |
branches into the delay slot. So, we add a nop in the delay slot |
| 6156 |
when this occurs. */ |
| 6157 |
|
| 6158 |
static bool |
| 6159 |
branch_needs_nop_p (rtx insn) |
| 6160 |
{ |
| 6161 |
rtx jump_insn; |
| 6162 |
|
| 6163 |
if (dbr_sequence_length ()) |
| 6164 |
return FALSE; |
| 6165 |
|
| 6166 |
jump_insn = next_active_insn (JUMP_LABEL (insn)); |
| 6167 |
while (insn) |
| 6168 |
{ |
| 6169 |
insn = next_active_insn (insn); |
| 6170 |
if (!insn || jump_insn == insn) |
| 6171 |
return TRUE; |
| 6172 |
|
| 6173 |
if (!(GET_CODE (PATTERN (insn)) == ASM_INPUT |
| 6174 |
|| asm_noperands (PATTERN (insn)) >= 0) |
| 6175 |
&& get_attr_length (insn) > 0) |
| 6176 |
break; |
| 6177 |
} |
| 6178 |
|
| 6179 |
return FALSE; |
| 6180 |
} |
| 6181 |
|
| 6182 |
/* Return TRUE if INSN, a forward jump insn, can use nullification |
| 6183 |
to skip the following instruction. This avoids an extra cycle due |
| 6184 |
to a mis-predicted branch when we fall through. */ |
| 6185 |
|
| 6186 |
static bool |
| 6187 |
use_skip_p (rtx insn) |
| 6188 |
{ |
| 6189 |
rtx jump_insn = next_active_insn (JUMP_LABEL (insn)); |
| 6190 |
|
| 6191 |
while (insn) |
| 6192 |
{ |
| 6193 |
insn = next_active_insn (insn); |
| 6194 |
|
| 6195 |
/* We can't rely on the length of asms, so we can't skip asms. */ |
| 6196 |
if (!insn |
| 6197 |
|| GET_CODE (PATTERN (insn)) == ASM_INPUT |
| 6198 |
|| asm_noperands (PATTERN (insn)) >= 0) |
| 6199 |
break; |
| 6200 |
if (get_attr_length (insn) == 4 |
| 6201 |
&& jump_insn == next_active_insn (insn)) |
| 6202 |
return TRUE; |
| 6203 |
if (get_attr_length (insn) > 0) |
| 6204 |
break; |
| 6205 |
} |
| 6206 |
|
| 6207 |
return FALSE; |
| 6208 |
} |
| 6209 |
|
| 6121 |
/* This routine handles all the normal conditional branch sequences we |
6210 |
/* This routine handles all the normal conditional branch sequences we |
| 6122 |
might need to generate. It handles compare immediate vs compare |
6211 |
might need to generate. It handles compare immediate vs compare |
| 6123 |
register, nullification of delay slots, varying length branches, |
6212 |
register, nullification of delay slots, varying length branches, |
|
Lines 6129-6135
Link Here
|
| 6129 |
output_cbranch (rtx *operands, int negated, rtx insn) |
6218 |
output_cbranch (rtx *operands, int negated, rtx insn) |
| 6130 |
{ |
6219 |
{ |
| 6131 |
static char buf[100]; |
6220 |
static char buf[100]; |
| 6132 |
int useskip = 0; |
6221 |
bool useskip; |
| 6133 |
int nullify = INSN_ANNULLED_BRANCH_P (insn); |
6222 |
int nullify = INSN_ANNULLED_BRANCH_P (insn); |
| 6134 |
int length = get_attr_length (insn); |
6223 |
int length = get_attr_length (insn); |
| 6135 |
int xdelay; |
6224 |
int xdelay; |
|
Lines 6143-6149
Link Here
|
| 6143 |
slot and the same branch target as this branch. We could check |
6232 |
slot and the same branch target as this branch. We could check |
| 6144 |
for this but jump optimization should eliminate nop jumps. It |
6233 |
for this but jump optimization should eliminate nop jumps. It |
| 6145 |
is always safe to emit a nop. */ |
6234 |
is always safe to emit a nop. */ |
| 6146 |
if (next_real_insn (JUMP_LABEL (insn)) == next_real_insn (insn)) |
6235 |
if (branch_to_delay_slot_p (insn)) |
| 6147 |
return "nop"; |
6236 |
return "nop"; |
| 6148 |
|
6237 |
|
| 6149 |
/* The doubleword form of the cmpib instruction doesn't have the LEU |
6238 |
/* The doubleword form of the cmpib instruction doesn't have the LEU |
|
Lines 6167-6178
Link Here
|
| 6167 |
/* A forward branch over a single nullified insn can be done with a |
6256 |
/* A forward branch over a single nullified insn can be done with a |
| 6168 |
comclr instruction. This avoids a single cycle penalty due to |
6257 |
comclr instruction. This avoids a single cycle penalty due to |
| 6169 |
mis-predicted branch if we fall through (branch not taken). */ |
6258 |
mis-predicted branch if we fall through (branch not taken). */ |
| 6170 |
if (length == 4 |
6259 |
useskip = (length == 4 && nullify) ? use_skip_p (insn) : FALSE; |
| 6171 |
&& next_real_insn (insn) != 0 |
|
|
| 6172 |
&& get_attr_length (next_real_insn (insn)) == 4 |
| 6173 |
&& JUMP_LABEL (insn) == next_nonnote_insn (next_real_insn (insn)) |
| 6174 |
&& nullify) |
| 6175 |
useskip = 1; |
| 6176 |
|
6260 |
|
| 6177 |
switch (length) |
6261 |
switch (length) |
| 6178 |
{ |
6262 |
{ |
|
Lines 6192-6198
Link Here
|
| 6192 |
if (useskip) |
6276 |
if (useskip) |
| 6193 |
strcat (buf, " %2,%r1,%%r0"); |
6277 |
strcat (buf, " %2,%r1,%%r0"); |
| 6194 |
else if (nullify) |
6278 |
else if (nullify) |
| 6195 |
strcat (buf, ",n %2,%r1,%0"); |
6279 |
{ |
|
|
6280 |
if (branch_needs_nop_p (insn)) |
| 6281 |
strcat (buf, ",n %2,%r1,%0%#"); |
| 6282 |
else |
| 6283 |
strcat (buf, ",n %2,%r1,%0"); |
| 6284 |
} |
| 6196 |
else |
6285 |
else |
| 6197 |
strcat (buf, " %2,%r1,%0"); |
6286 |
strcat (buf, " %2,%r1,%0"); |
| 6198 |
break; |
6287 |
break; |
|
Lines 6455-6461
Link Here
|
| 6455 |
output_bb (rtx *operands ATTRIBUTE_UNUSED, int negated, rtx insn, int which) |
6544 |
output_bb (rtx *operands ATTRIBUTE_UNUSED, int negated, rtx insn, int which) |
| 6456 |
{ |
6545 |
{ |
| 6457 |
static char buf[100]; |
6546 |
static char buf[100]; |
| 6458 |
int useskip = 0; |
6547 |
bool useskip; |
| 6459 |
int nullify = INSN_ANNULLED_BRANCH_P (insn); |
6548 |
int nullify = INSN_ANNULLED_BRANCH_P (insn); |
| 6460 |
int length = get_attr_length (insn); |
6549 |
int length = get_attr_length (insn); |
| 6461 |
int xdelay; |
6550 |
int xdelay; |
|
Lines 6465-6471
Link Here
|
| 6465 |
is only used when optimizing; jump optimization should eliminate the |
6555 |
is only used when optimizing; jump optimization should eliminate the |
| 6466 |
jump. But be prepared just in case. */ |
6556 |
jump. But be prepared just in case. */ |
| 6467 |
|
6557 |
|
| 6468 |
if (next_real_insn (JUMP_LABEL (insn)) == next_real_insn (insn)) |
6558 |
if (branch_to_delay_slot_p (insn)) |
| 6469 |
return "nop"; |
6559 |
return "nop"; |
| 6470 |
|
6560 |
|
| 6471 |
/* If this is a long branch with its delay slot unfilled, set `nullify' |
6561 |
/* If this is a long branch with its delay slot unfilled, set `nullify' |
|
Lines 6481-6493
Link Here
|
| 6481 |
/* A forward branch over a single nullified insn can be done with a |
6580 |
/* A forward branch over a single nullified insn can be done with a |
| 6482 |
extrs instruction. This avoids a single cycle penalty due to |
6581 |
extrs instruction. This avoids a single cycle penalty due to |
| 6483 |
mis-predicted branch if we fall through (branch not taken). */ |
6582 |
mis-predicted branch if we fall through (branch not taken). */ |
| 6484 |
|
6583 |
useskip = (length == 4 && nullify) ? use_skip_p (insn) : FALSE; |
| 6485 |
if (length == 4 |
|
|
| 6486 |
&& next_real_insn (insn) != 0 |
| 6487 |
&& get_attr_length (next_real_insn (insn)) == 4 |
| 6488 |
&& JUMP_LABEL (insn) == next_nonnote_insn (next_real_insn (insn)) |
| 6489 |
&& nullify) |
| 6490 |
useskip = 1; |
| 6491 |
|
6584 |
|
| 6492 |
switch (length) |
6585 |
switch (length) |
| 6493 |
{ |
6586 |
{ |
|
Lines 6511-6521
Link Here
|
| 6511 |
if (useskip) |
6594 |
if (useskip) |
| 6512 |
strcat (buf, " %0,%1,1,%%r0"); |
6595 |
strcat (buf, " %0,%1,1,%%r0"); |
| 6513 |
else if (nullify && negated) |
6596 |
else if (nullify && negated) |
| 6514 |
strcat (buf, ",n %0,%1,%3"); |
6597 |
{ |
|
|
6598 |
if (branch_needs_nop_p (insn)) |
| 6599 |
strcat (buf, ",n %0,%1,%3%#"); |
| 6600 |
else |
| 6601 |
strcat (buf, ",n %0,%1,%3"); |
| 6602 |
} |
| 6515 |
else if (nullify && ! negated) |
6603 |
else if (nullify && ! negated) |
| 6516 |
strcat (buf, ",n %0,%1,%2"); |
6604 |
{ |
|
|
6605 |
if (branch_needs_nop_p (insn)) |
| 6606 |
strcat (buf, ",n %0,%1,%2%#"); |
| 6607 |
else |
| 6608 |
strcat (buf, ",n %0,%1,%2"); |
| 6609 |
} |
| 6517 |
else if (! nullify && negated) |
6610 |
else if (! nullify && negated) |
| 6518 |
strcat (buf, "%0,%1,%3"); |
6611 |
strcat (buf, " %0,%1,%3"); |
| 6519 |
else if (! nullify && ! negated) |
6612 |
else if (! nullify && ! negated) |
| 6520 |
strcat (buf, " %0,%1,%2"); |
6613 |
strcat (buf, " %0,%1,%2"); |
| 6521 |
break; |
6614 |
break; |
|
Lines 6636-6642
Link Here
|
| 6636 |
output_bvb (rtx *operands ATTRIBUTE_UNUSED, int negated, rtx insn, int which) |
6729 |
output_bvb (rtx *operands ATTRIBUTE_UNUSED, int negated, rtx insn, int which) |
| 6637 |
{ |
6730 |
{ |
| 6638 |
static char buf[100]; |
6731 |
static char buf[100]; |
| 6639 |
int useskip = 0; |
6732 |
bool useskip; |
| 6640 |
int nullify = INSN_ANNULLED_BRANCH_P (insn); |
6733 |
int nullify = INSN_ANNULLED_BRANCH_P (insn); |
| 6641 |
int length = get_attr_length (insn); |
6734 |
int length = get_attr_length (insn); |
| 6642 |
int xdelay; |
6735 |
int xdelay; |
|
Lines 6646-6652
Link Here
|
| 6646 |
is only used when optimizing; jump optimization should eliminate the |
6739 |
is only used when optimizing; jump optimization should eliminate the |
| 6647 |
jump. But be prepared just in case. */ |
6740 |
jump. But be prepared just in case. */ |
| 6648 |
|
6741 |
|
| 6649 |
if (next_real_insn (JUMP_LABEL (insn)) == next_real_insn (insn)) |
6742 |
if (branch_to_delay_slot_p (insn)) |
| 6650 |
return "nop"; |
6743 |
return "nop"; |
| 6651 |
|
6744 |
|
| 6652 |
/* If this is a long branch with its delay slot unfilled, set `nullify' |
6745 |
/* If this is a long branch with its delay slot unfilled, set `nullify' |
|
Lines 6662-6674
Link Here
|
| 6662 |
/* A forward branch over a single nullified insn can be done with a |
6755 |
/* A forward branch over a single nullified insn can be done with a |
| 6663 |
extrs instruction. This avoids a single cycle penalty due to |
6756 |
extrs instruction. This avoids a single cycle penalty due to |
| 6664 |
mis-predicted branch if we fall through (branch not taken). */ |
6757 |
mis-predicted branch if we fall through (branch not taken). */ |
| 6665 |
|
6758 |
useskip = (length == 4 && nullify) ? use_skip_p (insn) : FALSE; |
| 6666 |
if (length == 4 |
|
|
| 6667 |
&& next_real_insn (insn) != 0 |
| 6668 |
&& get_attr_length (next_real_insn (insn)) == 4 |
| 6669 |
&& JUMP_LABEL (insn) == next_nonnote_insn (next_real_insn (insn)) |
| 6670 |
&& nullify) |
| 6671 |
useskip = 1; |
| 6672 |
|
6759 |
|
| 6673 |
switch (length) |
6760 |
switch (length) |
| 6674 |
{ |
6761 |
{ |
|
Lines 6692-6702
Link Here
|
| 6692 |
if (useskip) |
6779 |
if (useskip) |
| 6693 |
strcat (buf, "{ %0,1,%%r0| %0,%%sar,1,%%r0}"); |
6780 |
strcat (buf, "{ %0,1,%%r0| %0,%%sar,1,%%r0}"); |
| 6694 |
else if (nullify && negated) |
6781 |
else if (nullify && negated) |
| 6695 |
strcat (buf, "{,n %0,%3|,n %0,%%sar,%3}"); |
6782 |
{ |
|
|
6783 |
if (branch_needs_nop_p (insn)) |
| 6784 |
strcat (buf, "{,n %0,%3%#|,n %0,%%sar,%3%#}"); |
| 6785 |
else |
| 6786 |
strcat (buf, "{,n %0,%3|,n %0,%%sar,%3}"); |
| 6787 |
} |
| 6696 |
else if (nullify && ! negated) |
6788 |
else if (nullify && ! negated) |
| 6697 |
strcat (buf, "{,n %0,%2|,n %0,%%sar,%2}"); |
6789 |
{ |
|
|
6790 |
if (branch_needs_nop_p (insn)) |
| 6791 |
strcat (buf, "{,n %0,%2%#|,n %0,%%sar,%2%#}"); |
| 6792 |
else |
| 6793 |
strcat (buf, "{,n %0,%2|,n %0,%%sar,%2}"); |
| 6794 |
} |
| 6698 |
else if (! nullify && negated) |
6795 |
else if (! nullify && negated) |
| 6699 |
strcat (buf, "{%0,%3|%0,%%sar,%3}"); |
6796 |
strcat (buf, "{ %0,%3| %0,%%sar,%3}"); |
| 6700 |
else if (! nullify && ! negated) |
6797 |
else if (! nullify && ! negated) |
| 6701 |
strcat (buf, "{ %0,%2| %0,%%sar,%2}"); |
6798 |
strcat (buf, "{ %0,%2| %0,%%sar,%2}"); |
| 6702 |
break; |
6799 |
break; |
|
Lines 6818-6824
Link Here
|
| 6818 |
/* A conditional branch to the following instruction (e.g. the delay slot) is |
6915 |
/* A conditional branch to the following instruction (e.g. the delay slot) is |
| 6819 |
asking for a disaster. Be prepared! */ |
6916 |
asking for a disaster. Be prepared! */ |
| 6820 |
|
6917 |
|
| 6821 |
if (next_real_insn (JUMP_LABEL (insn)) == next_real_insn (insn)) |
6918 |
if (branch_to_delay_slot_p (insn)) |
| 6822 |
{ |
6919 |
{ |
| 6823 |
if (which_alternative == 0) |
6920 |
if (which_alternative == 0) |
| 6824 |
return "ldo %1(%0),%0"; |
6921 |
return "ldo %1(%0),%0"; |
|
Lines 6855-6861
Link Here
|
| 6855 |
{ |
6952 |
{ |
| 6856 |
case 4: |
6953 |
case 4: |
| 6857 |
if (nullify) |
6954 |
if (nullify) |
| 6858 |
return "addib,%C2,n %1,%0,%3"; |
6955 |
{ |
|
|
6956 |
if (branch_needs_nop_p (insn)) |
| 6957 |
return "addib,%C2,n %1,%0,%3%#"; |
| 6958 |
else |
| 6959 |
return "addib,%C2,n %1,%0,%3"; |
| 6960 |
} |
| 6859 |
else |
6961 |
else |
| 6860 |
return "addib,%C2 %1,%0,%3"; |
6962 |
return "addib,%C2 %1,%0,%3"; |
| 6861 |
|
6963 |
|
|
Lines 6963-6969
Link Here
|
| 6963 |
/* A conditional branch to the following instruction (e.g. the delay slot) is |
7065 |
/* A conditional branch to the following instruction (e.g. the delay slot) is |
| 6964 |
asking for a disaster. Be prepared! */ |
7066 |
asking for a disaster. Be prepared! */ |
| 6965 |
|
7067 |
|
| 6966 |
if (next_real_insn (JUMP_LABEL (insn)) == next_real_insn (insn)) |
7068 |
if (branch_to_delay_slot_p (insn)) |
| 6967 |
{ |
7069 |
{ |
| 6968 |
if (which_alternative == 0) |
7070 |
if (which_alternative == 0) |
| 6969 |
return "copy %1,%0"; |
7071 |
return "copy %1,%0"; |
|
Lines 7001-7007
Link Here
|
| 7001 |
{ |
7103 |
{ |
| 7002 |
case 4: |
7104 |
case 4: |
| 7003 |
if (nullify) |
7105 |
if (nullify) |
| 7004 |
return "movb,%C2,n %1,%0,%3"; |
7106 |
{ |
|
|
7107 |
if (branch_needs_nop_p (insn)) |
| 7108 |
return "movb,%C2,n %1,%0,%3%#"; |
| 7109 |
else |
| 7110 |
return "movb,%C2,n %1,%0,%3"; |
| 7111 |
} |
| 7005 |
else |
7112 |
else |
| 7006 |
return "movb,%C2 %1,%0,%3"; |
7113 |
return "movb,%C2 %1,%0,%3"; |
| 7007 |
|
7114 |
|