diff options
-rw-r--r-- | src/cmd/6g/ggen.c | 38 | ||||
-rw-r--r-- | test/ken/divconst.go | 110 | ||||
-rw-r--r-- | test/ken/modconst.go | 110 |
3 files changed, 250 insertions, 8 deletions
diff --git a/src/cmd/6g/ggen.c b/src/cmd/6g/ggen.c index 629a8cd3d..278b2ef69 100644 --- a/src/cmd/6g/ggen.c +++ b/src/cmd/6g/ggen.c @@ -565,7 +565,7 @@ cgen_div(int op, Node *nl, Node *nr, Node *res) { Node ax, dx, oldax, olddx; Node n1, n2, n3, savl, savr; - int n, w, s; + int n, w, s, a; Magic m; if(nl->ullman >= UINF) { @@ -616,8 +616,8 @@ cgen_div(int op, Node *nl, Node *nr, Node *res) case 1: // divide by 2 if(op == OMOD) { - if(issigned[nl->type->etype]) - goto longdiv; + if(issigned[nl->type->etype]) + goto longmod; regalloc(&n1, nl->type, res); cgen(nl, &n1); nodconst(&n2, nl->type, 1); @@ -641,8 +641,8 @@ cgen_div(int op, Node *nl, Node *nr, Node *res) break; default: if(op == OMOD) { - if(issigned[nl->type->etype]) - goto longdiv; + if(issigned[nl->type->etype]) + goto longmod; regalloc(&n1, nl->type, res); cgen(nl, &n1); nodconst(&n2, nl->type, mpgetfix(nr->val.u.xval)-1); @@ -688,6 +688,7 @@ divbymul: default: goto longdiv; + case TUINT8: case TUINT16: case TUINT32: case TUINT64: @@ -709,6 +710,13 @@ divbymul: gmove(&n2, &ax); // const->ax gins(optoas(OHMUL, nl->type), &n1, N); // imul reg + if(w == 8) { + // fix up 8-bit multiply + Node ah, dl; + nodreg(&ah, types[TUINT8], D_AH); + nodreg(&dl, types[TUINT8], D_DL); + gins(AMOVB, &ah, &dl); + } if(m.ua) { // need to add numerator accounting for overflow @@ -730,6 +738,7 @@ divbymul: restx(&dx, &olddx); return; + case TINT8: case TINT16: case TINT32: case TINT64: @@ -751,6 +760,13 @@ divbymul: gmove(&n2, &ax); // const->ax gins(optoas(OHMUL, nl->type), &n1, N); // imul reg + if(w == 8) { + // fix up 8-bit multiply + Node ah, dl; + nodreg(&ah, types[TUINT8], D_AH); + nodreg(&dl, types[TUINT8], D_DL); + gins(AMOVB, &ah, &dl); + } if(m.sm < 0) { // need to add numerator @@ -795,13 +811,19 @@ longmod: cgen(nl, &n1); regalloc(&n2, nl->type, N); cgen_div(ODIV, &n1, nr, &n2); + a = optoas(OMUL, nl->type); + if(w == 8) { + // use 2-operand 16-bit multiply + // because there is no 2-operand 8-bit multiply + a = AIMULW; + } if(!smallintconst(nr)) { regalloc(&n3, nl->type, N); cgen(nr, &n3); - gins(optoas(OMUL, nl->type), &n3, &n2); + gins(a, &n3, &n2); regfree(&n3); } else - gins(optoas(OMUL, nl->type), nr, &n2); + gins(a, nr, &n2); gins(optoas(OSUB, nl->type), &n2, &n1); gmove(&n1, res); regfree(&n1); @@ -908,7 +930,7 @@ ret: /* * generate byte multiply: * res = nl * nr - * no byte multiply instruction so have to do + * no 2-operand byte multiply instruction so have to do * 16-bit multiply and take bottom half. */ void diff --git a/test/ken/divconst.go b/test/ken/divconst.go index d0cbbbedc..34d7d430b 100644 --- a/test/ken/divconst.go +++ b/test/ken/divconst.go @@ -351,6 +351,114 @@ u16run() } } +func +i8rand() int8 +{ + for { + a := int8(rand.Uint32()); + a >>= uint(rand.Intn(8)); + if -a != a { + return a; + } + } + return 0; // impossible +} + +func +i8test(a,b,c int8) +{ + d := a/c; + if d != b { + panicln("i8", a, b, c, d); + } +} + +func +i8run() +{ + var a, b int8; + + for i:=0; i<Count; i++ { + a = i8rand(); + + b = a/1; i8test(a,b,1); + b = a/2; i8test(a,b,2); + b = a/3; i8test(a,b,3); + b = a/4; i8test(a,b,4); + b = a/5; i8test(a,b,5); + b = a/6; i8test(a,b,6); + b = a/7; i8test(a,b,7); + b = a/8; i8test(a,b,8); + b = a/10; i8test(a,b,10); + b = a/8; i8test(a,b,8); + b = a/20; i8test(a,b,20); + b = a/32; i8test(a,b,32); + b = a/60; i8test(a,b,60); + b = a/64; i8test(a,b,64); + b = a/127; i8test(a,b,127); + + b = a/-1; i8test(a,b,-1); + b = a/-2; i8test(a,b,-2); + b = a/-3; i8test(a,b,-3); + b = a/-4; i8test(a,b,-4); + b = a/-5; i8test(a,b,-5); + b = a/-6; i8test(a,b,-6); + b = a/-7; i8test(a,b,-7); + b = a/-8; i8test(a,b,-8); + b = a/-10; i8test(a,b,-10); + b = a/-8; i8test(a,b,-8); + b = a/-20; i8test(a,b,-20); + b = a/-32; i8test(a,b,-32); + b = a/-60; i8test(a,b,-60); + b = a/-64; i8test(a,b,-64); + b = a/-128; i8test(a,b,-128); + } +} + +func +u8rand() uint8 +{ + a := uint8(rand.Uint32()); + a >>= uint(rand.Intn(8)); + return a; +} + +func +u8test(a,b,c uint8) +{ + d := a/c; + if d != b { + panicln("u8", a, b, c, d); + } +} + +func +u8run() +{ + var a, b uint8; + + for i:=0; i<Count; i++ { + a = u8rand(); + + b = a/1; u8test(a,b,1); + b = a/2; u8test(a,b,2); + b = a/3; u8test(a,b,3); + b = a/4; u8test(a,b,4); + b = a/5; u8test(a,b,5); + b = a/6; u8test(a,b,6); + b = a/7; u8test(a,b,7); + b = a/8; u8test(a,b,8); + b = a/10; u8test(a,b,10); + b = a/8; u8test(a,b,8); + b = a/20; u8test(a,b,20); + b = a/32; u8test(a,b,32); + b = a/60; u8test(a,b,60); + b = a/64; u8test(a,b,64); + b = a/128; u8test(a,b,128); + b = a/184; u8test(a,b,184); + } +} + func xtest() func @@ -363,6 +471,8 @@ main() u32run(); i16run(); u16run(); + i8run(); + u8run(); } func diff --git a/test/ken/modconst.go b/test/ken/modconst.go index 812a13ca8..7a9ebed0e 100644 --- a/test/ken/modconst.go +++ b/test/ken/modconst.go @@ -351,6 +351,114 @@ u16run() } } +func +i8rand() int8 +{ + for { + a := int8(rand.Uint32()); + a >>= uint(rand.Intn(8)); + if -a != a { + return a; + } + } + return 0; // impossible +} + +func +i8test(a,b,c int8) +{ + d := a%c; + if d != b { + panicln("i8", a, b, c, d); + } +} + +func +i8run() +{ + var a, b int8; + + for i:=0; i<Count; i++ { + a = i8rand(); + + b = a%1; i8test(a,b,1); + b = a%2; i8test(a,b,2); + b = a%3; i8test(a,b,3); + b = a%4; i8test(a,b,4); + b = a%5; i8test(a,b,5); + b = a%6; i8test(a,b,6); + b = a%7; i8test(a,b,7); + b = a%8; i8test(a,b,8); + b = a%10; i8test(a,b,10); + b = a%8; i8test(a,b,8); + b = a%20; i8test(a,b,20); + b = a%32; i8test(a,b,32); + b = a%60; i8test(a,b,60); + b = a%64; i8test(a,b,64); + b = a%127; i8test(a,b,127); + + b = a%-1; i8test(a,b,-1); + b = a%-2; i8test(a,b,-2); + b = a%-3; i8test(a,b,-3); + b = a%-4; i8test(a,b,-4); + b = a%-5; i8test(a,b,-5); + b = a%-6; i8test(a,b,-6); + b = a%-7; i8test(a,b,-7); + b = a%-8; i8test(a,b,-8); + b = a%-10; i8test(a,b,-10); + b = a%-8; i8test(a,b,-8); + b = a%-20; i8test(a,b,-20); + b = a%-32; i8test(a,b,-32); + b = a%-60; i8test(a,b,-60); + b = a%-64; i8test(a,b,-64); + b = a%-128; i8test(a,b,-128); + b = a%-101; i8test(a,b,-101); + } +} + +func +u8rand() uint8 +{ + a := uint8(rand.Uint32()); + a >>= uint(rand.Intn(8)); + return a; +} + +func +u8test(a,b,c uint8) +{ + d := a%c; + if d != b { + panicln("u8", a, b, c, d); + } +} + +func +u8run() +{ + var a, b uint8; + + for i:=0; i<Count; i++ { + a = u8rand(); + + b = a%1; u8test(a,b,1); + b = a%2; u8test(a,b,2); + b = a%3; u8test(a,b,3); + b = a%4; u8test(a,b,4); + b = a%5; u8test(a,b,5); + b = a%6; u8test(a,b,6); + b = a%7; u8test(a,b,7); + b = a%8; u8test(a,b,8); + b = a%10; u8test(a,b,10); + b = a%8; u8test(a,b,8); + b = a%20; u8test(a,b,20); + b = a%32; u8test(a,b,32); + b = a%60; u8test(a,b,60); + b = a%64; u8test(a,b,64); + b = a%127; u8test(a,b,127); + } +} + func xtest() func @@ -363,6 +471,8 @@ main() u32run(); i16run(); u16run(); + i8run(); + u8run(); } func |