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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [or1ksim/] [testsuite/] [test-code-or1k/] [inst-set-test/] [is-mul-test.S] - Blame information for rev 118

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 118 jeremybenn
/* is-mul-test.S. l.mul, l.muli and l.mulu instruction test of Or1ksim
2
 *
3
 * Copyright (C) 1999-2006 OpenCores
4
 * Copyright (C) 2010 Embecosm Limited
5
 *
6
 * Contributors various OpenCores participants
7
 * Contributor Jeremy Bennett 
8
 *
9
 * This file is part of OpenRISC 1000 Architectural Simulator.
10
 *
11
 * This program is free software; you can redistribute it and/or modify it
12
 * under the terms of the GNU General Public License as published by the Free
13
 * Software Foundation; either version 3 of the License, or (at your option)
14
 * any later version.
15
 *
16
 * This program is distributed in the hope that it will be useful, but WITHOUT
17
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
19
 * more details.
20
 *
21
 * You should have received a copy of the GNU General Public License along
22
 * with this program.  If not, see .
23
 */
24
 
25
/* ----------------------------------------------------------------------------
26
 * Coding conventions are described in inst-set-test.S
27
 * ------------------------------------------------------------------------- */
28
 
29
/* ----------------------------------------------------------------------------
30
 * Test coverage
31
 *
32
 * The l.mul, l.muli and l.mulu instructions should all be present and set the
33
 * carry and overflow flags.
34
 *
35
 * Problems in this area were reported in Bugs 1774, 1782, 1783 and 1784.
36
 * Having fixed the problem, this is (in good software engineering style), a
37
 * regression test to go with the fix.
38
 *
39
 * This is not a comprehensive test of any instruction (yet).
40
 *
41
 * Of course what is really needed is a comprehensive instruction test...
42
 * ------------------------------------------------------------------------- */
43
 
44
 
45
#include "inst-set-test.h"
46
 
47
/* ----------------------------------------------------------------------------
48
 * A macro to carry out a test of multiply signed or unsigned
49
 *
50
 * Arguments
51
 *   opc:       The opcode
52
 *   op1:       First operand value
53
 *   op2:       Second operand value
54
 *   res:       Expected result
55
 *   cy:        Expected carry flag
56
 *   ov:        Expected overflow flag
57
 * ------------------------------------------------------------------------- */
58
#define TEST_MUL(opc, op1, op2, res, cy, ov)                             \
59
        l.mfspr r3,r0,SPR_SR                                            ;\
60
        LOAD_CONST (r2, ~(SPR_SR_CY | SPR_SR_OV))                       ;\
61
        l.and   r3,r3,r2                /* Clear flags */               ;\
62
        l.mtspr r0,r3,SPR_SR                                            ;\
63
                                                                        ;\
64
        LOAD_CONST (r5,op1)             /* Load numbers to add */       ;\
65
        LOAD_CONST (r6,op2)                                             ;\
66
        l.mtspr r0,r0,SPR_EPCR_BASE     /* Clear record */              ;\
67
50:     opc     r4,r5,r6                                                ;\
68
        l.mfspr r2,r0,SPR_SR            /* So we can examine flags */   ;\
69
        l.mfspr r5,r0,SPR_EPCR_BASE     /* What triggered exception */  ;\
70
        PUSH (r5)                       /* Save EPCR for later */       ;\
71
        PUSH (r2)                       /* Save SR for later */         ;\
72
        PUSH (r4)                       /* Save result for later */     ;\
73
                                                                        ;\
74
        PUTS ("  0x")                                                   ;\
75
        PUTH (op1)                                                      ;\
76
        PUTS (" * 0x")                                                  ;\
77
        PUTH (op2)                                                      ;\
78
        PUTS (" = 0x")                                                  ;\
79
        PUTH (res)                                                      ;\
80
        PUTS (": ")                                                     ;\
81
        POP (r4)                                                        ;\
82
        CHECK_RES1 (r4, res)                                            ;\
83
                                                                        ;\
84
        POP (r2)                        /* Retrieve SR */               ;\
85
        PUSH (r2)                                                       ;\
86
        LOAD_CONST (r4, SPR_SR_CY)      /* The carry bit */             ;\
87
        l.and   r2,r2,r4                                                ;\
88
        l.sfeq  r2,r4                                                   ;\
89
        CHECK_FLAG ("- carry flag set:      ", cy)                      ;\
90
                                                                        ;\
91
        POP (r2)                        /* Retrieve SR */               ;\
92
        LOAD_CONST (r4, SPR_SR_OV)      /* The overflow bit */          ;\
93
        l.and   r2,r2,r4                                                ;\
94
        l.sfeq  r2,r4                                                   ;\
95
        CHECK_FLAG ("- overflow flag set:   ", ov)                      ;\
96
                                                                        ;\
97
        POP (r2)                        /* Retrieve EPCR */             ;\
98
        LOAD_CONST (r4, 50b)            /* The opcode of interest */    ;\
99
        l.and   r2,r2,r4                                                ;\
100
        l.sfeq  r2,r4                                                   ;\
101
        l.bnf   51f                                                     ;\
102
                                                                        ;\
103
        PUTS ("  - exception triggered: TRUE\n")                        ;\
104
        l.j     52f                                                     ;\
105
        l.nop                                                           ;\
106
                                                                        ;\
107
51:     PUTS ("  - exception triggered: FALSE\n")                       ;\
108
52:
109
 
110
 
111
/* ----------------------------------------------------------------------------
112
 * A macro to carry out a test of multiply immediate
113
 *
114
 * Arguments
115
 *   op1:       First operand value
116
 *   op2:       Second operand value
117
 *   res:       Expected result
118
 *   cy:        Expected carry flag
119
 *   ov:        Expected overflow flag
120
 * ------------------------------------------------------------------------- */
121
#define TEST_MULI(op1, op2, res, cy, ov)                                 \
122
        l.mfspr r3,r0,SPR_SR                                            ;\
123
        LOAD_CONST (r2, ~(SPR_SR_CY | SPR_SR_OV))                       ;\
124
        l.and   r3,r3,r2                /* Clear flags */               ;\
125
        l.mtspr r0,r3,SPR_SR                                            ;\
126
                                                                        ;\
127
        LOAD_CONST (r5,op1)             /* Load numbers to add */       ;\
128
        l.mtspr r0,r0,SPR_EPCR_BASE     /* Clear record */              ;\
129
53:     l.muli  r4,r5,op2                                               ;\
130
        l.mfspr r2,r0,SPR_SR            /* So we can examine flags */   ;\
131
        l.mfspr r5,r0,SPR_EPCR_BASE     /* What triggered exception */  ;\
132
        PUSH (r5)                       /* Save EPCR for later */       ;\
133
        PUSH (r2)                       /* Save SR for later */         ;\
134
        PUSH (r4)                       /* Save result for later */     ;\
135
                                                                        ;\
136
        PUTS ("  0x")                                                   ;\
137
        PUTH (op1)                                                      ;\
138
        PUTS (" * 0x")                                                  ;\
139
        PUTHH (op2)                                                     ;\
140
        PUTS (" = 0x")                                                  ;\
141
        PUTH (res)                                                      ;\
142
        PUTS (": ")                                                     ;\
143
        POP (r4)                                                        ;\
144
        CHECK_RES1 (r4, res)                                            ;\
145
                                                                        ;\
146
        POP(r2)                         /* Retrieve SR */               ;\
147
        PUSH(r2)                                                        ;\
148
        LOAD_CONST (r4, SPR_SR_CY)      /* The carry bit */             ;\
149
        l.and   r2,r2,r4                                                ;\
150
        l.sfeq  r2,r4                                                   ;\
151
        CHECK_FLAG ("- carry flag set:      ", cy)                      ;\
152
                                                                        ;\
153
        POP(r2)                         /* Retrieve SR */               ;\
154
        LOAD_CONST (r4, SPR_SR_OV)      /* The overflow bit */          ;\
155
        l.and   r2,r2,r4                                                ;\
156
        l.sfeq  r2,r4                                                   ;\
157
        CHECK_FLAG ("- overflow flag set:   ", ov)                      ;\
158
                                                                        ;\
159
        POP (r2)                        /* Retrieve EPCR */             ;\
160
        LOAD_CONST (r4, 53b)            /* The opcode of interest */    ;\
161
        l.and   r2,r2,r4                                                ;\
162
        l.sfeq  r2,r4                                                   ;\
163
        l.bnf   54f                                                     ;\
164
                                                                        ;\
165
        PUTS ("  - exception triggered: TRUE\n")                        ;\
166
        l.j     55f                                                     ;\
167
        l.nop                                                           ;\
168
                                                                        ;\
169
54:     PUTS ("  - exception triggered: FALSE\n")                       ;\
170
55:
171
 
172
 
173
/* ----------------------------------------------------------------------------
174
 * Start of code
175
 * ------------------------------------------------------------------------- */
176
        .section .text
177
        .global _start
178
_start:
179
        l.mfspr r3,r0,SPR_SR
180
        LOAD_CONST (r2, ~SPR_SR_OVE)    /* Clear OVE */
181
        l.and   r3,r3,r2
182
        l.mtspr r0,r3,SPR_SR
183
 
184
        LOAD_STR (r3, "  ** OVE flag cleared **\n")
185
        l.jal   _puts
186
        l.nop
187
 
188
/* ----------------------------------------------------------------------------
189
 * Test of multiply signed, l.mul
190
 * ------------------------------------------------------------------------- */
191
_mul:
192
        LOAD_STR (r3, "l.mul\n")
193
        l.jal   _puts
194
        l.nop
195
 
196
        /* Multiply two small positive numbers. Should set no flags. */
197
        TEST_MUL (l.mul, 0x00000002, 0x00000003,
198
                  0x00000006, FALSE, FALSE)
199
 
200
        /* Multiply two quite large positive numbers. Should set no flags */
201
        TEST_MUL (l.mul, 0x00008001, 0x0000fffe,
202
                  0x7ffffffe, FALSE, FALSE)
203
 
204
        /* Multiply two slightly too large positive numbers. Should set the
205
           overflow, but not the carry flag */
206
        TEST_MUL (l.mul, 0x00008000, 0x00010000,
207
                  0x80000000, FALSE, TRUE)
208
 
209
        /* Multiply two large positive numbers. Should set both the carry and
210
           overflow flags (even though the result is not a negative number. */
211
        TEST_MUL (l.mul, 0x00010000, 0x00010000, 0x00000000, TRUE, TRUE)
212
 
213
        /* Multiply two small negative numbers. Should set the overflow, but not
214
           the carry flag. */
215
        TEST_MUL (l.mul, 0xfffffffe, 0xfffffffd,
216
                  0x00000006, TRUE, FALSE)
217
 
218
        /* Multiply two quite large negative numbers. Should set the overflow,
219
           but not the carry flag. */
220
        TEST_MUL (l.mul, 0xffff7fff, 0xffff0002,
221
                  0x7ffffffe, TRUE, FALSE)
222
 
223
        /* Multiply two slightly too large negative numbers. Should set both the
224
           overflow, and the carry flags */
225
        TEST_MUL (l.mul, 0xffff7fff, 0xffff0000,
226
                  0x80010000, TRUE, TRUE)
227
 
228
        /* Multiply two large negative numbers. Should set the
229
           both the carry and overflow flags (even though the result is a
230
           positive number. */
231
        TEST_MUL (l.mul, 0xffff0000, 0xfffeffff,
232
                  0x00010000, TRUE, TRUE)
233
 
234
        /* Multiply one small negative number and one small positive number.
235
           Should set the overflow, but not the carry flag. */
236
        TEST_MUL (l.mul, 0x00000002, 0xfffffffd,
237
                  0xfffffffa, TRUE, FALSE)
238
 
239
        /* Multiply one quite large negative number and one quite large
240
           positive number. Should set the overflow, but not the carry flag. */
241
        TEST_MUL (l.mul, 0xffff8000, 0x00010000,
242
                  0x80000000, TRUE, FALSE)
243
 
244
        /* Multiply one slightly too large negative number and one slightly
245
           too large positive number. Should set both the carry and overflow
246
           flags. */
247
        TEST_MUL (l.mul, 0xffff7fff, 0x00010000,
248
                  0x7fff0000, TRUE, TRUE)
249
 
250
        /* Multiply the largest negative number by positive unity. Should set
251
           neither carry, nor overflow flag. */
252
        TEST_MUL (l.mul, 0x80000000, 0x00000001,
253
                  0x80000000, FALSE, FALSE)
254
 
255
        /* Check that range exceptions are triggered */
256
        l.mfspr r3,r0,SPR_SR
257
        LOAD_CONST (r2, SPR_SR_OVE)     /* Set OVE */
258
        l.or    r3,r3,r2
259
        l.mtspr r0,r3,SPR_SR
260
 
261
        LOAD_STR (r3, "  ** OVE flag set **\n")
262
        l.jal   _puts
263
        l.nop
264
 
265
        /* Check that an overflow alone causes a RANGE Exception. */
266
        TEST_MUL (l.mul, 0x00008000, 0x00010000,
267
                  0x80000000, FALSE, TRUE)
268
 
269
        /* Check that a carry alone does not cause a RANGE Exception. */
270
        TEST_MUL (l.mul, 0x00000002, 0xfffffffd,
271
                  0xfffffffa, TRUE, FALSE)
272
 
273
        /* Check that carry and overflow together cause an exception. */
274
        TEST_MUL (l.mul, 0xffff7fff, 0xffff0000,
275
                  0x80010000, TRUE, TRUE)
276
 
277
        /* Finished checking range exceptions */
278
        l.mfspr r3,r0,SPR_SR
279
        LOAD_CONST (r2, ~SPR_SR_OVE)    /* Clear OVE */
280
        l.and   r3,r3,r2
281
        l.mtspr r0,r3,SPR_SR
282
 
283
        LOAD_STR (r3, "  ** OVE flag cleared **\n")
284
        l.jal   _puts
285
        l.nop
286
 
287
/* ----------------------------------------------------------------------------
288
 * Test of multiply signed, l.muli
289
 * ------------------------------------------------------------------------- */
290
_muli:
291
        LOAD_STR (r3, "l.muli\n")
292
        l.jal   _puts
293
        l.nop
294
 
295
        /* Multiply two small positive numbers. Should set no flags. */
296
        TEST_MULI (0x00000002, 0x0003,
297
                  0x00000006, FALSE, FALSE)
298
 
299
        /* Multiply two quite large positive numbers. Should set no flags */
300
        TEST_MULI (0x00010002, 0x7fff,
301
                  0x7ffffffe, FALSE, FALSE)
302
 
303
        /* Multiply two slightly too large positive numbers. Should set the
304
           overflow, but not the carry flag */
305
        TEST_MULI (0x00020000, 0x4000,
306
                  0x80000000, FALSE, TRUE)
307
 
308
        /* Multiply two large positive numbers. Should set both the carry and
309
           overflow flags (even though the result is not a negative number. */
310
        TEST_MULI (0x00040000, 0x4000,
311
                   0x00000000, TRUE, TRUE)
312
 
313
        /* Multiply two small negative numbers. Should set the overflow, but not
314
           the carry flag. */
315
        TEST_MULI (0xfffffffe, 0xfffd,
316
                  0x00000006, TRUE, FALSE)
317
 
318
        /* Multiply two quite large negative numbers. Should set the overflow,
319
           but not the carry flag. */
320
        TEST_MULI (0xfffefffe, 0x8001,
321
                  0x7ffffffe, TRUE, FALSE)
322
 
323
        /* Multiply two slightly too large negative numbers. Should set both the
324
           overflow, and the carry flags */
325
        TEST_MULI (0xfffe0000, 0xbfff,
326
                  0x80020000, TRUE, TRUE)
327
 
328
        /* Multiply two large negative numbers. Should set the
329
           both the carry and overflow flags (even though the result is a
330
           positive number. */
331
        TEST_MULI (0xfffdfffe, 0x8000,
332
                  0x00010000, TRUE, TRUE)
333
 
334
        /* Multiply one small negative number and one small positive number.
335
           Should set the overflow, but not the carry flag. */
336
        TEST_MULI (0x00000002, 0xfffd,
337
                  0xfffffffa, TRUE, FALSE)
338
 
339
        /* Multiply one quite large negative number and one quite large
340
           positive number. Should set the overflow, but not the carry flag. */
341
        TEST_MULI (0x00010000, 0x8000,
342
                  0x80000000, TRUE, FALSE)
343
 
344
        /* Multiply one slightly too large negative number and one slightly
345
           too large positive number. Should set both the carry and overflow
346
           flags. */
347
        TEST_MULI (0xfffdfffc, 0x4000,
348
                  0x7fff0000, TRUE, TRUE)
349
 
350
        /* Multiply the largest negative number by positive unity. Should set
351
           neither carry, nor overflow flag. */
352
        TEST_MULI (0x80000000, 0x0001,
353
                  0x80000000, FALSE, FALSE)
354
 
355
        /* Check that range exceptions are triggered */
356
        l.mfspr r3,r0,SPR_SR
357
        LOAD_CONST (r2, SPR_SR_OVE)     /* Set OVE */
358
        l.or    r3,r3,r2
359
        l.mtspr r0,r3,SPR_SR
360
 
361
        LOAD_STR (r3, "  ** OVE flag set **\n")
362
        l.jal   _puts
363
        l.nop
364
 
365
        /* Check that an overflow alone causes a RANGE Exception. */
366
        TEST_MULI (0x00020000, 0x4000,
367
                  0x80000000, FALSE, TRUE)
368
 
369
        /* Check that a carry alone does not cause a RANGE Exception. */
370
        TEST_MULI (0xfffffffe, 0xfffd,
371
                  0x00000006, TRUE, FALSE)
372
 
373
        /* Check that carry and overflow together cause an exception. */
374
        TEST_MULI (0xfffdfffe, 0x8000,
375
                  0x00010000, TRUE, TRUE)
376
 
377
        /* Finished checking range exceptions */
378
        l.mfspr r3,r0,SPR_SR
379
        LOAD_CONST (r2, ~SPR_SR_OVE)    /* Clear OVE */
380
        l.and   r3,r3,r2
381
        l.mtspr r0,r3,SPR_SR
382
 
383
        LOAD_STR (r3, "  ** OVE flag cleared **\n")
384
        l.jal   _puts
385
        l.nop
386
 
387
/* ----------------------------------------------------------------------------
388
 * Test of multiply unsigned, l.mulu
389
 * ------------------------------------------------------------------------- */
390
_mulu:
391
        LOAD_STR (r3, "l.mulu\n")
392
        l.jal   _puts
393
        l.nop
394
 
395
        /* Multiply two small positive numbers. Should set no flags. */
396
        TEST_MUL (l.mulu, 0x00000002, 0x00000003,
397
                  0x00000006, FALSE, FALSE)
398
 
399
        /* Multiply two quite large positive numbers. Should set no flags */
400
        TEST_MUL (l.mulu, 0x00008001, 0x0000fffe,
401
                  0x7ffffffe, FALSE, FALSE)
402
 
403
        /* Multiply two slightly too large positive numbers. Should set the
404
           overflow, but not the carry flag */
405
        TEST_MUL (l.mulu, 0x00008000, 0x00010000,
406
                  0x80000000, FALSE, FALSE)
407
 
408
        /* Multiply two large positive numbers. Should set both the carry and
409
           overflow flags (even though the result is not a negative number. */
410
        TEST_MUL (l.mulu, 0x00010000, 0x00010000,
411
                  0x00000000, TRUE, FALSE)
412
 
413
        /* Multiply two small negative numbers. Should set the overflow, but not
414
           the carry flag. */
415
        TEST_MUL (l.mulu, 0xfffffffe, 0xfffffffd,
416
                  0x00000006, TRUE, FALSE)
417
 
418
        /* Multiply two quite large negative numbers. Should set the overflow,
419
           but not the carry flag. */
420
        TEST_MUL (l.mulu, 0xffff7fff, 0xffff0002,
421
                  0x7ffffffe, TRUE, FALSE)
422
 
423
        /* Multiply two slightly too large negative numbers. Should set both the
424
           overflow, and the carry flags */
425
        TEST_MUL (l.mulu, 0xffff7fff, 0xffff0000,
426
                  0x80010000, TRUE, FALSE)
427
 
428
        /* Multiply two large negative numbers. Should set the
429
           both the carry and overflow flags (even though the result is a
430
           positive number. */
431
        TEST_MUL (l.mulu, 0xffff0000, 0xfffeffff,
432
                  0x00010000, TRUE, FALSE)
433
 
434
        /* Multiply one small negative number and one small positive number.
435
           Should set the overflow, but not the carry flag. */
436
        TEST_MUL (l.mulu, 0x00000002, 0xfffffffd,
437
                  0xfffffffa, TRUE, FALSE)
438
 
439
        /* Multiply one quite large negative number and one quite large
440
           positive number. Should set the overflow, but not the carry flag. */
441
        TEST_MUL (l.mulu, 0xffff8000, 0x00010000,
442
                  0x80000000, TRUE, FALSE)
443
 
444
        /* Multiply one slightly too large negative number and one slightly
445
           too large positive number. Should set both the carry and overflow
446
           flags. */
447
        TEST_MUL (l.mulu, 0xffff7fff, 0x00010000,
448
                  0x7fff0000, TRUE, FALSE)
449
 
450
        /* Multiply the largest negative number by positive unity. Should set
451
           neither carry, nor overflow flag. */
452
        TEST_MUL (l.mulu, 0x80000000, 0x00000001,
453
                  0x80000000, FALSE, FALSE)
454
 
455
        /* Check that range exceptions are never triggered */
456
        l.mfspr r3,r0,SPR_SR
457
        LOAD_CONST (r2, SPR_SR_OVE)     /* Set OVE */
458
        l.or    r3,r3,r2
459
        l.mtspr r0,r3,SPR_SR
460
 
461
        LOAD_STR (r3, "  ** OVE flag set **\n")
462
        l.jal   _puts
463
        l.nop
464
 
465
        /* Check that what would cause an overflow alone in 2's complement does
466
           not cause a RANGE Exception. */
467
        TEST_MUL (l.mulu, 0x00008000, 0x00010000,
468
                  0x80000000, FALSE, FALSE)
469
 
470
        /* Check that a carry alone does not cause a RANGE Exception. */
471
        TEST_MUL (l.mulu, 0x00000002, 0xfffffffd,
472
                  0xfffffffa, TRUE, FALSE)
473
 
474
        /* Check that what would cause an overflow and carry in 2's complement
475
           does not cause a RANGE Exception. */
476
        TEST_MUL (l.mulu, 0xffff7fff, 0xffff0000,
477
                  0x80010000, TRUE, FALSE)
478
 
479
        /* Finished checking range exceptions */
480
        l.mfspr r3,r0,SPR_SR
481
        LOAD_CONST (r2, ~SPR_SR_OVE)    /* Clear OVE */
482
        l.and   r3,r3,r2
483
        l.mtspr r0,r3,SPR_SR
484
 
485
        LOAD_STR (r3, "  ** OVE flag cleared **\n")
486
        l.jal   _puts
487
        l.nop
488
 
489
/* ----------------------------------------------------------------------------
490
 * All done
491
 * ------------------------------------------------------------------------- */
492
_exit:
493
        LOAD_STR (r3, "Test completed\n")
494
        l.jal   _puts
495
        l.nop
496
 
497
        TEST_EXIT

powered by: WebSVN 2.1.0

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