summaryrefslogtreecommitdiff
path: root/Source/DSPSpy/tests/cmpaxh_test.ds
blob: 0cfbed4010e888cf1854a7b6d21fd28257450775 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
incdir "tests"
include "dsp_base.inc"

input_ax:
; [0] - 0x0000'0000 - 0
CW 0
CW 0
; [1] - 0x0000'0001 - 1 in $ax0.l
CW 0
CW 1
; [2] - 0x0000'ffff - -1 in $ax0.l
CW 0
CW 0xffff
; [3] - 0x0001'0000 - 1 in $ax0.h
CW 1
CW 0
; [4] - 0x7fff'0000 - INT_MAX in $ax0.h
CW 0x7fff
CW 0
; [5] - 0x8000'0000 - INT_MIN in $ax0.h
CW 0x8000
CW 0
; [6] - 0xffff'0000 - -1 in $ax0.h
CW 0xffff
CW 0
input_ax_end:

input_acc:
; [0] - 0x00'0000'0000 - 0
CW 0
CW 0
CW 0
; [1] - 0x00'0000'0001 - 1 in $ac0.l
CW 0
CW 0
CW 1
; [2] - 0x00'0000'ffff - -1 in $ac0.l
CW 0
CW 0
CW 1
; [3] - 0x00'0001'0000 - 1 in $ac0.m
CW 0
CW 1
CW 0
; [4] - 0x00'7fff'0000 - INT_MAX in $ac0.m
CW 0
CW 0x7fff
CW 0
; [5] - 0x00'8000'0000 - INT_MIN in $ac0.m, but not sign extended
CW 0
CW 0x8000
CW 0
; [6] - 0x00'ffff'0000 - -1 in $ac0.m, but not sign extended
CW 0
CW 0xffff
CW 0
; [7] - 0x01'0000'0000 - 1 in $ac0.l
CW 1
CW 0
CW 0
; [8] - 0x7f'ffff'0000 - true INT_MAX
CW 0x7f
CW 0xffff
CW 0
; [9] - 0x80'0000'0000 - true INT_MIN
CW 0x80
CW 0
CW 0
; [10] - 0xff'8000'0000 - INT_MIN in $ac0.m, sign-extended
CW 0xff
CW 0x8000
CW 0
; [11] - 0xff'ffff'0000 - -1
CW 0xff
CW 0xffff
CW 0
input_acc_end:

/* Python script to generate the following result tables from a DSP dump:
import struct
def gen_tables(name, num_ax, num_acc):
	with open(name, "rb") as fin:
		data = fin.read()
	reg_values = list(struct.iter_unpack(">" + "H"*0x20, data))
	# Initial register values (there is no corresponding send_back call for these), then our two
	# default value checks, then the TSTAXH test, then the CMPAXH test, then the test results
	assert len(reg_values) == 1 + 2 + num_ax + num_ax * num_acc + 1
	print("result_table_tstaxh:")
	for ax in range(num_ax):
		# SR is register 0x13
		print("CW {:#04x}".format(reg_values[3 + ax][0x13]))
	print("result_table_tstaxh_end:")
	print()
	print("result_table_cmpaxh:")
	for ax in range(num_ax):
		print("; ax [{}]".format(ax))
		for acc in range(num_acc):
			print("CW {:#04x}".format(reg_values[3 + num_ax + ax * num_acc + acc][0x13]))
	print("result_table_cmpaxh_end:")

gen_tables("dsp_dump0.bin", 7, 12)
*/

result_table_tstaxh:
CW 0x22a4
CW 0x22a4
CW 0x22a4
CW 0x22a0
CW 0x2280
CW 0x2288
CW 0x22a8
result_table_tstaxh_end:

result_table_cmpaxh:
; ax [0]
CW 0x22a5
CW 0x22a1
CW 0x22a1
CW 0x22a1
CW 0x2281
CW 0x2291
CW 0x22b1
CW 0x22b1
CW 0x22b1
CW 0x22b9
CW 0x2289
CW 0x22a9
; ax [1]
CW 0x22a5
CW 0x22a1
CW 0x22a1
CW 0x22a1
CW 0x2281
CW 0x2291
CW 0x22b1
CW 0x22b1
CW 0x22b1
CW 0x22b9
CW 0x2289
CW 0x22a9
; ax [2]
CW 0x22a5
CW 0x22a1
CW 0x22a1
CW 0x22a1
CW 0x2281
CW 0x2291
CW 0x22b1
CW 0x22b1
CW 0x22b1
CW 0x22b9
CW 0x2289
CW 0x22a9
; ax [3]
CW 0x22a8
CW 0x22a8
CW 0x22a8
CW 0x22a5
CW 0x2281
CW 0x2281
CW 0x22b1
CW 0x22b1
CW 0x22b1
CW 0x22b3
CW 0x2299
CW 0x22a9
; ax [4]
CW 0x2288
CW 0x2288
CW 0x2288
CW 0x2288
CW 0x22a5
CW 0x22a1
CW 0x2291
CW 0x2291
CW 0x2291
CW 0x2293
CW 0x22b9
CW 0x2289
; ax [5]
CW 0x2290
CW 0x2290
CW 0x2290
CW 0x2290
CW 0x22b0
CW 0x22b0
CW 0x2290
CW 0x2290
CW 0x229a
CW 0x2298
CW 0x22a5
CW 0x2281
; ax [6]
CW 0x22a0
CW 0x22a0
CW 0x22a0
CW 0x22a0
CW 0x2290
CW 0x2290
CW 0x22b0
CW 0x22b0
CW 0x22ba
CW 0x22b8
CW 0x2288
CW 0x22a5
result_table_cmpaxh_end:

test_main:
	; Perform one test using the default values
	; ($acc0 is 14 0009 0007 and $ax0 is 8000 0003, but this can be changed in the DSPSpy UI)
	; Also, as a sanity check, record the computed sizes of the result tables
	LRI $ar0, #input_ax
	LRI $ix0, #(input_ax_end - input_ax)
	LRI $ar1, #input_acc
	LRI $ix1, #(input_acc_end - input_acc)
	LRI $ar2, #result_table_tstaxh
	LRI $ix2, #(input_ax_end - input_ax)/2
	LRI $ar3, #result_table_cmpaxh
	LRI $ix3, #((input_ax_end - input_ax)/2)*((input_acc_end - input_acc)/3)
	; Set the sticky overflow bit just so that we get consistent $sr values
	; before and after an overflow occurs
	SBSET #1
	CMPAXH $acc0, $ax0.h
	CALL send_back ; Expected $sr: 2290
	; $ar0 should match $ix0, etc
	ADDARN $ar0, $ix0
	LRI $ix0, #input_ax_end
	ADDARN $ar1, $ix1
	LRI $ix1, #input_acc_end
	ADDARN $ar2, $ix2
	LRI $ix2, #result_table_tstaxh_end
	ADDARN $ar3, $ix3
	LRI $ix3, #result_table_cmpaxh_end
	TSTAXH $ax0.h
	CALL send_back ; Expected $sr: 2288

	CLR $acc0
	CLR $acc1
	LRI $ax0.h, #0
	LRI $ax0.l, #0
	LRI $ax1.h, #0
	LRI $ax1.l, #0

	; Check TSTAXH...
	LRI $ar0, #input_ax
	LRI $ar2, #result_table_tstaxh

	; for (int ctr = input_ax.size(); ctr > 0; ctr--) {
	BLOOPI #(input_ax_end - input_ax)/2, check_tstaxh_last_ins
		; Note: if DSPSpy supported populating DMEM as well as IMEM, then there are several
		; instructions that could make this faster and cleaner... but it doesn't currently,
		; so we're stuck with ILRRI.

		; Load the test value into $ax0.h/$ax0.l via $ac0.m
		ILRRI $ac0.m, $ar0 ; $ac0.m = IMEM[$ar0++]
		MRR $ax0.h, $ac0.m
		ILRRI $ac0.m, $ar0
		MRR $ax0.l, $ac0.m
		; Load the expected value into $ac1.m
		ILRRI $ac1.m, $ar2 ; $ac1.m = IMEM[$ar2++]
		; Reduce noise in the results
		LRI $ac0.m, #0

		; Do the test
		TSTAXH $ax0.h
		CALL send_back

		; Check if $sr matches the value we expected.  If there is any difference,
		; note it via a nonzero $ax1.l.  (send_back saves the value of $sr)
		MRR $ac0.m, $sr
		CMP
		IFNZ
		LRIS $ax1.l, #1
check_tstaxh_last_ins:
	NOP
	; }

	; Check CMPAXH...
	CLR $acc0
	CLR $acc1
	LRI $ar0, #input_ax
	LRI $ar3, #result_table_cmpaxh

	; for (int ctr_ax = input_ax.size(); ctr_ax > 0; ctr_ax--) {
	BLOOPI #(input_ax_end - input_ax)/2, check_cmpaxh_last_ins_outer
		; Load the test value into $ax0.h/$ax0.l via $ac1.m
		ILRRI $ac1.m, $ar0
		MRR $ax0.h, $ac1.m
		ILRRI $ac1.m, $ar0
		MRR $ax0.l, $ac1.m

		LRI $ar1, #input_acc

		; for (int ctr_acc = input_acc.size(); ctr_acc > 0; ctr_acc--) {
		BLOOPI #(input_acc_end - input_acc)/3, check_cmpaxh_last_ins_inner

			; Load the test value into $ac0.h/$ac0.m/$ac0.l via $ac1.m
			ILRRI $ac1.m, $ar1
			MRR $ac0.h, $ac1.m
			ILRRI $ac0.m, $ar1 ; we can load it directly here
			ILRRI $ac1.m, $ar1
			MRR $ac0.l, $ac1.m

			; Load the expected value into $ac1.m
			ILRRI $ac1.m, $ar3

			; Do the test
			CMPAXH $acc0, $ax0.h
			CALL send_back

			; Check if $sr matches the value we expected.  If there is any difference,
			; note it via a nonzero $ax1.h.  (send_back saves the value of $sr)
			; We can overwrite $ac0.m here because we load it on the next iteration.
			MRR $ac0.m, $sr
			LRIS $ac0.l, #0
			LRI $ac0.h, #0
			CMP
			IFNZ
			LRIS $ax1.h, #1
check_cmpaxh_last_ins_inner:
		NOP
		; }
check_cmpaxh_last_ins_outer:
	NOP
	; }

	; We're done testing.  In the final send_back call, if $ax1.l or $ax1.h
	; is nonzero, the test failed.
	CALL send_back

	; We're done, DO NOT DELETE THIS LINE
	JMP end_of_test