Line 373... |
Line 373... |
add = f->bb[pred].ninsn;
|
add = f->bb[pred].ninsn;
|
if (f->bb[pred].ninsn <= 0
|
if (f->bb[pred].ninsn <= 0
|
|| !(f->bb[pred].insn[f->bb[pred].ninsn - 1].type & IT_BRANCH)) type = 1;
|
|| !(f->bb[pred].insn[f->bb[pred].ninsn - 1].type & IT_BRANCH)) type = 1;
|
if (type == 0 && f->bb[succ].prev[0] == f->bb[succ].next[0]) add_cond = 1;
|
if (type == 0 && f->bb[succ].prev[0] == f->bb[succ].next[0]) add_cond = 1;
|
|
|
ninsn = f->bb[pred].ninsn + f->bb[succ].ninsn + (type == 0 || type == 2 ? 1 : 0)
|
ninsn = f->bb[pred].ninsn + f->bb[succ].ninsn + (type == 0 ? 1 : type == 1 ? 0 : 2)
|
+ (add_cond ? MAX_REGS : 0);
|
+ (add_cond ? MAX_REGS : 0);
|
|
|
insn = (cuc_insn *) malloc (ninsn * sizeof (cuc_insn));
|
insn = (cuc_insn *) malloc (ninsn * sizeof (cuc_insn));
|
for (i = 0; i < add; i++) insn[i] = f->bb[pred].insn[i];
|
for (i = 0; i < add; i++) insn[i] = f->bb[pred].insn[i];
|
/* when type == 0, we copy the last (jump) instruction to the end */
|
/* when type == 0, we copy the last (jump) instruction to the end */
|
if (type == 0 || type == 2) {
|
if (type == 0 || type == 2) {
|
insn[ninsn - 1] = insn[add - 1];
|
insn[ninsn - 1] = insn[add - 1];
|
cond_op = insn[add - 1].op[1];
|
cond_op = insn[add - 1].op[1];
|
cond_opt = insn[add - 1].opt[1];
|
cond_opt = insn[add - 1].opt[1];
|
change_insn_type (&insn[add - 1], II_NOP);
|
change_insn_type (&insn[add - 1], II_NOP);
|
/* and when type == 2, we must add sfor instruction, to quit when either is true */
|
}
|
|
/* Copy second block */
|
|
for (i = 0; i < f->bb[succ].ninsn; i++) insn[i + f->bb[pred].ninsn] = f->bb[succ].insn[i];
|
|
|
|
|
|
/* and when type == 2, we may need to add sfor instruction, to quit when either is true */
|
if (type == 2) {
|
if (type == 2) {
|
/* TODO */
|
|
assert (0);
|
assert (0);
|
}
|
}
|
|
|
|
/* LRBB at start of succ BB is not valid, it should be set when */
|
|
if (insn[add].index == II_LRBB) {
|
|
assert (0); /* not tested yet */
|
|
change_insn_type (&insn[add], II_NOP);
|
|
for (i = add; i < ninsn; i++)
|
|
if (insn[i].index == II_CMOV && insn[i].op[3] == REF (succ, add)) {
|
|
assert (insn[i].opt[3] == OPT_REF);
|
|
insn[i].op[3] = cond_op;
|
|
insn[i].opt[3] = cond_opt;
|
|
if (f->bb[pred].next[0] != succ) {
|
|
unsigned long t; /* negate conditional -- exchange */
|
|
assert (f->bb[pred].next[1] == succ);
|
|
t = insn[i].op[1];
|
|
insn[i].op[1] = insn[i].op[2];
|
|
insn[i].op[2] = t;
|
|
t = insn[i].opt[1];
|
|
insn[i].opt[1] = insn[i].opt[2];
|
|
insn[i].opt[2] = t;
|
|
}
|
|
}
|
}
|
}
|
/* Copy second block */
|
|
for (i = 0; i < f->bb[succ].ninsn; i++) insn[i + f->bb[pred].ninsn] = f->bb[succ].insn[i];
|
|
|
|
for (i = 0; i < ninsn; i++) reloc[i] = -1;
|
for (i = 0; i < ninsn; i++) reloc[i] = -1;
|
|
|
/* Add conditional instructions if required */
|
/* Add conditional instructions if required */
|
if (add_cond) {
|
if (add_cond) {
|