Skip to content

Instantly share code, notes, and snippets.

@tadglines
Created April 28, 2012 17:58
Show Gist options
  • Save tadglines/2520858 to your computer and use it in GitHub Desktop.
Save tadglines/2520858 to your computer and use it in GitHub Desktop.
There's a problem with the current implementation of the DCPI DIV and IDIV instructions.

There appears to be a problem with the way the DCPU rc1 does DIV. The current DCPU RC1 implementation does the following for DIV:

long val = (b << 16) / a;
b = (char)(int)(val >> 16);
this.ex = (char)(int)val;

Given b = 0xFFFF, a = 0x2 the result will be a = 0xFFFF and ex = 0x8000. This is wrong. (0xFFFF << 16) / 0x2 should = 0x7FFF8000. The problem is that given "(b << 16) / a", Java will sign extend it. So, what Java ends up doing is (0xFFFFFFFFFFFF0000 / 0x2) which produces 0xFFFFFFFFFFFF8000 and that's not what is described in the spec. In order for the DCPU to meet the spec it would need to do:

long val = b;
val <<= 16;
val /= a;
b = (char)(int)(val >> 16);
this.ex = (char)(int)val;

Now, in order to divide a 32 bit value by a 16 bit value, a different spec for DIV would be useful. On the x86 DIV does the following AX = DX:AX / divisor DX = DX:AX % divisor If the DCPU DIV instruction did:

int long = (ex << 16) | b;
b = (char)(tmp / a);
ex = (char)(tmp % b);

Then a 32 bit unsigned value could be divided using:

SET A, 0xFFFF ; Low Word
SET B, 0x000F ; High Word
SET EX, 0     ; Zero extend the value into EX
DIV B, 0x3
DIV A, 0x3

This will produce the result: A = 0x5555 B = 0x0005 Giving the correct result of 0x00055555. For signed division DVI should:

int tmp = (ex << 16) | b;
b = (char)(tmp / (short)a);
ex = (char)(tmp % (short)b);

Then a 32 bit value could be divided using:

SET A, 0x0001  ; Low Word
SET B, 0xFFF0  ; High Word
SET EX, 0xFFFF ; Zero extend the value into EX (only if dividend is signed)
DIV B, 0x3
DIV A, 0x3

This should produce the result: A = 0xAAAB B = 0xFFFB Giving the correct result of 0xFFFBAAAB.

Finally, let me say I haven't had this much fun in a long time. Thank's Notch!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment