OpenCores
URL https://opencores.org/ocsvn/zipcpu/zipcpu/trunk

Subversion Repositories zipcpu

[/] [zipcpu/] [trunk/] [bench/] [asm/] [cputest.c] - Blame information for rev 177

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 168 dgisselq
///////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    cputest.c
4
//
5
// Project:     Zip CPU -- a small, lightweight, RISC CPU soft core
6
//
7
// Purpose:     To test the CPU, it's instructions, cache, and pipeline, to make
8
//              certain that it works.  This includes testing that each of the
9
//      instructions works, as well as any strange instruction combinations.
10
//
11
//
12
// Creator:     Dan Gisselquist, Ph.D.
13
//              Gisselquist Technology, LLC
14
//
15
///////////////////////////////////////////////////////////////////////////////
16
//
17
// Copyright (C) 2015-2016, Gisselquist Technology, LLC
18
//
19
// This program is free software (firmware): you can redistribute it and/or
20
// modify it under the terms of  the GNU General Public License as published
21
// by the Free Software Foundation, either version 3 of the License, or (at
22
// your option) any later version.
23
//
24
// This program is distributed in the hope that it will be useful, but WITHOUT
25
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
26
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
27
// for more details.
28
//
29
// License:     GPL, v3, as defined and found on www.gnu.org,
30
//              http://www.gnu.org/licenses/gpl.html
31
//
32
//
33
///////////////////////////////////////////////////////////////////////////////
34
//
35
//
36
#define NULL    (void *)0
37
volatile        int     *const UARTTX = (volatile int *)0x010b,
38
        * const UART_CTRL = (int *)0x0107;
39
// #define      ZIPSYS
40
#ifdef  ZIPSYS
41
#define HAVE_COUNTER
42
volatile        int * const PIC = (volatile int *)0xc0000000;
43
const int       INT_UARTTX = 0x2000;
44
volatile        int     *const COUNTER = (volatile int *)0xc0000008;
45
 
46
#define HAVE_SCOPE
47
 
48
#else
49
volatile        int     * const PIC = (volatile int *)0x0102;
50
const int       INT_UARTTX = 0x080;
51
volatile        int     *const TIMER = (volatile int *)0x0104;
52
#define HAVE_TIMER
53
#endif
54
 
55
#ifdef  HAVE_SCOPE
56
volatile        int     *const SCOPE = (volatile int *)0x011e;
57
#endif
58
 
59
unsigned        zip_ucc(void);
60
void            zip_save_context(int *);
61
void            zip_halt(void);
62
 
63
asm("\t.section\t.start\n"
64
        "\t.global\t_start\n"
65
        "\t.type\t_start,@function\n"
66
"_start:\n"
67
#ifdef  HAVE_SCOPE
68
        "\tNOOP\n"
69
        "\tLOD\t286,R0\n"
70
        "\tROL\t16,R0\n"
71
        "\tTST\t0x1000,R0\n"
72
        "\tBZ\t_start\n"
73
        "\tOR\t0x0f00,R0\n"
74
        "\tROL\t16,R0\n"
75
        "\tSTO\tR0,286\n"
76
#endif
77
        "\tCLR\tR0\n"
78
        "\tCLR\tR1\n"
79
        "\tCLR\tR2\n"
80
        "\tCLR\tR3\n"
81
        "\tCLR\tR4\n"
82
        "\tCLR\tR5\n"
83
        "\tCLR\tR6\n"
84
        "\tCLR\tR7\n"
85
        "\tCLR\tR8\n"
86
        "\tCLR\tR9\n"
87
        "\tCLR\tR10\n"
88
        "\tCLR\tR11\n"
89
        "\tCLR\tR12\n"
90
        "\tLDI\t_top_of_stack,SP\n"
91
        "\tCLR\tCC\n"
92
        "\tMOV\tbusy_failure(PC),R0\n"
93
        "\tBRA\tentry\n"
94
"busy_failure:\n"
95
        "\tBUSY\n"
96
        "\t.section\t.text");
97
 
98
#ifdef  HAVE_COUNTER
99
#define MARKSTART       start_time = *COUNTER
100
#define MARKSTOP        stop_time  = *COUNTER
101
#else
102
#ifdef  HAVE_TIMER
103
#define MARKSTART       start_time = *TIMER
104
#define MARKSTOP        stop_time  = *TIMER
105
#else
106
#define MARKSTART
107
#define MARKSTOP
108
#endif
109
#endif
110
 
111
 
112
extern  int     run_test(void *pc, void *stack);
113
asm("\t.global\trun_test\n"
114
        "\t.type\trun_test,@function\n"
115
"run_test:\n"
116
        "\tCLR\tR3\n"
117
        "\tMOV\ttest_return(PC),uR0\n"
118
        "\tMOV\tR3,uR1\n"
119
        "\tMOV\tR3,uR2\n"
120
        "\tMOV\tR3,uR3\n"
121
        "\tMOV\tR3,uR4\n"
122
        "\tMOV\tR3,uR5\n"
123
        "\tMOV\tR3,uR6\n"
124
        "\tMOV\tR3,uR7\n"
125
        "\tMOV\tR3,uR8\n"
126
        "\tMOV\tR3,uR9\n"
127
        "\tMOV\tR3,uR10\n"
128
        "\tMOV\tR1,uR11\n"
129
        "\tMOV\tR1,uR12\n"
130
        "\tMOV\tR2,uSP\n"
131
        "\tMOV\t0x20+R3,uCC\n"
132
        "\tMOV\tR1,uPC\n"
133
        "\tRTU\n"
134
"test_return:\n"
135
        "\tMOV\tuR1,R1\n"
136
        "\tAND\t0xffffffdf,CC\n"
137
        // Works with 5 NOOPS, works with 3 NOOPS, works with 1 NOOP
138
        "\tJMP\tR0\n");
139
 
140
void    break_one(void);
141
asm("\t.global\tbreak_one\n"
142
        "\t.type\tbreak_one,@function\n"
143
"break_one:\n"
144
        "\tLDI\t0,R1\n"
145
        "\tBREAK\n"
146
        "\tLDI\t1,R1\n" // Test fails
147
        "\tJMP\tR0");
148
 
149
void    break_two(void);
150 172 dgisselq
        // Can we stop a break before we hit it?
151 168 dgisselq
asm("\t.global\tbreak_two\n"
152
        "\t.type\tbreak_two,@function\n"
153
"break_two:\n"
154
        "\tLDI\t0,R1\n"
155
        "\tJMP\tR0\n"
156
        "\tBREAK\n");
157
 
158
void    early_branch_test(void);
159
asm("\t.global\tearly_branch_test\n"
160
        "\t.type\tearly_branch_test,@function\n"
161
"early_branch_test:\n"
162
        "\tLDI\t1,R1\n"
163
        "\tBRA\t_eb_a\n"
164
        "\tBREAK\n"
165
"_eb_a:\n"
166
        "\tLDI\t2,R1\n"
167
        "\tBRA\t_eb_b\n"
168
        "\tNOP\n"
169
        "\tBREAK\n"
170
"_eb_b:\n"
171
        "\tLDI\t3,R1\n"
172
        "\tBRA\t_eb_c\n"
173
        "\tNOP\n"
174
        "\tNOP\n"
175
        "\tBREAK\n"
176
"_eb_c:\n"
177
        "\tLDI\t4,R1\n"
178
        "\tBRA\t_eb_d\n"
179
        "\tNOP\n"
180
        "\tNOP\n"
181
        "\tNOP\n"
182
        "\tBREAK\n"
183
"_eb_d:\n"
184
        "\tLDI\t5,R1\n"
185
        "\tBRA\t_eb_e\n"
186
        "\tNOP\n"
187
        "\tNOP\n"
188
        "\tNOP\n"
189
        "\tNOP\n"
190
        "\tBREAK\n"
191
"_eb_e:\n"
192
        "\tLDI\t6,R1\n"
193
        "\tBRA\t_eb_f\n"
194
        "\tNOP\n"
195
        "\tNOP\n"
196
        "\tNOP\n"
197
        "\tNOP\n"
198
        "\tNOP\n"
199
        "\tBREAK\n"
200
"_eb_f:\n"
201
        "\tLDI\t0,R1\n"
202
        "\tJMP\tR0");
203
 
204
void    trap_test_and(void);
205
asm("\t.global\ttrap_test_and\n"
206
        "\t.type\ttrap_test_and,@function\n"
207
"trap_test_and:\n"
208
        "\tLDI\t0,R1\n"
209
        "\tAND\t0xffffffdf,CC\n"
210
        "\tLDI\t1,R1\n" // Test fails
211
        "\tJMP\tR0");
212
 
213
void    trap_test_clr(void);
214
asm("\t.global\ttrap_test_clr\n"
215
        "\t.type\ttrap_test_clr,@function\n"
216
"trap_test_clr:\n"
217
        "\tLDI\t0,R1\n"
218
        "\tCLR\tCC\n"
219
        "\tLDI\t1,R1\n" // Test fails
220
        "\tJMP\tR0");
221
 
222
void    overflow_test(void);
223
asm("\t.global\toverflow_test\n"
224
        "\t.type\toverflow_test,@function\n"
225
"overflow_test:\n"
226
        "\tLDI\t0,R1\n"
227
        "\tLDI\t0,R3\n"         // Clear our scorecard
228
// First test: does adding one to the maximum integer cause an overflow?
229
        "\tLDI\t-1,R2\n"
230
        "\tLSR\t1,R2\n"
231
        "\tADD\t1,R2\n"
232
        "\tOR.V\t1,R3\n"
233
// Second test: does subtracting one to the minimum integer cause an overflow?
234
        "\tLDI\t0x80000000,R2\n"
235
        "\tSUB\t1,R2\n"
236
        "\tOR.V\t2,R3\n"
237
// Third test, overflow from LSR
238
        "\tLDI\t0x80000000,R2\n"
239
        "\tLSR\t1,R2\n"         // Overflows 'cause the sign changes
240
        "\tOR.V\t4,R3\n"
241
// Fourth test, overflow from LSL
242
        "\tLDI\t0x40000000,R2\n"
243
        "\tLSL\t1,R2\n"
244
        "\tOR.V\t8,R3\n"
245
// Fifth test, overflow from LSL, negative to positive
246
        "\tLDI\t0x80000000,R2\n"
247
        "\tLSL\t1,R2\n"
248
        "\tOR.V\t16,R3\n"
249
// Record our scores
250
        "\tXOR\t31,R3\n"
251
        "\tOR\tR3,R1\n"
252
// And return the results
253
        "\tJMP\tR0");
254
 
255
 
256
void    carry_test(void);
257
asm("\t.global\tcarry_test\n"
258
        "\t.type\tcarry_test,@function\n"
259
"carry_test:\n"
260
        "\tLDI\t0,R1\n"
261
        "\tLDI\t0,R3\n"
262
// First, in adding
263
        "\tLDI\t-1,R2\n"
264
        "\tADD\t1,R2\n"
265
        "\tOR.C\t1,R3\n"
266
// Then, in subtraction
267
        "\tSUB\t1,R2\n"
268
        "\tOR.C\t2,R3\n"
269
// From a right shift
270
        "\tLDI\t1,R2\n"
271
        "\tLSR\t1,R2\n"
272
        "\tOR.C\t4,R3\n"
273
        "\tLDI\t1,R2\n"
274
        "\tASR\t1,R2\n"
275
        "\tOR.C\t8,R3\n"
276
// Or from a compare
277
        "\tLDI\t0,R2\n"
278
        "\tCMP\t1,R2\n"
279
        "\tOR.C\t16,R3\n"
280
// Set our return and clean up
281
        "\tXOR\t31,R3\n"
282
        "\tOR\tR3,R1\n"
283
        "\tJMP\tR0");
284
 
285
void    loop_test(void);
286
asm("\t.global\tloop_test\n"
287
        "\t.type\tloop_test,@function\n"
288
"loop_test:\n"
289
        "\tLDI\t0,R1\n"
290
// Let's try a loop: for(i=0; i<5; i++)
291
        "\tLDI\t0,R2\n"
292
        "\tLDI\t0,R3\n"
293
        "\tCMP\t5,R2\n"
294
        "\tBGE\tend_for_loop_test\n"
295
"for_loop_test:"
296
        "\tADD\t1,R2\n"
297
        "\tADD\t1,R3\n"
298
        "\tCMP\t5,R2\n"
299
        "\tBLT\tfor_loop_test\n"
300
"end_for_loop_test:"
301
        "\tCMP\t5,R3\n"
302
        "\tOR.NZ\t1,R1\n"
303
// How about a reverse do{} while loop?  These are usually cheaper than for()
304
// loops.
305
        "\tLDI\t0,R2\n"
306
        "\tLDI\t5,R3\n"
307
"bgt_loop_test:\n"
308
        "\tADD\t1,R2\n"
309
        "\tSUB\t1,R3\n"
310
        "\tBGT\tbgt_loop_test\n"
311
        "\tCMP\t5,R2\n"
312
        "\tOR.NZ\t2,R1\n"
313
// What if we use >=?
314
        "\tLDI\t0,R2\n"
315
        "\tLDI\t5,R3\n"
316
"bge_loop_test:\n"
317
        "\tADD\t1,R2\n"
318
        "\tSUB\t1,R3\n"
319
        "\tBGE\tbge_loop_test\n"
320
        "\tCMP\t6,R2\n"
321
        "\tOR.NZ\t4,R1\n"
322
// Once more with the reverse loop, this time storing the loop variable in
323
// memory
324
        "\tSUB\t1,SP\n"
325
        "\tLDI\t0,R2\n"
326
        "\tLDI\t5,R3\n"
327
        "\tSTO\tR3,(SP)\n"
328
"mem_loop_test:\n"
329
        "\tADD\t1,R2\n"
330
        "\tADD\t14,R3\n"
331
        "\tLOD\t(SP),R3\n"
332
        "\tSUB\t1,R3\n"
333
        "\tSTO\tR3,(SP)\n"
334
        "\tBGT\tmem_loop_test\n"
335
        "\tCMP\t5,R2\n"
336
        "\tOR.NZ\t8,R1\n"
337
        "\tADD\t1,SP\n"
338
//
339
        "\tJMP\tR0\n");
340
 
341
// Test whether or not LSL, LSR, and ASR instructions work, together with their
342
// carry flags
343
void    shift_test(void);
344
asm("\t.global\tshift_test\n"
345
        "\t.type\tshift_test,@function\n"
346
"shift_test:\n"
347
        "\tLDI\t0,R1\n"
348
        "\tLDI\t0,R3\n"
349
        "\tLDI\t0,R4\n"
350
// Does shifting right by 32 result in a zero?
351
        "\tLDI\t-1,R2\n"
352
        "\tLSR\t32,R2\n"
353
        "\tOR.Z\t1,R3\n"
354
        "\tOR.C\t2,R3\n"
355
        "\tCMP\t0,R2\n"
356
        "\tOR.Z\t4,R3\n"
357
// Does shifting a -1 right arithmetically by 32 result in a -1?
358
        "\tLDI\t-1,R2\n"
359
        "\tASR\t32,R2\n"
360
        "\tOR.LT\t8,R3\n"
361
        "\tOR.C\t16,R3\n"
362
        "\tCMP\t-1,R2\n"
363
        "\tOR.Z\t32,R3\n"
364
// Does shifting a -4 right arithmetically by 2 result in a -1?
365
        "\tLDI\t-4,R2\n"
366
        "\tASR\t2,R2\n"
367
        "\tOR.LT\t64,R3\n"
368
        "\tOR.C\t128,R1\n"
369
        "\tOR\t128,R3\n" // Artificially declare passing, so as not to fail it
370
        "\tCMP\t-1,R2\n"
371
        "\tOR.Z\t256,R3\n"
372
// Does one more set the carry flag as desired?
373
        "\tASR\t1,R2\n"
374
        "\tOR.LT\t512,R3\n"
375
        "\tOR.C\t1024,R3\n"
376
        "\tCMP\t-1,R2\n"
377
        "\tOR.Z\t2048,R3\n"
378
// Does shifting -1 left by 32 result in a zero?
379
        "\tLDI\t-1,R2\n"
380
        "\tLSL\t32,R2\n"
381
        "\tOR.Z\t4096,R3\n"
382
        "\tOR.C\t8192,R3\n"
383
        "\tCMP\t0,R2\n"
384
        "\tOR.Z\t16384,R3\n"
385
// How about shifting by zero?
386
        "\tLDI\t-1,R2\n"
387
        "\tASR\t0,R2\n"
388
        "\tOR.C\t32768,R1\n"
389
        "\tOR\t32768,R3\n"
390
        "\tCMP\t-1,R2\n"
391
        "\tOR.Z\t1,R4\n"
392
// 
393
        "\tLSR\t0,R2\n"
394
        "\tOR.C\t131072,R1\n"
395
        "\tCMP\t-1,R2\n"
396
        "\tOR.Z\t2,R4\n"
397
//
398
        "\tLSL\t0,R2\n"
399
        "\tOR.C\t524288,R1\n"
400
        "\tCMP\t-1,R2\n"
401
        "\tOR.Z\t4,R4\n"
402
// Tally up our results and return
403
        "\tXOR\t7,R4\n"
404
        "\tXOR\t65535,R3\n"
405
        "\tLSL\t16,R4\n"
406
        "\tOR\tR4,R3\n"
407
        "\tOR\tR3,R1\n"
408
        "\tJMP\tR0");
409
 
410
int     sw_brev(int v);
411
asm("\t.global\tsw_brev\n"
412
        "\t.type\tsw_brev,@function\n"
413
"sw_brev:\n"
414
        "\tSUB\t2,SP\n"
415
        "\tSTO\tR2,(SP)\n"
416
        "\tSTO\tR3,1(SP)\n"
417
        "\tLDI\t-1,R2\n"
418
        "\tCLR\tR3\n"
419
"sw_brev_loop:\n"
420
        "\tLSL\t1,R3\n"
421
        "\tLSR\t1,R1\n"
422
        "\tOR.C\t1,R3\n"
423
        "\tLSR\t1,R2\n"
424
        "\tBZ\tsw_brev_endloop\n"
425
        "\tBRA\tsw_brev_loop\n"
426
"sw_brev_endloop:\n"
427
        "\tMOV\tR3,R1\n"
428
        "\tLOD\t(SP),R2\n"
429
        "\tLOD\t1(SP),R3\n"
430
        "\tADD\t2,SP\n"
431
        "\tJMP\tR0");
432
 
433
void    pipeline_stack_test(void);
434
asm("\t.global\tpipeline_stack_test\n"
435
        "\t.type\tpipeline_stack_test,@function\n"
436
"pipeline_stack_test:\n"
437
        "\tSUB\t1,SP\n"
438
        "\tSTO\tR0,(SP)\n"
439
        "\tLDI\t0,R0\n"
440
        "\tMOV\t1(R0),R1\n"
441
        "\tMOV\t1(R1),R2\n"
442
        "\tMOV\t1(R2),R3\n"
443
        "\tMOV\t1(R3),R4\n"
444
        "\tMOV\t1(R4),R5\n"
445
        "\tMOV\t1(R5),R6\n"
446
        "\tMOV\t1(R6),R7\n"
447
        "\tMOV\t1(R7),R8\n"
448
        "\tMOV\t1(R8),R9\n"
449
        "\tMOV\t1(R9),R10\n"
450
        "\tMOV\t1(R10),R11\n"
451
        "\tMOV\t1(R11),R12\n"
452
        "\tMOV\tpipeline_stack_test_component_return(PC),R0\n"
453
        // "\tLJMP\tpipeline_stack_test_component\n"
454
        "\tBRA\tpipeline_stack_test_component\n"
455
"pipeline_stack_test_component_return:\n"
456
        "\tCMP\t1,R1\n"
457
        "\tLDI.Z\t0,R1\n"
458
        "\tCMP\t2,R2\n"
459
        "\tCMP.Z\t3,R3\n"
460
        "\tCMP.Z\t4,R4\n"
461
        "\tCMP.Z\t5,R5\n"
462
        "\tCMP.Z\t6,R6\n"
463
        "\tCMP.Z\t7,R7\n"
464
        "\tCMP.Z\t8,R8\n"
465
        "\tCMP.Z\t9,R9\n"
466
        "\tCMP.Z\t10,R10\n"
467
        "\tCMP.Z\t11,R11\n"
468
        "\tCMP.Z\t12,R12\n"
469
        "\tBREV.NZ\t-1,R1\n"
470
        "\tLOD\t(SP),R0\n"
471
        "\tADD\t1,SP\n"
472
        "\tJMP\tR0\n"
473
        );
474
 
475
void    pipeline_stack_test_component(void);
476
asm("\t.global\tpipeline_stack_test_component\n"
477
        "\t.type\tpipeline_stack_test_component,@function\n"
478
"pipeline_stack_test_component:\n"
479
        "\tSUB\t13,SP\n"
480
        "\tSTO\tR0,(SP)\n"
481
        "\tSTO\tR1,1(SP)\n"
482
        "\tSTO\tR2,2(SP)\n"
483
        "\tSTO\tR3,3(SP)\n"
484
        "\tSTO\tR4,4(SP)\n"
485
        "\tSTO\tR5,5(SP)\n"
486
        "\tSTO\tR6,6(SP)\n"
487
        "\tSTO\tR7,7(SP)\n"
488
        "\tSTO\tR8,8(SP)\n"
489
        "\tSTO\tR9,9(SP)\n"
490
        "\tSTO\tR10,10(SP)\n"
491
        "\tSTO\tR11,11(SP)\n"
492
        "\tSTO\tR12,12(SP)\n"
493
        "\tXOR\t-1,R0\n"
494
        "\tXOR\t-1,R1\n"
495
        "\tXOR\t-1,R2\n"
496
        "\tXOR\t-1,R3\n"
497
        "\tXOR\t-1,R4\n"
498
        "\tXOR\t-1,R5\n"
499
        "\tXOR\t-1,R6\n"
500
        "\tXOR\t-1,R7\n"
501
        "\tXOR\t-1,R8\n"
502
        "\tXOR\t-1,R9\n"
503
        "\tXOR\t-1,R10\n"
504
        "\tXOR\t-1,R11\n"
505
        "\tXOR\t-1,R12\n"
506
        "\tLOD\t(SP),R0\n"
507
        "\tLOD\t1(SP),R1\n"
508
        "\tLOD\t2(SP),R2\n"
509
        "\tLOD\t3(SP),R3\n"
510
        "\tLOD\t4(SP),R4\n"
511
        "\tLOD\t5(SP),R5\n"
512
        "\tLOD\t6(SP),R6\n"
513
        "\tLOD\t7(SP),R7\n"
514
        "\tLOD\t8(SP),R8\n"
515
        "\tLOD\t9(SP),R9\n"
516
        "\tLOD\t10(SP),R10\n"
517
        "\tLOD\t11(SP),R11\n"
518
        "\tLOD\t12(SP),R12\n"
519
        "\tADD\t13,SP\n"
520
        "\tJMP\tR0\n");
521
 
522
//mpy_test
523
void    mpy_test(void);
524
asm("\t.global\tmpy_test\n"
525
        "\t.type\tmpy_test,@function\n"
526
"mpy_test:\n"
527
        "\tCLR\tR1\n"
528
        // First test: let's count multiples of 137
529
        "\tLDI\t137,R2\n"       // What we're doing multiples of
530
        "\tCLR\tR3\n"           // Our accumulator via addition
531
        "\tCLR\tR4\n"           // Our index for multiplication
532
        "mpy_137_test_loop:\n"
533
        "\tMOV\tR2,R5\n"
534
        "\tMPY\tR4,R5\n"
535
        "\tCMP\tR3,R5\n"
536
        "\tBNZ\tend_mpy_137_test_loop_failed\n"
537
        // Let's try negative while we are at it
538
        "\tMOV\tR2,R6\n"
539
        "\tNEG\tR6\n"
540
        "\tMPY\tR4,R6\n"
541
        "\tNEG\tR6\n"
542
        "\tCMP\tR3,R6\n"
543
        "\tBNZ\tend_mpy_137_test_loop_failed\n"
544
        "\tCLR\tR6\n"
545
        "\tTEST\t0xffff0000,R3\n"
546
        "\tBNZ\tend_mpy_137_test_loop\n"
547
        "\tADD\tR2,R3\n"
548
        "\tADD\t1,R4\n"
549
        "\tBRA\tmpy_137_test_loop\n"
550
"end_mpy_137_test_loop_failed:\n"
551
        "\tOR\t1,R1\n"
552
"end_mpy_137_test_loop:\n"
553
        // Second test ... whatever that might be
554
        "\tJMP\tR0\n");
555
 
556
//brev_test
557
//pipeline_test -- used to be called pipeline memory race conditions
558
void    pipeline_test(void);
559
asm("\t.global\tpipeline_test\n"
560
        "\t.type\tpipeline_test,@function\n"
561
"pipeline_test:\n"
562
        "\tSUB\t2,SP\n"
563
        // Test setup
564
        "\tLDI\t275,R2\n"
565
        "\tSTO\tR2,1(SP)\n"
566
        "\tMOV\t1(SP),R2\n"
567
        "\tSTO\tR2,(SP)\n"
568
        "\tCLR\tR2\n"
569
        //
570
        "\tMOV\tSP,R2\n"
571
        "\tLOD\t(R2),R2\n"
572
        "\tLOD\t(R2),R2\n"
573
        "\tCMP\t275,R2\n"
574
        "\tOR.NZ\t1,R1\n"
575
        //
576
        "\tMOV\tSP,R2\n"
577
        // Here's the test sequence
578
        "\tLOD\t(R2),R3\n"
579
        "\tLOD\t1(R2),R4\n"
580
        "\tSTO\tR4,1(R3)\n"
581
        // Make sure we clear the load pipeline
582
        "\tLOD\t(R2),R3\n"
583
        // Load our written value
584
        "\tLOD\t2(R2),R4\n"
585
        "\tCMP\t275,R4\n"
586
        "\tOR.NZ\t2,R1\n"
587
        //
588
        //
589
        // Next (once upon a time) failing sequence:
590
        //      LOD -x(R12),R0
591
        //      LOD y(R0),R0
592
        "\tMOV\tSP,R2\n"
593
        "\tMOV\t1(R2),R3\n"
594
        "\tSTO\tR3,1(R2)\n"
595
        "\tLDI\t3588,R4\n"      // Just some random value
596
        "\tSTO\tR4,2(R2)\n"
597
        "\tMOV\tR2,R3\n"
598
        // Here's the test sequence
599
        "\tLOD\t(R2),R3\n"
600
        "\tLOD\t1(R3),R3\n"
601
        "\tCMP\tR4,R3\n"
602
        "\tOR.NZ\t4,R1\n"
603
        //
604
        "\tADD\t2,SP\n"
605
        "\tJMP\tR0\n");
606
 
607
//mempipe_test
608
void    mempipe_test(void);
609
asm("\t.global\tmempipe_test\n"
610
        "\t.type\tmempipe_test,@function\n"
611
"mempipe_test:\n"
612
        "\tSUB\t4,SP\n"
613
        "\tSTO\tR0,(SP)\n"
614
        "\tLDI\t0x1000,R11\n"
615
        // Test #1 ... Let's start by writing a value to memory
616
        "\tLDI\t-1,R2\n"
617
        "\tCLR\tR3\n"
618
        "\tSTO\tR2,2(SP)\n"
619
        "\tLOD\t2(SP),R3\n"
620
        "\tCMP\tR3,R2\n"
621
        "\tOR.NZ\t1,R1\n"
622
        // Test #2, reading and then writing a value from memory
623
        "\tNOOP\n"
624
        "\tNOOP\n"
625
        "\tCLR\tR2\n"
626
        "\tCLR\tR3\n"
627
        "\tLOD\t2(SP),R2\n"     // This should load back up our -1 value
628
        "\tSTO\tR2,3(SP)\n"
629
        // Insist that the pipeline clear
630
        "\tLOD\t2(SP),R2\n"
631
        // Now let's try loading into R3
632
        "\tNOOP\n"
633
        "\tNOOP\n"
634
        "\tNOOP\n"
635
        "\tNOOP\n"
636
        "\tLOD\t3(SP),R3\n"
637
        "\tCMP\tR3,R2\n"
638
        "\tOR.NZ\t2,R1\n"
639
        //
640
        "\tLOD\t(SP),R0\n"
641
        "\tADD\t4,SP\n"
642
        "\tJMP\tR0\n");
643
 
644
//cexec_test
645
void    cexec_test(void);
646
asm("\t.global\tcexec_test\n"
647
        "\t.type\tcexec_test,@function\n"
648
"cexec_test:\n"
649
        "\tSUB\t1,SP\n"
650
        "\tSTO\tR0,(SP)\n"
651
        //
652
        "\tXOR\tR2,R2\n"
653
        "\tADD.Z\t1,R2\n"
654
        "\tADD.NZ\t1,R1\n"
655
        "\tCMP.Z\t0,R2\n"
656
        "\tOR.Z\t2,R1\n"
657
        //
658
        "\tLOD\t(SP),R0\n"
659
        "\tADD\t1,SP\n"
660
        "\tJMP\tR0\n");
661
 
662
// Pipeline stalls have been hideous problems for me.  The CPU has been modified
663
// with special logic to keep stages from stalling.  For the most part, this
664
// means that ALU and memory results may be accessed either before or as they
665
// are written to the register file.  This set of code is designed to test
666
// whether this bypass logic works.
667
//
668
//nowaitpipe_test
669
void    nowaitpipe_test(void);
670
asm("\t.global\tnowaitpipe_test\n"
671
        "\t.type\tnowaitpipe_test,@function\n"
672
"nowaitpipe_test:\n"
673
        "\tSUB\t2,SP\n"
674
        //
675
        // Let's start with ALU-ALU testing
676
        //      AA: result->input A
677
        "\tLDI\t-1,R2\n"
678
        "\tCLR\tR2\n"
679
        "\tADD\t1,R2\n"
680
        "\tCMP\t1,R2\n"
681
        "\tOR.NZ\t1,R1\n"
682
        //
683
        //      AA: result -> input B
684
        "\tCLR\tR2\n"
685
        "\tCLR\tR3\n"
686
        "\tADD\t1,R2\n"
687
        "\tCMP\tR2,R3\n"
688
        "\tOR.Z\t2,R1\n"
689
        //      AA: result -> input A on condition
690
        "\tXOR\tR2,R2\n"
691
        "\tADD.Z\t5,R2\n"
692
        "\tCMP\t5,R2\n"
693
        "\tOR.NZ\t4,R1\n"
694
        //      AA: result -> input B on condition
695
        "\tCLR\tR2\n"
696
        "\tXOR\tR3,R3\n"
697
        "\tADD.Z\t5,R2\n"
698
        "\tCMP\tR2,R3\n"
699
        "\tOR.Z\t8,R1\n"
700
        //      AA: result->input B plus offset
701
        "\tCLR\tR2\n"
702
        "\tXOR\tR3,R3\n"
703
        "\tADD\t5,R2\n"
704
        "\tCMP\t-5(R2),R3\n"
705
        "\tOR.NZ\t16,R1\n"
706
        //      AA: result->input B plus offset on condition
707
        "\tCLR\tR2\n"
708
        "\tXOR\tR3,R3\n"
709
        "\tADD.Z\t5,R2\n"
710
        "\tCMP\t-5(R2),R3\n"
711
        "\tOR.NZ\t32,R1\n"
712
        //
713
        // Then we need to do the ALU-MEM input testing
714
        //
715
        "\tCLR\tR2\n"
716
        "\tSTO\tR2,1(SP)\n"
717
        "\tLDI\t8352,R2\n"
718
        "\tLOD\t1(SP),R2\n"
719
        "\tTST\t-1,R2\n"
720
        "\tOR.NZ\t64,R1\n"
721
        // Let's try again, this time with something that's not zero
722
        "\tLDI\t937,R2\n"
723
        "\tSTO\tR2,1(SP)\n"
724
        "\tNOOP\n"
725
        "\tLOD\t1(SP),R2\n"
726
        "\tCMP\t938,R2\n"
727
        "\tOR.GE\t128,R1\n"
728
        "\tCMP\t936,R2\n"
729
        "\tOR.LT\t256,R1\n"
730
        // Mem output->ALU input testing
731
        //      Okay, we just did that as part of our last test
732
        // Mem output->mem input testing
733
        "\tLDI\t5328,R2\n"
734
        "\tLOD\t1(SP),R2\n"
735
        "\tSTO\tR2,1(SP)\n"
736
        "\tLOD\t1(SP),R3\n"
737
        "\tCMP\t937,R3\n"
738
        "\tOR.NZ\t512,R1\n"
739
        //
740
        "\tADD\t2,SP\n"
741
        "\tJMP\tR0\n");
742
 
743
//bcmem_test
744
void    bcmem_test(void);
745
asm("\t.global\tbcmem_test\n"
746
        "\t.type\tbcmem_test,@function\n"
747
"bcmem_test:\n"
748
        "\tSUB\t1,SP\n"
749
        "\tCLR\tR1\n"
750
        "\tCLR\tR2\n"
751
        "\tLDI\t-1,R3\n"
752
        "\tLDI\t0x13000,R4\n"
753
        "\tSTO\tR2,(SP)\n"
754
        "\tLOD\t(SP),R3\n"
755
        "\tCMP\tR2,R3\n"
756
        "\tOR.NZ\t1,R1\n"
757
        "\tCMP\t0x13000,R4\n"
758
        "\tBZ\tbcmem_test_cmploc_1\n"
759
        "\tSTO\tR4,(SP)\n"
760
"bcmem_test_cmploc_1:\n"
761
        "\tLOD\t(SP),R2\n"
762
        "\tCMP\tR2,R4\n"
763
        "\tOR.Z\t2,R1\n"
764
        "\tCLR\tR2\n"
765
        "\tCMP\tR2,R4\n"
766
        "\tBZ\tbcmem_test_cmploc_2\n"
767
        "\tSTO.NZ\tR4,(SP)\n"
768
"bcmem_test_cmploc_2:\n"
769
        "\tLOD\t(SP),R2\n"
770
        "\tCMP\tR2,R4\n"
771
        "\tOR.NZ\t4,R1\n"
772
//
773
        "\tADD\t1,SP\n"
774
        "\tJMP\tR0\n");
775
 
776
//
777
// The CC register has some ... unique requirements associated with it.
778
// Particularly, flags are unavailable until after an ALU operation completes,
779
// and they can't really be bypassed for the CC register.  After writeback,
780
// the "new" CC register isn't really available for another clock.  Trying to
781
// bypass this extra clock can have problems, since ... some bits are fixed,
782
// some bits can only be changed by the supervisor, and others can/will change
783
// and even have effects--like sending the CPU to supervisor mode or
784
// alternatively to sleep.
785
//
786
// Here, let's see if our pipeline can successfully navigate any of these
787
// issues.
788
//
789
void    ccreg_test(void);
790
asm("\t.global\tccreg_test\n"
791
        "\t.type\tccreg_test,@function\n"
792
"ccreg_test:\n"
793
        // First test: If we try to change the fixed bits, will they change
794
        // because the pipeline tries to bypass the write-back stage
795
        "\tCLR\tR1\n"   // We'll start with an "answer" of success
796
        "\tMOV\tCC,R2\n"
797
        "\tMOV\tR2,R4\n"        // Keep a copy
798
        "\tBREV\t0x0ff,R3\n"    // Attempt to change the top fixed bits
799
        "\tXOR\tR3,R2\n"        // Arrange for the changes
800
        "\tMOV\tR2,CC\n"        // Set the changes (they won't take)
801
        "\tMOV\tCC,R5\n"        // See if the pipeline makes them take
802
        "\tXOR\tR4,R5\n"        // Let's look for anything that has changed
803
        "\tOR.NZ\t1,R1\n"       // If anything has changed, then we fail the tst
804
        // 
805
        // Test #2: Can we set the flags?
806
        "\tMOV\tCC,R6\n"
807
        "\tOR\t15,R6\n"
808
        "\tMOV\tR6,CC\n"
809
        "\tMOV\tCC,R7\n"
810
        "\tAND\t15,R7\n"
811
        "\tCMP\t15,R7\n"
812
        "\tOR.NZ\t2,R1\n"
813
        //
814
        // Test #3: How about setting specific flags, and immediately acting
815
        // on them?
816
        "\tXOR\t1+R8,R8\n"      // Turn off the Z bit
817
        "\tOR\t1,CC\n"          // Turn on the Z bit
818
        "\tOR.NZ\t4,R1\n"
819
        //
820
        // Test #4: Can we load the CC plus a value into a register?
821
        //      I don't think so ...
822
        "\tJMP\tR0\n");
823
 
824 172 dgisselq
// Multiple argument test
825 168 dgisselq
__attribute__((noinline))
826 172 dgisselq
int     multiarg_subroutine(int a, int b, int c, int d, int e, int f, int g) {
827
        if (a!=0)        return 1;
828
        if (b!=1)       return 2;
829
        if (c!=2)       return 4;
830
        if (d!=3)       return 8;
831
        if (e!=4)       return 16;
832
        if (f!=5)       return 32;
833
        if (g!=6)       return 64;
834
        return 0;
835
}
836
 
837
int     multiarg_test(void) {
838
        return multiarg_subroutine(0,1,2,3,4,5,6);
839
}
840
 
841
__attribute__((noinline))
842 168 dgisselq
void    wait(unsigned int msk) {
843
        *PIC = 0x7fff0000|msk;
844
        asm("MOV\tidle_task(PC),uPC\n");
845
        *PIC = 0x80000000|(msk<<16);
846
        asm("WAIT\n");
847
        *PIC = 0; // Turn interrupts back off, lest they confuse the test
848
}
849
 
850
asm("\nidle_task:\n\tWAIT\n\tBRA\tidle_task\n");
851
 
852
__attribute__((noinline))
853
void    txchr(char v) {
854
        wait(INT_UARTTX);
855
        *UARTTX = v;
856
}
857
 
858
__attribute__((noinline))
859
void    txstr(const char *str) {
860
        const char *ptr = str;
861
        while(*ptr)
862
                txchr(*ptr++);
863
}
864
 
865
__attribute__((noinline))
866
void    txhex(int num) {
867
        for(int ds=28; ds>=0; ds-=4) {
868
                int     ch;
869
                ch = (num >> ds)&0x0f;
870
                if (ch >= 10)
871
                        ch = 'A'+ch-10;
872
                else
873
                        ch += '0';
874
                txchr(ch);
875
        }
876
}
877
 
878
__attribute__((noinline))
879
void    txreg(const char *name, int val) {
880
        txstr(name);    // 4 characters
881
        txstr("0x");    // 2 characters
882
        txhex(val);     // 8 characters
883
        txstr("    ");  // 4 characters
884
}
885
 
886
__attribute__((noinline))
887
void    save_context(int *context) {
888
        zip_save_context(context);
889
}
890
 
891
__attribute__((noinline))
892
void    test_fails(int start_time, int *listno) {
893
        int     context[16], stop_time;
894
 
895
        // Trigger the scope, if it hasn't already triggered.  Otherwise,
896
        // if it has triggered, don't clear it.
897
#ifdef  HAVE_SCOPE
898
        *SCOPE = 0x8f000004;
899
#endif
900
 
901
        MARKSTOP;
902
        save_context(context);
903
        *listno++ = context[1];
904
        *listno++ = context[14];
905
        *listno++ = context[15];
906
#ifdef  HAVE_COUNTER
907
        *listno   = stop_time;
908
#endif
909
 
910
        txstr("FAIL!\r\n\r\n");
911
        txstr("Between 0x"); txhex(start_time);
912
                txstr(" and 0x"); txhex(stop_time); txstr("\r\n\r\n");
913
        txstr("Core-dump:\r\n");
914
        txreg("uR0 : ", context[0]);
915
        txreg("uR1 : ", context[1]);
916
        txreg("uR2 : ", context[2]);
917
        txreg("uR3 : ", context[3]);
918
        txstr("\r\n");
919
 
920
        txreg("uR4 : ", context[4]);
921
        txreg("uR5 : ", context[5]);
922
        txreg("uR6 : ", context[6]);
923
        txreg("uR7 : ", context[7]);
924
        txstr("\r\n");
925
 
926
        txreg("uR8 : ", context[8]);
927
        txreg("uR9 : ", context[9]);
928
        txreg("uR10: ", context[10]);
929
        txreg("uR11: ", context[11]);
930
        txstr("\r\n");
931
 
932
        txreg("uR12: ", context[12]);
933
        txreg("uSP : ", context[13]);
934
        txreg("uCC : ", context[14]);
935
        txreg("uPC : ", context[15]);
936
        txstr("\r\n\r\n");
937
 
938
        asm("\tBUSY");
939
}
940
 
941
void    testid(const char *str) {
942
        const int       WIDTH=32;
943
        txstr(str);
944
        const char *ptr = str;
945
        int     i = 0;
946
        while(0 != *ptr++)
947
                i++;
948
        i = WIDTH-i;
949
        while(i-- > 0)
950
                txchr(' ');
951
}
952
 
953
int     testlist[32];
954
 
955
void entry(void) {
956
        int     context[16];
957
        int     user_stack[256], *user_stack_ptr = &user_stack[256];
958
        int     start_time, i;
959
 
960
        for(i=0; i<32; i++)
961
                testlist[i] = -1;
962
 
963
#ifdef  HAVE_TIMER
964
        *TIMER = 0x7fffffff;
965
#endif
966
#ifdef  HAVE_COUNTER
967
        *COUNTER = 0;
968
#endif
969
 
970 172 dgisselq
// #define      STACKTEST       asm("CMP\t16108,SP\n\tHALT.NZ\n")
971
#define STACKTEST
972 168 dgisselq
        STACKTEST;
973
 
974
        // *UART_CTRL = 8333; // 9600 Baud, 8-bit chars, no parity, one stop bit
975
        *UART_CTRL = 25; // 9600 Baud, 8-bit chars, no parity, one stop bit
976
        //
977
        STACKTEST;
978
 
979
        txstr("\r\n");
980
        txstr("Running CPU self-test\n");
981
        txstr("-----------------------------------\r\n");
982
 
983
        int     tnum = 0;
984
        STACKTEST;
985
 
986
        // Test break instruction in user mode
987
        // Make sure the break works as designed
988
        testid("Break test #1"); MARKSTART;
989
        STACKTEST;
990
 
991
        if ((run_test(break_one, user_stack_ptr))||(zip_ucc()&0x1f50))
992
                test_fails(start_time, &testlist[tnum]);
993
        STACKTEST;
994
 
995
        save_context(context);
996 172 dgisselq
        if ((context[15] != (int)break_one+1)||(0==(zip_ucc()&0x80)))
997 168 dgisselq
                test_fails(start_time, &testlist[tnum]);
998
        txstr("Pass\r\n"); testlist[tnum++] = 0; // 0
999
 
1000
        STACKTEST;
1001
 
1002
        // Test break instruction in user mode
1003
        // Make sure that a decision on the clock prior won't still cause a 
1004
        // break condition
1005
        testid("Break test #2"); MARKSTART;
1006 172 dgisselq
        if ((run_test(break_two, user_stack_ptr))||(zip_ucc()&0x1d90))
1007 168 dgisselq
                test_fails(start_time, &testlist[tnum]);
1008
        txstr("Pass\r\n"); testlist[tnum++] = 0; // #1
1009
 
1010
        // LJMP test ... not (yet) written
1011
 
1012
        // Test the early branching capability
1013
        //      Does it successfully clear whatever else is in the pipeline?
1014
        testid("Early Branch test"); MARKSTART;
1015
        if ((run_test(early_branch_test, user_stack_ptr))||(zip_ucc()&0x01d90))
1016
                test_fails(start_time, &testlist[tnum]);
1017
        txstr("Pass\r\n"); testlist[tnum++] = 0; // #2
1018
 
1019
        // TRAP test
1020
        testid("Trap test/AND"); MARKSTART;
1021
        if ((run_test(trap_test_and, user_stack_ptr))||(zip_ucc()&0x01d90))
1022
                test_fails(start_time, &testlist[tnum]);
1023
        if ((zip_ucc() & 0x0200)==0)
1024
                test_fails(start_time, &testlist[tnum]);
1025
        txstr("Pass\r\n"); testlist[tnum++] = 0; // #3
1026
 
1027
        testid("Trap test/CLR"); MARKSTART;
1028
        if ((run_test(trap_test_clr, user_stack_ptr))||(zip_ucc()&0x01d90))
1029
                test_fails(start_time, &testlist[tnum]);
1030
        if ((zip_ucc() & 0x0200)==0)
1031
                test_fails(start_time, &testlist[tnum]);
1032
        txstr("Pass\r\n"); testlist[tnum++] = 0; // #4
1033
 
1034
        // Overflow test
1035
        testid("Overflow test"); MARKSTART;
1036
        if ((run_test(overflow_test, user_stack_ptr))||(zip_ucc()&0x01d90))
1037
                test_fails(start_time, &testlist[tnum]);
1038
        txstr("Pass\r\n"); testlist[tnum++] = 0; // #5
1039
 
1040
        // Carry test
1041
        testid("Carry test"); MARKSTART;
1042
        if ((run_test(carry_test, user_stack_ptr))||(zip_ucc()&0x01d90))
1043
                test_fails(start_time, &testlist[tnum]);
1044
        txstr("Pass\r\n"); testlist[tnum++] = 0; // #6
1045
 
1046
        // LOOP_TEST
1047
        testid("Loop test"); MARKSTART;
1048
        if ((run_test(loop_test, user_stack_ptr))||(zip_ucc()&0x01d90))
1049
                test_fails(start_time, &testlist[tnum]);
1050
        txstr("Pass\r\n"); testlist[tnum++] = 0; // #7 -- FAILS
1051
 
1052
        // SHIFT_TEST
1053
        testid("Shift test"); MARKSTART;
1054
        if ((run_test(shift_test, user_stack_ptr))||(zip_ucc()&0x01d90))
1055
                test_fails(start_time, &testlist[tnum]);
1056
        txstr("Pass\r\n"); testlist[tnum++] = 0; // #8
1057
 
1058
        // MPY_TEST
1059
        testid("Multiply test"); MARKSTART;
1060
        if ((run_test(mpy_test, user_stack_ptr))||(zip_ucc()&0x01d90))
1061
                test_fails(start_time, &testlist[tnum]);
1062
        txstr("Pass\r\n"); testlist[tnum++] = 0; // #9
1063
 
1064
        // BREV_TEST
1065
        //testid("BREV/stack test"); MARKSTART;
1066
        //if ((run_test(brev_test, user_stack_ptr))||(zip_ucc()&0x01d90))
1067
                //test_fails(start_time);
1068
        //txstr("Pass\r\n");
1069
 
1070
        // PIPELINE_TEST
1071
        testid("Pipeline test"); MARKSTART;
1072
        if ((run_test(pipeline_test, user_stack_ptr))||(zip_ucc()&0x01d90))
1073
                test_fails(start_time, &testlist[tnum]);
1074
        txstr("Pass\r\n"); testlist[tnum++] = 0; // #10
1075
 
1076
        // MEM_PIPELINE_STACK_TEST
1077
        testid("Mem-Pipeline test"); MARKSTART;
1078
        if ((run_test(mempipe_test, user_stack_ptr))||(zip_ucc()&0x01d90))
1079
                test_fails(start_time, &testlist[tnum]);
1080
        txstr("Pass\r\n"); testlist[tnum++] = 0; // #11
1081
 
1082
        // CONDITIONAL EXECUTION test
1083
        testid("Conditional Execution test"); MARKSTART;
1084
        if ((run_test(cexec_test, user_stack_ptr))||(zip_ucc()&0x01d90))
1085
                test_fails(start_time, &testlist[tnum]);
1086
        txstr("Pass\r\n"); testlist[tnum++] = 0; // #12 -- FAILS
1087
 
1088
        // NOWAIT pipeline test
1089
        testid("No-waiting pipeline test"); MARKSTART;
1090
        if ((run_test(nowaitpipe_test, user_stack_ptr))||(zip_ucc()&0x01d90))
1091
                test_fails(start_time, &testlist[tnum]);
1092
        txstr("Pass\r\n"); testlist[tnum++] = 0; // #13
1093
 
1094
        // BCMEM test
1095
        testid("Conditional Branching test"); MARKSTART;
1096
        if ((run_test(bcmem_test, user_stack_ptr))||(zip_ucc()&0x01d90))
1097
                test_fails(start_time, &testlist[tnum]);
1098
        txstr("Pass\r\n"); testlist[tnum++] = 0; // #14
1099
 
1100
        // Illegal Instruction test
1101
        testid("Illegal Instruction test"); MARKSTART;
1102
        if ((run_test(NULL, user_stack_ptr))||((zip_ucc()^0x100)&0x01d90))
1103
                test_fails(start_time, &testlist[tnum]);
1104
        txstr("Pass\r\n"); testlist[tnum++] = 0;
1105
 
1106
        // Pipeline memory race condition test
1107
        // DIVIDE test
1108
 
1109
        // CC Register test
1110
        testid("CC Register test"); MARKSTART;
1111
        if ((run_test(ccreg_test, user_stack_ptr))||(zip_ucc()&0x01d90))
1112
                test_fails(start_time, &testlist[tnum]);
1113
        txstr("Pass\r\n"); testlist[tnum++] = 0;
1114
 
1115 172 dgisselq
        // Multiple argument test
1116
        testid("Multi-Arg test"); MARKSTART;
1117
        if ((run_test(multiarg_test, user_stack_ptr))||(zip_ucc()&0x01d90))
1118
                test_fails(start_time, &testlist[tnum]);
1119
        txstr("Pass\r\n"); testlist[tnum++] = 0;
1120
 
1121 168 dgisselq
        txstr("\r\n");
1122
        txstr("-----------------------------------\r\n");
1123
        txstr("All tests passed.  Halting CPU.\n");
1124
        zip_halt();
1125
}
1126
 
1127
// To build this:
1128
//      zip-gcc -O3 -Wall -Wextra -nostdlib -fno-builtin -T xula.ld -Wl,-Map,cputest.map cputest.cpp -o cputest
1129
//      zip-objdump -D cputest > cputest.txt
1130
//

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.