From cbe45e78f988184938ab63f8bac28632058e5810 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Sun, 2 Aug 2020 19:48:25 +0200 Subject: 7c: fix wrong type on OASxxx operations the bug can be reproduced with the following test case: #include #include 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(). --- sys/src/cmd/7c/cgen.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/sys/src/cmd/7c/cgen.c b/sys/src/cmd/7c/cgen.c index 2e6010b81..d7536aad0 100644 --- a/sys/src/cmd/7c/cgen.c +++ b/sys/src/cmd/7c/cgen.c @@ -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) -- cgit v1.2.3