summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cmd/6g/ggen.c38
-rw-r--r--test/ken/divconst.go110
-rw-r--r--test/ken/modconst.go110
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