Skip to content

Commit b5365e7

Browse files
committed
cmd/7g: fix comparisons
Arm64 CPU uses op from, reg form, not op from, to. Fixes golang#5 Change-Id: I5203ee8f1c4fef52da2ec3da2afae07bf7ff0273
1 parent b417b32 commit b5365e7

File tree

4 files changed

+53
-16
lines changed

4 files changed

+53
-16
lines changed

src/cmd/7g/cgen.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ cgen(Node *n, Node *res)
348348
cgen(nl, &n1);
349349

350350
nodconst(&n2, types[tptr], 0);
351-
gins(optoas(OCMP, types[tptr]), &n1, &n2);
351+
gcmp(optoas(OCMP, types[tptr]), &n1, &n2);
352352
p1 = gbranch(optoas(OEQ, types[tptr]), T, 0);
353353

354354
n2 = n1;
@@ -383,7 +383,7 @@ cgen(Node *n, Node *res)
383383
cgen(nl, &n1);
384384

385385
nodconst(&n2, types[tptr], 0);
386-
gins(optoas(OCMP, types[tptr]), &n1, &n2);
386+
gcmp(optoas(OCMP, types[tptr]), &n1, &n2);
387387
p1 = gbranch(optoas(OEQ, types[tptr]), T, 0);
388388

389389
n2 = n1;
@@ -735,7 +735,7 @@ agenr(Node *n, Node *a, Node *res)
735735
p1->from.offset = nl->type->bound;
736736
}
737737
}
738-
gins(optoas(OCMP, types[TUINT64]), &n2, &n4);
738+
gcmp(optoas(OCMP, types[TUINT64]), &n2, &n4);
739739
if(n4.op == OREGISTER)
740740
regfree(&n4);
741741
p1 = gbranch(optoas(OLT, types[TUINT64]), T, +1);
@@ -1094,7 +1094,7 @@ bgen(Node *n, int true, int likely, Prog *to)
10941094
regalloc(&n1, n->type, N);
10951095
cgen(n, &n1);
10961096
nodconst(&n2, n->type, 0);
1097-
gins(optoas(OCMP, n->type), &n1, &n2);
1097+
gcmp(optoas(OCMP, n->type), &n1, &n2);
10981098
a = ABNE;
10991099
if(!true)
11001100
a = ABEQ;
@@ -1201,7 +1201,7 @@ bgen(Node *n, int true, int likely, Prog *to)
12011201
nodconst(&tmp, types[tptr], 0);
12021202
regalloc(&n2, types[tptr], &n1);
12031203
gmove(&n1, &n2);
1204-
gins(optoas(OCMP, types[tptr]), &n2, &tmp);
1204+
gcmp(optoas(OCMP, types[tptr]), &n2, &tmp);
12051205
regfree(&n2);
12061206
patch(gbranch(a, types[tptr], likely), to);
12071207
regfree(&n1);
@@ -1220,7 +1220,7 @@ bgen(Node *n, int true, int likely, Prog *to)
12201220
nodconst(&tmp, types[tptr], 0);
12211221
regalloc(&n2, types[tptr], &n1);
12221222
gmove(&n1, &n2);
1223-
gins(optoas(OCMP, types[tptr]), &n2, &tmp);
1223+
gcmp(optoas(OCMP, types[tptr]), &n2, &tmp);
12241224
regfree(&n2);
12251225
patch(gbranch(a, types[tptr], likely), to);
12261226
regfree(&n1);
@@ -1254,7 +1254,7 @@ bgen(Node *n, int true, int likely, Prog *to)
12541254
// TODO(minux): cmpi does accept 16-bit signed immediate as p->to.
12551255
// and cmpli accepts 16-bit unsigned immediate.
12561256
//if(smallintconst(nr)) {
1257-
// gins(optoas(OCMP, nr->type), &n1, nr);
1257+
// gcmp(optoas(OCMP, nr->type), &n1, nr);
12581258
// patch(gbranch(optoas(a, nr->type), nr->type, likely), to);
12591259
// regfree(&n1);
12601260
// break;
@@ -1265,7 +1265,7 @@ bgen(Node *n, int true, int likely, Prog *to)
12651265
cmp:
12661266
l = &n1;
12671267
r = &n2;
1268-
gins(optoas(OCMP, nr->type), l, r);
1268+
gcmp(optoas(OCMP, nr->type), l, r);
12691269
if(isfloat[nr->type->etype] && (a == OLE || a == OGE)) {
12701270
// To get NaN right, must rewrite x <= y into separate x < y or x = y.
12711271
switch(a) {
@@ -1501,7 +1501,7 @@ sgen(Node *n, Node *ns, int64 w)
15011501
p->to.type = D_OREG;
15021502
p->to.offset = dir;
15031503

1504-
p = gins(ACMP, &src, &nend);
1504+
p = gcmp(ACMP, &src, &nend);
15051505

15061506
patch(gbranch(ABNE, T, 0), ploop);
15071507
regfree(&nend);

src/cmd/7g/gg.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ void afunclit(Addr*, Node*);
9595
void nodfconst(Node*, Type*, Mpflt*);
9696
void gtrack(Sym*);
9797
void fixlargeoffset(Node *n);
98+
void raddr(Node *n, Prog *p);
99+
Prog* gcmp(int, Node*, Node*);
98100

99101
/*
100102
* cplx.c

src/cmd/7g/ggen.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ ginscall(Node *f, int proc)
261261

262262
if(proc == 2) {
263263
nodreg(&reg, types[TINT64], D_R0+3);
264-
p = gins(ACMP, &reg, N);
264+
p = gcmp(ACMP, &reg, N);
265265
p->to.type = D_REG;
266266
p->to.reg = D_R0;
267267
p = gbranch(ABEQ, T, +1);
@@ -562,7 +562,7 @@ dodiv(int op, Node *nl, Node *nr, Node *res)
562562
}
563563

564564
// Handle divide-by-zero panic.
565-
p1 = gins(optoas(OCMP, t), &tr, N);
565+
p1 = gcmp(optoas(OCMP, t), &tr, N);
566566
p1->to.type = D_REG;
567567
p1->to.reg = REGZERO;
568568
p1 = gbranch(optoas(ONE, t), T, +1);
@@ -573,7 +573,7 @@ dodiv(int op, Node *nl, Node *nr, Node *res)
573573

574574
if(check) {
575575
nodconst(&nm1, t, -1);
576-
gins(optoas(OCMP, t), &tr, &nm1);
576+
gcmp(optoas(OCMP, t), &tr, &nm1);
577577
p1 = gbranch(optoas(ONE, t), T, +1);
578578
if(op == ODIV) {
579579
// a / (-1) is -a.
@@ -857,7 +857,7 @@ cgen_shift(int op, int bounded, Node *nl, Node *nr, Node *res)
857857
// test and fix up large shifts
858858
if(!bounded) {
859859
nodconst(&n3, tcount, nl->type->width*8);
860-
gins(optoas(OCMP, tcount), &n1, &n3);
860+
gcmp(optoas(OCMP, tcount), &n1, &n3);
861861
p1 = gbranch(optoas(OLT, tcount), T, +1);
862862
if(op == ORSH && issigned[nl->type->etype]) {
863863
nodconst(&n3, types[TUINT32], nl->type->width*8-1);
@@ -923,7 +923,7 @@ clearfat(Node *nl)
923923
p->to.offset = 8;
924924
pl = p;
925925

926-
p = gins(ACMP, &dst, &end);
926+
p = gcmp(ACMP, &dst, &end);
927927
patch(gbranch(ABNE, T, 0), pl);
928928

929929
regfree(&end);

src/cmd/7g/gsubr.c

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -573,15 +573,15 @@ ginscon2(int as, Node *n2, vlong c)
573573
fatal("ginscon2");
574574
case ACMP:
575575
if(-BIG <= c && c <= BIG) {
576-
gins(as, n2, &n1);
576+
gcmp(as, n2, &n1);
577577
return;
578578
}
579579
break;
580580
}
581581
// MOV n1 into register first
582582
regalloc(&ntmp, types[TINT64], N);
583583
gins(AMOV, &n1, &ntmp);
584-
gins(as, n2, &ntmp);
584+
gcmp(as, n2, &ntmp);
585585
regfree(&ntmp);
586586
}
587587

@@ -1083,6 +1083,41 @@ fixlargeoffset(Node *n)
10831083
}
10841084
}
10851085

1086+
/*
1087+
* insert n into reg slot of p
1088+
*/
1089+
void
1090+
raddr(Node *n, Prog *p)
1091+
{
1092+
Addr a;
1093+
1094+
naddr(n, &a, 1);
1095+
if(a.type != D_REG && a.type != D_FREG) {
1096+
if(n)
1097+
fatal("bad in raddr: %O", n->op);
1098+
else
1099+
fatal("bad in raddr: <null>");
1100+
p->reg = NREG;
1101+
} else
1102+
p->reg = a.reg;
1103+
}
1104+
1105+
/* generate a comparison
1106+
TODO(kaib): one of the args can actually be a small constant. relax the constraint and fix call sites.
1107+
*/
1108+
Prog*
1109+
gcmp(int as, Node *lhs, Node *rhs)
1110+
{
1111+
Prog *p;
1112+
1113+
if(lhs->op != OREGISTER)
1114+
fatal("bad operands to gcmp: %O %O", lhs->op, rhs->op);
1115+
1116+
p = gins(as, rhs, N);
1117+
raddr(lhs, p);
1118+
return p;
1119+
}
1120+
10861121
/*
10871122
* generate code to compute n;
10881123
* make a refer to result.

0 commit comments

Comments
 (0)