Fixed bugs in `rshift` subroutine.
[vvhitespace] / stdlib / logic.pvvs
CommitLineData
0c56152e
AT
1#ifndef VVS_STDLIB_LOGIC
2#define VVS_STDLIB_LOGIC
3
4@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
5@ These subroutines assume they are running on the official VVS interpreter
6@ which internally uses a twos-complement representation.
7@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
8
9@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
10@ Name:
11@ not (101000)
12@ Description:
13@ Performs a bitwise NOT on the TOS word.
14@ Call Stack:
15@ X
16@ Return Stack:
17@ NOT(X)
18@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
19NSSVTSTSSSN | Mark: 101000 (not)
20@ In twos-complement, NOT(X) = (-X)-1
21SSTTN | PUSH -1
22TSSN | MULTIPLY
76974914 23SSSTN | PUSH 1
0c56152e
AT
24TSST | SUBTRACT
25NTN | RTS
26
3eaa958a
AT
27@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
28@ Name:
29@ and (101001)
30@ Description:
31@ Performs a bitwise AND on the TOS word.
32@ Call Stack:
33@ X
34@ Y
35@ Return Stack:
36@ X ^ Y
37@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
149f16fd 38#include <stack.pvvs>
3eaa958a
AT
39NSSVTSTSSTN | Mark: 101001 (and)
40
41@ Prepare the stack for computation.
42SSSSN | PUSH 0 (result)
43SSSTTTTTTN | PUSH 63 (shift counter)
44
45@ Loop through the bits one at a time.
46NSSVSSTSTSSTSSSSSSSSN | Mark: 00101001 00000000
76974914 47@ Prepare copy of X for the AND
3eaa958a
AT
48SNS | DUP
49SSSTSTN | PUSH 5
50NSTTTSSN | JSR > 1100 (deepdup)
51SNT | SWAP
52NSTTSTTSSN | JSR > 101100 (rshift)
76974914 53@ Prepare copy of Y for the AND
3eaa958a
AT
54SSSTSSN | PUSH 4
55NSTTTSSN | JSR > 1100 (deepdup)
56SSSTTN | PUSH 3
57NSTTTSSN | JSR > 1100 (deepdup)
58NSTTSTTSSN | JSR > 101100 (rshift)
59@ Do the AND and store in result.
60NSTTSSSSSSN | JSR > 1000000 (lowbitand)
61SSSTTN | PUSH 3
62NSTTSTTN | JSR > 1011 (stackrotatereverse)
63SSSTN | PUSH 1
64NSTTSTTSTN | JSR > 101101 (lshift)
65TSSS | ADD
66SSSTSN | PUSH 2
67NSTTSTSN | JSR > 1010 (stackrotate)
68@ Test for end of loop.
69SNS | DUP
70NTSSSTSTSSTSSSSSSSTN | BRZ > 00101001 00000001
71@ Decrement the counter and loop again.
72SSSTN | PUSH 1
73TSST | SUBTRACT
74NSNSSTSTSSTSSSSSSSSN | JMP > 00101001 00000000
75
76@ Clean up and return.
77NSSVSSTSTSSTSSSSSSSTN | Mark: 00101001 00000001
78SNN | DROP
79SNT | SWAP
80SNN | DROP
81SNT | SWAP
82SNN | DROP
83NTN | RTS
84
76974914
AT
85@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
86@ Name:
87@ or (101010)
88@ Description:
89@ Performs a bitwise OR on the TOS word.
90@ Call Stack:
91@ X
92@ Y
93@ Return Stack:
94@ X v Y
95@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
96NSSVTSTSTSN | Mark: 101010 (or)
97NSTTSTSSSN | JSR > 101000 (not)
98SNT | SWAP
99NSTTSTSSSN | JSR > 101000 (not)
100NSTTSTSSTN | JSR > 101001 (and)
101NSTTSTSSSN | JSR > 101000 (not)
102NTN | RTS
103
104@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
105@ Name:
106@ xor (101011)
107@ Description:
108@ Performs a bitwise XOR on the TOS word.
109@ Call Stack:
110@ X
111@ Y
112@ Return Stack:
113@ X xor Y
114@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
149f16fd 115#include <stack.pvvs>
76974914
AT
116NSSVTSTSTTN | Mark: 101011 (xor)
117SNS | DUP
118SSSTTN | PUSH 3
119NSTTTSSN | JSR > 1100 (deepdup)
120NSTTSTSTSN | JSR > 101010 (or)
121SNT | SWAP
122SSSTTN | PUSH 3
123NSTTSTTN | JSR > 1011 (stackrotatereverse)
124NSTTSTSSTN | JSR > 101001 (and)
125NSTTSTSSSN | JSR > 101000 (not)
126NSTTSTSSTN | JSR > 101001 (and)
127NTN | RTS
128
0c56152e
AT
129@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
130@ Name:
131@ rshift (101100)
132@ Description:
133@ Shifts 'X' right by 'shiftcount' bits with sign extension.
134@ Call Stack:
135@ X
136@ shiftcount
137@ Return Stack:
138@ X >> shiftcount
139@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
140NSSVTSTTSSN | Mark: 101100 (rshift)
3eaa958a 141@ Test for loop completion first since it is allowable to shift by zero.
0c56152e
AT
142SNS | DUP
143NTSSSTSTTSSSSSSSSSSN | BRZ > 00101100 00000000
0750ec76
AT
144
145@ Negative numbers need special handling.
0c56152e 146SNT | SWAP
0750ec76
AT
147SNS | DUP
148NTTSSTSTTSSSSSSSTSTN | BMI > 00101100 00000101
149
150@ Shift by one bit on each pass.
151NSSVSSTSTTSSSSSSSTSSN | Mark: 00101100 00000100
0c56152e
AT
152SSSTSN | PUSH 2
153TSTS | DIVIDE
154@ Decrement the counter.
155SNT | SWAP
156SSSTN | PUSH 1
157TSST | SUBTRACT
158@ Loop again.
0750ec76 159NSNTSTTSSN | JMP > 101100 (rshift)
0c56152e 160
0750ec76 161@ Clean up
0c56152e
AT
162NSSVSSTSTTSSSSSSSSSSN | Mark: 00101100 00000000
163SNN | DROP
164NTN | RTS
165
0750ec76
AT
166@ Found a negative number. Subtract one before proceeding if odd.
167NSSVSSTSTTSSSSSSSTSTN | Mark: 00101100 00000101
168SNS | DUP
169SSSTSN | PUSH 2
170TSTT | MODULO
171NTSSSTSTTSSSSSSSTSSN | BRZ > 00101100 00000100
172SSSTN | PUSH 1
173TSST | SUBTRACT
174NSNSSTSTTSSSSSSSTSSN | JMP > 00101100 00000100
175
0c56152e
AT
176@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
177@ Name:
178@ lshift (101101)
179@ Description:
180@ Shifts 'X' left by 'shiftcount' bits with zero filling.
181@ Call Stack:
182@ X
183@ shiftcount
184@ Return Stack:
185@ X << shiftcount
186@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
187NSSVTSTTSTN | Mark: 101101 (lshift)
188
3eaa958a 189@ Test for loop completion first since it is allowable to shift by zero.
0c56152e
AT
190NSSVSSTSTTSTSSSSSSSTN | Mark: 00101101 00000001
191SNS | DUP
192NTSSSTSTTSTSSSSSSSSN | BRZ > 00101101 00000000
193@ Shift by one bit on each pass.
194SNT | SWAP
195SSSTSN | PUSH 2
196TSSN | MULTIPLY
197@ Decrement the counter.
198SNT | SWAP
199SSSTN | PUSH 1
200TSST | SUBTRACT
201@ Loop again.
202NSNSSTSTTSTSSSSSSSTN | JMP > 00101101 00000001
203
204@ Clean up and return.
205NSSVSSTSTTSTSSSSSSSSN | Mark: 00101101 00000000
206SNN | DROP
207NTN | RTS
208
e0d5136c
AT
209@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
210@ Name:
211@ lowbitand (1000000)
212@ Description:
213@ Performs logical AND on the least-significant bit of 'X' and 'Y'.
214@ Returns either 1 or 0, no other values.
215@ Call Stack:
216@ X
217@ Y
218@ Return Stack:
219@ lsb(X) AND lsb(Y)
220@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
221NSSVTSSSSSSN | Mark: 1000000 (lowbitand)
222SSSTSN | PUSH 2
223TSTT | MODULO
224SNT | SWAP
225SSSTSN | PUSH 2
226TSTT | MODULO
227TSSS | ADD
228SSSTSN | PUSH 2
229TSTS | DIVIDE
230NTN | RTS
231
0c56152e 232#endif