7c: fix wrong type on OASxxx operations
the bug can be reproduced with the following test case: #include <u.h> #include <libc.h> void main() { int size = 1; size*=1.5; exits(0); } this produces the following assembly: TEXT main+0(SB),0,$16 MOVW $1,R1 FCVTZSDW $1.50000000000000000e+00,R2 <- tries to convert rhs to int?? MULW R2,R1,R2 <- multiplication done in int? bug! MOV $0,R0 BL ,exits+0(SB) RETURN , END , the confusion comes from the *= operation using the wrong type for the multiplication. in this case we should use the float type of the rhs, do the operation, and then convert the result back to int type of the lhs. this change ports the same logic from 5c's getasop().
This commit is contained in:
parent
cf69bb920a
commit
cbe45e78f9
1 changed files with 11 additions and 14 deletions
|
@ -287,28 +287,25 @@ cgenrel(Node *n, Node *nn, int inrel)
|
|||
reglcgen(&nod2, l, Z);
|
||||
else
|
||||
nod2 = *l;
|
||||
regalloc(&nod, n, nn);
|
||||
cgen(r, &nod);
|
||||
regalloc(&nod1, r, Z);
|
||||
cgen(r, &nod1);
|
||||
} else {
|
||||
regalloc(&nod, n, nn);
|
||||
cgen(r, &nod);
|
||||
regalloc(&nod1, r, Z);
|
||||
cgen(r, &nod1);
|
||||
if(l->addable < INDEXED)
|
||||
reglcgen(&nod2, l, Z);
|
||||
else
|
||||
nod2 = *l;
|
||||
}
|
||||
regalloc(&nod1, n, Z);
|
||||
gopcode(OAS, &nod2, Z, &nod1);
|
||||
if(nod1.type->etype != nod.type->etype){
|
||||
regalloc(&nod3, &nod, Z);
|
||||
gmove(&nod1, &nod3);
|
||||
regfree(&nod1);
|
||||
nod1 = nod3;
|
||||
}
|
||||
gopcode(o, &nod, &nod1, &nod);
|
||||
if(nod1.type == nod2.type || !typefd[nod1.type->etype])
|
||||
regalloc(&nod, &nod2, nn);
|
||||
else
|
||||
regalloc(&nod, &nod1, Z);
|
||||
gmove(&nod2, &nod);
|
||||
gopcode(o, &nod1, &nod, &nod);
|
||||
gmove(&nod, &nod2);
|
||||
if(nn != Z)
|
||||
gmove(&nod, nn);
|
||||
gmove(&nod2, nn);
|
||||
regfree(&nod);
|
||||
regfree(&nod1);
|
||||
if(l->addable < INDEXED)
|
||||
|
|
Loading…
Reference in a new issue