]> git.lizzy.rs Git - plan9front.git/commitdiff
7c: fix wrong type on OASxxx operations
authorcinap_lenrek <cinap_lenrek@felloff.net>
Sun, 2 Aug 2020 17:48:25 +0000 (19:48 +0200)
committercinap_lenrek <cinap_lenrek@felloff.net>
Sun, 2 Aug 2020 17:48:25 +0000 (19:48 +0200)
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().

sys/src/cmd/7c/cgen.c

index 2e6010b817fb1f187c8aaa718940f7484c796194..d7536aad077dd0ace31fee1b912c3c26e3ae9d17 100644 (file)
@@ -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)