8-bit div and mod

R=ken
OCL=32975
CL=32975
This commit is contained in:
Russ Cox 2009-08-10 12:46:23 -07:00
parent f70e285178
commit 3f91f80a21
3 changed files with 250 additions and 8 deletions

View file

@ -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

View file

@ -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

View file

@ -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