mirror of
https://github.com/golang/go
synced 2024-11-02 11:50:30 +00:00
8-bit div and mod
R=ken OCL=32975 CL=32975
This commit is contained in:
parent
f70e285178
commit
3f91f80a21
3 changed files with 250 additions and 8 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue