Last active
October 20, 2022 03:50
-
-
Save non/00e0a45297a7f67a0fbfe149aba29abf to your computer and use it in GitHub Desktop.
tested implementation of signed division for 16-bit numbers in uxntal
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
( main method for testing ) | |
|0100 | |
#1234 #0001 ;testcases JSR2 | |
#0000 #0431 ;testcases JSR2 | |
#0039 #0003 ;testcases JSR2 | |
#9321 #ffff ;testcases JSR2 | |
#ffff #9321 ;testcases JSR2 | |
#ffff #ffff ;testcases JSR2 | |
#7654 #8000 ;testcases JSR2 | |
#8000 #0001 ;testcases JSR2 | |
#8000 #0012 ;testcases JSR2 | |
#8000 #8000 ;testcase JSR2 #0a #18 DEO | |
BRK | |
( run tests for all of: x/y, -x/y, x/-y, -x/-y ) | |
@testcases ( x* y* -> ) | |
OVR2 OVR2 ;testcase JSR2 | |
OVR2 #ffff MUL2 OVR2 ;testcase JSR2 | |
OVR2 OVR2 #ffff MUL2 ;testcase JSR2 | |
#ffff MUL2 SWP2 #ffff MUL2 SWP2 ;testcase JSR2 | |
#0a #18 DEO JMP2r | |
( test x/y ) | |
( print out the result and the absolute value of the result ) | |
@testcase ( x* y* -> ) | |
OVR2 ;print/short JSR2 | |
#20 #18 DEO LIT "/ #18 DEO #20 #18 DEO | |
DUP2 ;print/short JSR2 | |
#20 #18 DEO LIT "= #18 DEO #20 #18 DEO | |
;s16-div JSR2 | |
DUP2 ;print/short JSR2 | |
#20 #18 DEO LIT "( #18 DEO | |
;abs JSR2 ;print/short JSR2 | |
LIT ") #18 DEO #0a #18 DEO JMP2r | |
( absolute value function ) | |
@abs ( x* -> |x|* ) | |
DUP2 ;xsign JSR2 MUL2 JMP2r | |
( modified sign function ) | |
( ) | |
( returns: ) | |
( #0001 for non-negative ) | |
( #1111 for negative ) | |
( ) | |
( this is not quite "signum" since we return #0001 for zero. ) | |
( but for our purposes this is fine. ) | |
@xsign ( x* -> sign* ) | |
#0f SFT2 ( neg-x? ) | |
#ffff MUL2 ( ffff or 0000 ) | |
#0001 ORA2 ( ffff or 0001 ) | |
JMP2r | |
( signed division ) | |
( ) | |
( the MIN value (-32768) needs special consideration. ) | |
( since +32768 is not representable, -1 * MIN = MIN. ) | |
( ) | |
( rules (in precedence order): ) | |
( ) | |
( 1. x/0 = error ) | |
( 2a. x/1 = x ) | |
( 2b. MIN/MIN = 1 ) | |
( 2c. x/MIN = 0 ) | |
( 2d. MIN/-1 = MIN, because -1*MIN -> MIN ) | |
( 3. x/y = |x|/|y| * xsign(x) * xsign(y) ) | |
( ) | |
( we must ensure these rules are handled in our code. ) | |
( ) | |
( as long as we run DIV2 we can be sure (1) is handled. ) | |
( ) | |
( similarly, we can be sure that (2a) is handled by ) | |
( |x|/1 * xsign(x) * xsign(1), since xsign(1) = 1 ) | |
( and this simplifies to |x| * xsign(x) = x. ) | |
( ) | |
( we handle (2b) because abs breaks down in the same way ) | |
( for the numerator and denominator, and DIV2 preserves ) | |
( this property ensuring MIN/MIN=1. ) | |
( ) | |
( since for any x we know |x| < 32768, we can be sure ) | |
( that (2c) holds when using DIV2. ) | |
( ) | |
( finally, (2d) works because -1*MIN = MIN. ) | |
( ) | |
( therefore we don't have to special case MIN despite ) | |
( the strangeness 16-bit signed numbers. ) | |
@s16-div ( x* y* -> x/y* ) | |
DUP2 ;xsign JSR2 ( x y sy ) | |
STH2k MUL2 ( x |y| {sy} ) | |
SWP2 ( |y| x {sy} ) | |
DUP2 ;xsign JSR2 ( |y| x sx {sy} ) | |
STH2k MUL2 MUL2r ( |y| |x| {sx*sy} ) | |
SWP2 DIV2 ( |x|/|y| {sx*sy} ) | |
STH2r MUL2 ( (|x|/|y|)*(sx*sy) ) | |
JMP2r | |
( print unsigned 16-bit numbers ) | |
@print ( short* -> ) | |
&short ( short* -> ) SWP ,&byte JSR | |
&byte ( byte^ -> ) DUP #04 SFT ,&char JSR | |
&char ( char -> ) #0f AND DUP #09 GTH #27 MUL ADD #30 ADD #18 DEO | |
JMP2r |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment