p1 = gins(AMOVW, N, &n3);
datastring(nl->val.u.sval->s, nl->val.u.sval->len, &p1->from);
p1->from.type = D_CONST;
- } else if(isslice(nl->type) || nl->type->etype == TSTRING) {
+ } else
+ if(isslice(nl->type) || nl->type->etype == TSTRING) {
n1 = n3;
n1.op = OINDREG;
n1.type = types[tptr];
agen(n, a);
}
+void
+gencmp0(Node *n, Type *t, int o, Prog *to)
+{
+ Node n1, n2, n3;
+ int a;
+
+ regalloc(&n1, t, N);
+ cgen(n, &n1);
+ a = optoas(OCMP, t);
+ if(a != ACMP) {
+ nodconst(&n2, t, 0);
+ regalloc(&n3, t, N);
+ gmove(&n2, &n3);
+ gcmp(a, &n1, &n3);
+ regfree(&n3);
+ } else
+ gins(ATST, &n1, N);
+ a = optoas(o, t);
+ patch(gbranch(optoas(o, t), t), to);
+ regfree(&n1);
+}
+
/*
* generate:
* if(n == true) goto to;
switch(n->op) {
default:
def:
- regalloc(&n1, n->type, N);
- cgen(n, &n1);
- nodconst(&n2, n->type, 0);
- regalloc(&n3, n->type, N);
- gmove(&n2, &n3);
- gcmp(optoas(OCMP, n->type), &n1, &n3);
- a = ABNE;
+ a = ONE;
if(!true)
- a = ABEQ;
- patch(gbranch(a, n->type), to);
- regfree(&n1);
- regfree(&n3);
+ a = OEQ;
+ gencmp0(n, n->type, a, to);
goto ret;
case OLITERAL:
patch(gbranch(AB, T), to);
goto ret;
- case ONAME:
- if(n->addable == 0)
- goto def;
- nodconst(&n1, n->type, 0);
- regalloc(&n2, n->type, N);
- regalloc(&n3, n->type, N);
- gmove(&n1, &n2);
- cgen(n, &n3);
- gcmp(optoas(OCMP, n->type), &n2, &n3);
- a = ABNE;
- if(!true)
- a = ABEQ;
- patch(gbranch(a, n->type), to);
- regfree(&n2);
- regfree(&n3);
- goto ret;
-
case OANDAND:
if(!true)
goto caseor;
yyerror("illegal array comparison");
break;
}
+
+ regalloc(&n1, types[tptr], N);
+ agen(nl, &n1);
+ n2 = n1;
+ n2.op = OINDREG;
+ n2.xoffset = Array_array;
+ gencmp0(&n2, types[tptr], a, to);
+ regfree(&n1);
+ break;
+
a = optoas(a, types[tptr]);
regalloc(&n1, types[tptr], N);
regalloc(&n3, types[tptr], N);
yyerror("illegal interface comparison");
break;
}
+
+ regalloc(&n1, types[tptr], N);
+ agen(nl, &n1);
+ n2 = n1;
+ n2.op = OINDREG;
+ n2.xoffset = 0;
+ gencmp0(&n2, types[tptr], a, to);
+ regfree(&n1);
+ break;
+
a = optoas(a, types[tptr]);
regalloc(&n1, types[tptr], N);
regalloc(&n3, types[tptr], N);
break;
}
+ if(nr->op == OLITERAL) {
+ if(nr->val.ctype == CTINT && mpgetfix(nr->val.u.xval) == 0) {
+ gencmp0(nl, nl->type, a, to);
+ break;
+ }
+ if(nr->val.ctype == CTNIL) {
+ gencmp0(nl, nl->type, a, to);
+ break;
+ }
+ }
+
a = optoas(a, nr->type);
if(nr->ullman >= UINF) {
// shift is >= 1<<32
split64(r, &cl, &ch);
gmove(&ch, &s);
- p1 = gins(AMOVW, &s, &s);
- p1->scond |= C_SBIT;
+ p1 = gins(ATST, &s, N);
p6 = gbranch(ABNE, T);
gmove(&cl, &s);
splitclean();
gmove(r, &s);
p6 = P;
}
- p1 = gins(AMOVW, &s, &s);
- p1->scond |= C_SBIT;
+ p1 = gins(ATST, &s, N);
// shift == 0
p1 = gins(AMOVW, &bl, &al);
// shift is >= 1<<32
split64(r, &cl, &ch);
gmove(&ch, &s);
- p1 = gins(AMOVW, &s, &s);
- p1->scond |= C_SBIT;
+ p1 = gins(ATST, &s, N);
p6 = gbranch(ABNE, T);
gmove(&cl, &s);
splitclean();
gmove(r, &s);
p6 = P;
}
- p1 = gins(AMOVW, &s, &s);
- p1->scond |= C_SBIT;
+ p1 = gins(ATST, &s, N);
// shift == 0
p1 = gins(AMOVW, &bl, &al);
}
// test for shift being 0
- p1 = gins(AMOVW, &n1, &n1);
- p1->scond |= C_SBIT;
+ p1 = gins(ATST, &n1, N);
p3 = gbranch(ABEQ, T);
// test and fix up large shifts
/*
* elide shift into D_SHIFT operand of subsequent instruction
*/
- if(shiftprop(r)) {
- excise(r);
- t++;
- break;
- }
+// if(shiftprop(r)) {
+// excise(r);
+// t++;
+// break;
+// }
break;
case AMOVW:
case AMOVD:
if(!regtyp(&p->to))
break;
- if(isdconst(&p->from)) {
- constprop(&p->from, &p->to, r->s1);
- break;
- }
+// if(isdconst(&p->from)) {
+// constprop(&p->from, &p->to, r->s1);
+// break;
+// }
if(!regtyp(&p->from))
break;
if(p->from.type != p->to.type)
excise(r1);
}
- for(r=firstr; r!=R; r=r->link) {
- p = r->prog;
- switch(p->as) {
- case AMOVW:
- case AMOVB:
- case AMOVBU:
- if(p->from.type == D_OREG && p->from.offset == 0)
- xtramodes(r, &p->from);
- else if(p->to.type == D_OREG && p->to.offset == 0)
- xtramodes(r, &p->to);
- else
- continue;
- break;
- case ACMP:
- /*
- * elide CMP $0,x if calculation of x can set condition codes
- */
- if(isdconst(&p->from) || p->from.offset != 0)
- continue;
- r2 = r->s1;
- if(r2 == R)
- continue;
- t = r2->prog->as;
- switch(t) {
- default:
- continue;
- case ABEQ:
- case ABNE:
- case ABMI:
- case ABPL:
- break;
- case ABGE:
- t = ABPL;
- break;
- case ABLT:
- t = ABMI;
- break;
- case ABHI:
- t = ABNE;
- break;
- case ABLS:
- t = ABEQ;
- break;
- }
- r1 = r;
- do
- r1 = uniqp(r1);
- while (r1 != R && r1->prog->as == ANOP);
- if(r1 == R)
- continue;
- p1 = r1->prog;
- if(p1->to.type != D_REG)
- continue;
- if(p1->to.reg != p->reg)
- if(!(p1->as == AMOVW && p1->from.type == D_REG && p1->from.reg == p->reg))
- continue;
- switch(p1->as) {
- default:
- continue;
- case AMOVW:
- if(p1->from.type != D_REG)
- continue;
- case AAND:
- case AEOR:
- case AORR:
- case ABIC:
- case AMVN:
- case ASUB:
- case ARSB:
- case AADD:
- case AADC:
- case ASBC:
- case ARSC:
- break;
- }
- p1->scond |= C_SBIT;
- r2->prog->as = t;
- excise(r);
- continue;
- }
- }
+// for(r=firstr; r!=R; r=r->link) {
+// p = r->prog;
+// switch(p->as) {
+// case AMOVW:
+// case AMOVB:
+// case AMOVBU:
+// if(p->from.type == D_OREG && p->from.offset == 0)
+// xtramodes(r, &p->from);
+// else
+// if(p->to.type == D_OREG && p->to.offset == 0)
+// xtramodes(r, &p->to);
+// else
+// continue;
+// break;
+// case ACMP:
+// /*
+// * elide CMP $0,x if calculation of x can set condition codes
+// */
+// if(isdconst(&p->from) || p->from.offset != 0)
+// continue;
+// r2 = r->s1;
+// if(r2 == R)
+// continue;
+// t = r2->prog->as;
+// switch(t) {
+// default:
+// continue;
+// case ABEQ:
+// case ABNE:
+// case ABMI:
+// case ABPL:
+// break;
+// case ABGE:
+// t = ABPL;
+// break;
+// case ABLT:
+// t = ABMI;
+// break;
+// case ABHI:
+// t = ABNE;
+// break;
+// case ABLS:
+// t = ABEQ;
+// break;
+// }
+// r1 = r;
+// do
+// r1 = uniqp(r1);
+// while (r1 != R && r1->prog->as == ANOP);
+// if(r1 == R)
+// continue;
+// p1 = r1->prog;
+// if(p1->to.type != D_REG)
+// continue;
+// if(p1->to.reg != p->reg)
+// if(!(p1->as == AMOVW && p1->from.type == D_REG && p1->from.reg == p->reg))
+// continue;
+//
+// switch(p1->as) {
+// default:
+// continue;
+// case AMOVW:
+// if(p1->from.type != D_REG)
+// continue;
+// case AAND:
+// case AEOR:
+// case AORR:
+// case ABIC:
+// case AMVN:
+// case ASUB:
+// case ARSB:
+// case AADD:
+// case AADC:
+// case ASBC:
+// case ARSC:
+// break;
+// }
+// p1->scond |= C_SBIT;
+// r2->prog->as = t;
+// excise(r);
+// continue;
+// }
+// }
predicate();
}
case ABL:
return 0;
- case ACMP:
case ACMN:
case AADD:
case ASUB:
case ADIV:
case ADIVU:
- case ACMPF:
- case ACMPD:
case AADDD:
case AADDF:
case ASUBD:
print("\t=>%P", p1);
}
case ABIC:
+ case ATST:
case ACMP:
case ACMN:
if(p1->reg == n)
switch(p->as) {
default:
- if(debug['P'])
- print(" (?)");
+ print("copyu: cant find %A\n", p->as);
return 2;
case AMOVM:
case ACMPF:
case ACMPD:
+ case ATST:
case ACMP:
case ACMN:
case ACASE:
switch(p->as) {
+ case ATST:
case ACMP:
case ACMN:
modifiescpsr(Prog *p)
{
switch(p->as) {
- case ATST:
case ATEQ:
case ACMN:
+ case ATST:
case ACMP:
case AMULU:
case ADIVU:
uint32 vreg;
Bits bit;
-return; // disabled for the moment
+return;
+
if(first == 0) {
fmtinstall('Q', Qconv);
}
* peep-hole on basic block
*/
if(!debug['R'] || debug['P']) {
-// peep();
+ peep();
}
/*
rt = 0;
if(p->as == AMOVW || p->as == AMVN)
r = 0;
- else if(r == NREG)
+ else
+ if(r == NREG)
r = rt;
o1 |= rf | (r<<16) | (rt<<12);
break;
o1 |= (p->from.reg<<16);
o1 |= (p->to.reg<<12);
break;
+
+ case 90: /* tst reg */
+ o1 = oprrr(AMOVW, p->scond);
+ o1 |= p->from.reg | (p->from.reg<<12);
+ o1 |= 1 << 20; // SBIT
+ break;
}
out[0] = o1;
{ AB, C_NONE, C_NONE, C_ROREG, 6, 4, 0, LPOOL },
{ ABL, C_NONE, C_NONE, C_ROREG, 7, 8, 0 },
{ ABX, C_NONE, C_NONE, C_ROREG, 75, 12, 0 },
- { ABXRET, C_NONE, C_NONE, C_ROREG, 76, 4, 0 },
+ { ABXRET, C_NONE, C_NONE, C_ROREG, 76, 4, 0 },
{ ASLL, C_RCON, C_REG, C_REG, 8, 4, 0 },
{ ASLL, C_RCON, C_NONE, C_REG, 8, 4, 0 },
{ AMOVW, C_REG, C_NONE, C_FREG, 88, 4, 0 },
{ AMOVW, C_FREG, C_NONE, C_REG, 89, 4, 0 },
+ { ATST, C_REG, C_NONE, C_NONE, 90, 4, 0 },
+
{ AXXX, C_NONE, C_NONE, C_NONE, 0, 4, 0 },
};
oprange[ABIC] = oprange[r];
break;
case ACMP:
- oprange[ATST] = oprange[r];
oprange[ATEQ] = oprange[r];
oprange[ACMN] = oprange[r];
break;
case ALDREX:
case ASTREX:
+ case ATST:
break;
}
}