ff53654aa2517eb4481ac62480cadcd8971d529e
[vvhitespace] / stdlib / logic.pvvs
#ifndef VVS_STDLIB_LOGIC
#define VVS_STDLIB_LOGIC
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ These subroutines assume they are running on the official VVS interpreter
@ which internally uses a twos-complement representation.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Name:
@ not (101000)
@ Description:
@ Performs a bitwise NOT on the TOS word.
@ Call Stack:
@ X
@ Return Stack:
@ NOT(X)
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
NSSVTSTSSSN | Mark: 101000 (not)
@ In twos-complement, NOT(X) = (-X)-1
SSTTN | PUSH -1
TSSN | MULTIPLY
SSTTN | PUSH -1
TSST | SUBTRACT
NTN | RTS
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Name:
@ and (101001)
@ Description:
@ Performs a bitwise AND on the TOS word.
@ Call Stack:
@ X
@ Y
@ Return Stack:
@ X ^ Y
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
NSSVTSTSSTN | Mark: 101001 (and)
@ Prepare the stack for computation.
SSSSN | PUSH 0 (result)
SSSTTTTTTN | PUSH 63 (shift counter)
@ Loop through the bits one at a time.
NSSVSSTSTSSTSSSSSSSSN | Mark: 00101001 00000000
@ Prepare X for the AND
SNS | DUP
SSSTSTN | PUSH 5
NSTTTSSN | JSR > 1100 (deepdup)
SNT | SWAP
NSTTSTTSSN | JSR > 101100 (rshift)
@ Prepare Y for the AND
SSSTSSN | PUSH 4
NSTTTSSN | JSR > 1100 (deepdup)
SSSTTN | PUSH 3
NSTTTSSN | JSR > 1100 (deepdup)
NSTTSTTSSN | JSR > 101100 (rshift)
@ Do the AND and store in result.
NSTTSSSSSSN | JSR > 1000000 (lowbitand)
SSSTTN | PUSH 3
NSTTSTTN | JSR > 1011 (stackrotatereverse)
SSSTN | PUSH 1
NSTTSTTSTN | JSR > 101101 (lshift)
TSSS | ADD
SSSTSN | PUSH 2
NSTTSTSN | JSR > 1010 (stackrotate)
@ Test for end of loop.
SNS | DUP
NTSSSTSTSSTSSSSSSSTN | BRZ > 00101001 00000001
@ Decrement the counter and loop again.
SSSTN | PUSH 1
TSST | SUBTRACT
NSNSSTSTSSTSSSSSSSSN | JMP > 00101001 00000000
@ Clean up and return.
NSSVSSTSTSSTSSSSSSSTN | Mark: 00101001 00000001
SNN | DROP
SNT | SWAP
SNN | DROP
SNT | SWAP
SNN | DROP
NTN | RTS
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Name:
@ rshift (101100)
@ Description:
@ Shifts 'X' right by 'shiftcount' bits with sign extension.
@ Call Stack:
@ X
@ shiftcount
@ Return Stack:
@ X >> shiftcount
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
NSSVTSTTSSN | Mark: 101100 (rshift)
@ Test for loop completion first since it is allowable to shift by zero.
NSSVSSTSTTSSSSSSSSSTN | Mark: 00101100 00000001
SNS | DUP
NTSSSTSTTSSSSSSSSSSN | BRZ > 00101100 00000000
@ Shift by one bit on each pass.
SNT | SWAP
SSSTSN | PUSH 2
TSTS | DIVIDE
@ Decrement the counter.
SNT | SWAP
SSSTN | PUSH 1
TSST | SUBTRACT
@ Loop again.
NSNSSTSTTSSSSSSSSSTN | JMP > 00101100 00000001
@ Clean up and return.
NSSVSSTSTTSSSSSSSSSSN | Mark: 00101100 00000000
SNN | DROP
NTN | RTS
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Name:
@ lshift (101101)
@ Description:
@ Shifts 'X' left by 'shiftcount' bits with zero filling.
@ Call Stack:
@ X
@ shiftcount
@ Return Stack:
@ X << shiftcount
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
NSSVTSTTSTN | Mark: 101101 (lshift)
@ Test for loop completion first since it is allowable to shift by zero.
NSSVSSTSTTSTSSSSSSSTN | Mark: 00101101 00000001
SNS | DUP
NTSSSTSTTSTSSSSSSSSN | BRZ > 00101101 00000000
@ Shift by one bit on each pass.
SNT | SWAP
SSSTSN | PUSH 2
TSSN | MULTIPLY
@ Decrement the counter.
SNT | SWAP
SSSTN | PUSH 1
TSST | SUBTRACT
@ Loop again.
NSNSSTSTTSTSSSSSSSTN | JMP > 00101101 00000001
@ Clean up and return.
NSSVSSTSTTSTSSSSSSSSN | Mark: 00101101 00000000
SNN | DROP
NTN | RTS
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Name:
@ lowbitand (1000000)
@ Description:
@ Performs logical AND on the least-significant bit of 'X' and 'Y'.
@ Returns either 1 or 0, no other values.
@ Call Stack:
@ X
@ Y
@ Return Stack:
@ lsb(X) AND lsb(Y)
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
NSSVTSSSSSSN | Mark: 1000000 (lowbitand)
SSSTSN | PUSH 2
TSTT | MODULO
SNT | SWAP
SSSTSN | PUSH 2
TSTT | MODULO
TSSS | ADD
SSSTSN | PUSH 2
TSTS | DIVIDE
NTN | RTS
#endif