1 /* Tests the multiply instructions.
3 Copyright (C) 2017-2024 Free Software Foundation, Inc.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 # output: report(0x00000002);\n
20 # output: report(0x00000003);\n
21 # output: report(0x00000006);\n
22 # output: report(0x00000000);\n
23 # output: report(0x00000000);\n
24 # output: report(0x00000000);\n
26 # output: report(0x00008001);\n
27 # output: report(0x0000fffe);\n
28 # output: report(0x7ffffffe);\n
29 # output: report(0x00000000);\n
30 # output: report(0x00000000);\n
31 # output: report(0x00000000);\n
33 # output: report(0x00008000);\n
34 # output: report(0x00010000);\n
35 # output: report(0x80000000);\n
36 # output: report(0x00000000);\n
37 # output: report(0x00000001);\n
38 # output: report(0x00000000);\n
40 # output: report(0x00010000);\n
41 # output: report(0x00010000);\n
42 # output: report(0x00000000);\n
43 # output: report(0x00000000);\n
44 # output: report(0x00000001);\n
45 # output: report(0x00000000);\n
47 # output: report(0xfffffffe);\n
48 # output: report(0xfffffffd);\n
49 # output: report(0x00000006);\n
50 # output: report(0x00000000);\n
51 # output: report(0x00000000);\n
52 # output: report(0x00000000);\n
54 # output: report(0xffff7fff);\n
55 # output: report(0xffff0002);\n
56 # output: report(0x7ffffffe);\n
57 # output: report(0x00000000);\n
58 # output: report(0x00000000);\n
59 # output: report(0x00000000);\n
61 # output: report(0xffff7fff);\n
62 # output: report(0xffff0000);\n
63 # output: report(0x80010000);\n
64 # output: report(0x00000000);\n
65 # output: report(0x00000001);\n
66 # output: report(0x00000000);\n
68 # output: report(0xffff0000);\n
69 # output: report(0xfffeffff);\n
70 # output: report(0x00010000);\n
71 # output: report(0x00000000);\n
72 # output: report(0x00000001);\n
73 # output: report(0x00000000);\n
75 # output: report(0x00000002);\n
76 # output: report(0xfffffffd);\n
77 # output: report(0xfffffffa);\n
78 # output: report(0x00000000);\n
79 # output: report(0x00000000);\n
80 # output: report(0x00000000);\n
82 # output: report(0xffff8000);\n
83 # output: report(0x00010000);\n
84 # output: report(0x80000000);\n
85 # output: report(0x00000000);\n
86 # output: report(0x00000000);\n
87 # output: report(0x00000000);\n
89 # output: report(0xffff7fff);\n
90 # output: report(0x00010000);\n
91 # output: report(0x7fff0000);\n
92 # output: report(0x00000000);\n
93 # output: report(0x00000001);\n
94 # output: report(0x00000000);\n
96 # output: report(0x80000000);\n
97 # output: report(0x00000001);\n
98 # output: report(0x80000000);\n
99 # output: report(0x00000000);\n
100 # output: report(0x00000000);\n
101 # output: report(0x00000000);\n
103 # output: report(0x00008000);\n
104 # output: report(0x00010000);\n
105 # output: report(0x80000000);\n
106 # output: report(0x00000000);\n
107 # output: report(0x00000001);\n
108 # output: report(0x00000001);\n
110 # output: report(0x00000002);\n
111 # output: report(0xfffffffd);\n
112 # output: report(0xfffffffa);\n
113 # output: report(0x00000000);\n
114 # output: report(0x00000000);\n
115 # output: report(0x00000000);\n
117 # output: report(0xffff7fff);\n
118 # output: report(0xffff0000);\n
119 # output: report(0x80010000);\n
120 # output: report(0x00000000);\n
121 # output: report(0x00000001);\n
122 # output: report(0x00000001);\n
124 # output: report(0x00000002);\n
125 # output: report(0x00000003);\n
126 # output: report(0x00000006);\n
127 # output: report(0x00000000);\n
128 # output: report(0x00000000);\n
129 # output: report(0x00000000);\n
131 # output: report(0x00010002);\n
132 # output: report(0x00007fff);\n
133 # output: report(0x7ffffffe);\n
134 # output: report(0x00000000);\n
135 # output: report(0x00000000);\n
136 # output: report(0x00000000);\n
138 # output: report(0x00020000);\n
139 # output: report(0x00004000);\n
140 # output: report(0x80000000);\n
141 # output: report(0x00000000);\n
142 # output: report(0x00000001);\n
143 # output: report(0x00000000);\n
145 # output: report(0x00040000);\n
146 # output: report(0x00004000);\n
147 # output: report(0x00000000);\n
148 # output: report(0x00000000);\n
149 # output: report(0x00000001);\n
150 # output: report(0x00000000);\n
152 # output: report(0xfffffffe);\n
153 # output: report(0x0000fffd);\n
154 # output: report(0x00000006);\n
155 # output: report(0x00000000);\n
156 # output: report(0x00000000);\n
157 # output: report(0x00000000);\n
159 # output: report(0xfffefffe);\n
160 # output: report(0x00008001);\n
161 # output: report(0x7ffffffe);\n
162 # output: report(0x00000000);\n
163 # output: report(0x00000000);\n
164 # output: report(0x00000000);\n
166 # output: report(0xfffe0000);\n
167 # output: report(0x0000bfff);\n
168 # output: report(0x80020000);\n
169 # output: report(0x00000000);\n
170 # output: report(0x00000001);\n
171 # output: report(0x00000000);\n
173 # output: report(0xfffdfffe);\n
174 # output: report(0x00008000);\n
175 # output: report(0x00010000);\n
176 # output: report(0x00000000);\n
177 # output: report(0x00000001);\n
178 # output: report(0x00000000);\n
180 # output: report(0x00000002);\n
181 # output: report(0x0000fffd);\n
182 # output: report(0xfffffffa);\n
183 # output: report(0x00000000);\n
184 # output: report(0x00000000);\n
185 # output: report(0x00000000);\n
187 # output: report(0x00010000);\n
188 # output: report(0x00008000);\n
189 # output: report(0x80000000);\n
190 # output: report(0x00000000);\n
191 # output: report(0x00000000);\n
192 # output: report(0x00000000);\n
194 # output: report(0xfffdfffc);\n
195 # output: report(0x00004000);\n
196 # output: report(0x7fff0000);\n
197 # output: report(0x00000000);\n
198 # output: report(0x00000001);\n
199 # output: report(0x00000000);\n
201 # output: report(0x80000000);\n
202 # output: report(0x00000001);\n
203 # output: report(0x80000000);\n
204 # output: report(0x00000000);\n
205 # output: report(0x00000000);\n
206 # output: report(0x00000000);\n
208 # output: report(0x00020000);\n
209 # output: report(0x00004000);\n
210 # output: report(0x80000000);\n
211 # output: report(0x00000000);\n
212 # output: report(0x00000001);\n
213 # output: report(0x00000001);\n
215 # output: report(0xfffffffe);\n
216 # output: report(0x0000fffd);\n
217 # output: report(0x00000006);\n
218 # output: report(0x00000000);\n
219 # output: report(0x00000000);\n
220 # output: report(0x00000000);\n
222 # output: report(0xfffdfffe);\n
223 # output: report(0x00008000);\n
224 # output: report(0x00010000);\n
225 # output: report(0x00000000);\n
226 # output: report(0x00000001);\n
227 # output: report(0x00000001);\n
229 # output: report(0x00000002);\n
230 # output: report(0x00000003);\n
231 # output: report(0x00000006);\n
232 # output: report(0x00000000);\n
233 # output: report(0x00000000);\n
234 # output: report(0x00000000);\n
236 # output: report(0x00008001);\n
237 # output: report(0x0000fffe);\n
238 # output: report(0x7ffffffe);\n
239 # output: report(0x00000000);\n
240 # output: report(0x00000000);\n
241 # output: report(0x00000000);\n
243 # output: report(0x00008000);\n
244 # output: report(0x00010000);\n
245 # output: report(0x80000000);\n
246 # output: report(0x00000000);\n
247 # output: report(0x00000000);\n
248 # output: report(0x00000000);\n
250 # output: report(0x00010000);\n
251 # output: report(0x00010000);\n
252 # output: report(0x00000000);\n
253 # output: report(0x00000001);\n
254 # output: report(0x00000000);\n
255 # output: report(0x00000000);\n
257 # output: report(0xfffffffe);\n
258 # output: report(0xfffffffd);\n
259 # output: report(0x00000006);\n
260 # output: report(0x00000001);\n
261 # output: report(0x00000000);\n
262 # output: report(0x00000000);\n
264 # output: report(0xffff7fff);\n
265 # output: report(0xffff0002);\n
266 # output: report(0x7ffffffe);\n
267 # output: report(0x00000001);\n
268 # output: report(0x00000000);\n
269 # output: report(0x00000000);\n
271 # output: report(0xffff7fff);\n
272 # output: report(0xffff0000);\n
273 # output: report(0x80010000);\n
274 # output: report(0x00000001);\n
275 # output: report(0x00000000);\n
276 # output: report(0x00000000);\n
278 # output: report(0xffff0000);\n
279 # output: report(0xfffeffff);\n
280 # output: report(0x00010000);\n
281 # output: report(0x00000001);\n
282 # output: report(0x00000000);\n
283 # output: report(0x00000000);\n
285 # output: report(0x00000002);\n
286 # output: report(0xfffffffd);\n
287 # output: report(0xfffffffa);\n
288 # output: report(0x00000001);\n
289 # output: report(0x00000000);\n
290 # output: report(0x00000000);\n
292 # output: report(0xffff8000);\n
293 # output: report(0x00010000);\n
294 # output: report(0x80000000);\n
295 # output: report(0x00000001);\n
296 # output: report(0x00000000);\n
297 # output: report(0x00000000);\n
299 # output: report(0xffff7fff);\n
300 # output: report(0x00010000);\n
301 # output: report(0x7fff0000);\n
302 # output: report(0x00000001);\n
303 # output: report(0x00000000);\n
304 # output: report(0x00000000);\n
306 # output: report(0x80000000);\n
307 # output: report(0x00000001);\n
308 # output: report(0x80000000);\n
309 # output: report(0x00000000);\n
310 # output: report(0x00000000);\n
311 # output: report(0x00000000);\n
313 # output: report(0x00008000);\n
314 # output: report(0x00010000);\n
315 # output: report(0x80000000);\n
316 # output: report(0x00000000);\n
317 # output: report(0x00000000);\n
318 # output: report(0x00000000);\n
320 # output: report(0x00000002);\n
321 # output: report(0xfffffffd);\n
322 # output: report(0xfffffffa);\n
323 # output: report(0x00000001);\n
324 # output: report(0x00000000);\n
325 # output: report(0x00000001);\n
327 # output: report(0xffff7fff);\n
328 # output: report(0xffff0000);\n
329 # output: report(0x80010000);\n
330 # output: report(0x00000001);\n
331 # output: report(0x00000000);\n
332 # output: report(0x00000001);\n
336 #include "or1k-asm-test-helpers.h"
338 STANDARD_TEST_ENVIRONMENT
340 .section .exception_vectors
342 /* Range exception. */
345 /* The handling is a bit dubious at present. We just patch the
346 instruction with l.nop and restart. This will go wrong in branch
347 delay slots, but we are not testing that here. */
348 l.addi r1, r1, -EXCEPTION_STACK_SKIP_SIZE
351 /* Save the address of the instruction that caused the problem. */
352 MOVE_FROM_SPR r2, SPR_EPCR_BASE
353 LOAD_IMMEDIATE r3, 0x15000000 /* Opcode for l.nop */
357 l.addi r1, r1, EXCEPTION_STACK_SKIP_SIZE
362 PUSH LINK_REGISTER_R9
366 /* Multiply two small positive numbers. This should set no flags.
368 TEST_INST_I32_I32 l.mul, 0x00000002, 0x00000003
370 /* Multiply two quite large positive numbers. This should set no
372 TEST_INST_I32_I32 l.mul, 0x00008001, 0x0000fffe
374 /* Multiply two slightly too large positive numbers. This should
375 set the overflow, but not the carry flag . */
376 TEST_INST_I32_I32 l.mul, 0x00008000, 0x00010000
378 /* Multiply two large positive numbers. This should set the
379 overflow flags (even though the result is not a negative
381 TEST_INST_I32_I32 l.mul, 0x00010000, 0x00010000
383 /* Multiply two small negative numbers. This will set no flags. */
384 TEST_INST_I32_I32 l.mul, 0xfffffffe, 0xfffffffd
386 /* Multiply two quite large negative numbers. This will no flags. */
387 TEST_INST_I32_I32 l.mul, 0xffff7fff, 0xffff0002
389 /* Multiply two slightly too large negative numbers. This should
390 set the overflow flag. */
391 TEST_INST_I32_I32 l.mul, 0xffff7fff, 0xffff0000
393 /* Multiply two large negative numbers. This should set the
394 both the carry and overflow flags (even though the result is a
396 TEST_INST_I32_I32 l.mul, 0xffff0000, 0xfffeffff
398 /* Multiply one small negative number and one small positive
399 number. This will set the no flags. */
400 TEST_INST_I32_I32 l.mul, 0x00000002, 0xfffffffd
402 /* Multiply one quite large negative number and one quite large
403 positive number. This will set no flags. */
404 TEST_INST_I32_I32 l.mul, 0xffff8000, 0x00010000
406 /* Multiply one slightly too large negative number and one slightly
407 too large positive number. This should set the overflow flag. */
408 TEST_INST_I32_I32 l.mul, 0xffff7fff, 0x00010000
410 /* Multiply the largest negative number by positive unity. This
411 should set neither carry, nor overflow flag. */
412 TEST_INST_I32_I32 l.mul, 0x80000000, 0x00000001
414 /* Check that range exceptions are triggered. */
416 SET_SPR_SR_FLAGS SPR_SR_OVE, r2, r3
418 /* Check that an overflow alone causes a RANGE Exception. */
419 TEST_INST_I32_I32 l.mul, 0x00008000, 0x00010000
421 /* Check multiply of a negative and positive does not cause a RANGE
423 TEST_INST_I32_I32 l.mul, 0x00000002, 0xfffffffd
425 /* Check that negative overflow causes a RANGE exception. */
426 TEST_INST_I32_I32 l.mul, 0xffff7fff, 0xffff0000
428 CLEAR_SPR_SR_FLAGS SPR_SR_OVE, r2, r3
433 /* Multiply two small positive numbers. This should set no flags. */
434 TEST_INST_I32_I16 l.muli, 0x00000002, 0x0003
436 /* Multiply two quite large positive numbers. This should set no
438 TEST_INST_I32_I16 l.muli, 0x00010002, 0x7fff
440 /* Multiply two slightly too large positive numbers. This should
441 set the overflow, but not the carry flag. */
442 TEST_INST_I32_I16 l.muli, 0x00020000, 0x4000
444 /* Multiply two large positive numbers. This should set the
445 overflow flag, even though the result is not a negative number. */
446 TEST_INST_I32_I16 l.muli, 0x00040000, 0x4000
448 /* Multiply two small negative numbers. This should set no flags. */
449 TEST_INST_I32_I16 l.muli, 0xfffffffe, 0xfffd
451 /* Multiply two quite large negative numbers. This will set no
453 TEST_INST_I32_I16 l.muli, 0xfffefffe, 0x8001
455 /* Multiply two slightly too large negative numbers. This should
456 set the overflow flag. */
457 TEST_INST_I32_I16 l.muli, 0xfffe0000, 0xbfff
459 /* Multiply two large negative numbers. This should set the
460 overflow flag, even though the result is a positive number. */
461 TEST_INST_I32_I16 l.muli, 0xfffdfffe, 0x8000
463 /* Multiply one small negative number and one small positive
464 number. This will set no flags. */
465 TEST_INST_I32_I16 l.muli, 0x00000002, 0xfffd
467 /* Multiply one quite large negative number and one quite large
468 positive number. This will set no flags. */
469 TEST_INST_I32_I16 l.muli, 0x00010000, 0x8000
471 /* Multiply one slightly too large negative number and one slightly
472 too large positive number. This will set the overflow flag. */
473 TEST_INST_I32_I16 l.muli, 0xfffdfffc, 0x4000
475 /* Multiply the largest negative number by positive unity. Should
476 set neither carry, nor overflow flag. */
477 TEST_INST_I32_I16 l.muli, 0x80000000, 0x0001
479 /* Check that range exceptions are triggered. */
481 SET_SPR_SR_FLAGS SPR_SR_OVE, r2, r3
483 /* Check that an overflow alone causes a RANGE Exception. */
484 TEST_INST_I32_I16 l.muli, 0x00020000, 0x4000
486 /* Check that two negatives will not cause a RANGE Exception. */
487 TEST_INST_I32_I16 l.muli, 0xfffffffe, 0xfffd
489 /* Check that multiply of larget negative and positive numbers causes
490 a RANGE exception and overflow. */
491 TEST_INST_I32_I16 l.muli, 0xfffdfffe, 0x8000
493 CLEAR_SPR_SR_FLAGS SPR_SR_OVE, r2, r3
497 /* Multiply two small positive numbers. This should set no flags. */
498 TEST_INST_I32_I32 l.mulu, 0x00000002, 0x00000003
500 /* Multiply two quite large positive numbers. This should set no
502 TEST_INST_I32_I32 l.mulu, 0x00008001, 0x0000fffe
504 /* Multiply two slightly too large positive numbers. This will set
506 TEST_INST_I32_I32 l.mulu, 0x00008000, 0x00010000
508 /* Multiply two large positive numbers. This will set the overflow
510 TEST_INST_I32_I32 l.mulu, 0x00010000, 0x00010000
512 /* Multiply two small negative numbers. This will set the
513 carry flag, but not the overflow flag. */
514 TEST_INST_I32_I32 l.mulu, 0xfffffffe, 0xfffffffd
516 /* Multiply two quite large negative numbers. This will set the
517 carry flag, but not the overflow flag. */
518 TEST_INST_I32_I32 l.mulu, 0xffff7fff, 0xffff0002
520 /* Multiply two slightly too large negative numbers. This will set
521 the carry flag, and not the overflow flag */
522 TEST_INST_I32_I32 l.mulu, 0xffff7fff, 0xffff0000
524 /* Multiply two large negative numbers. This will set the both the
525 carry flag (even though the result is a positive number.) */
526 TEST_INST_I32_I32 l.mulu, 0xffff0000, 0xfffeffff
528 /* Multiply one small negative number and one small positive
529 number. This will set the carry flag, but not the overflow
531 TEST_INST_I32_I32 l.mulu, 0x00000002, 0xfffffffd
533 /* Multiply one quite large negative number and one quite large
534 positive number. This will set the carry flag, but not the
536 TEST_INST_I32_I32 l.mulu, 0xffff8000, 0x00010000
538 /* Multiply one slightly too large negative number and one slightly
539 too large positive number. This will set the carry flag, but
540 not the overflow flag. */
541 TEST_INST_I32_I32 l.mulu, 0xffff7fff, 0x00010000
543 /* Multiply the largest negative number by positive unity. Should
544 set neither carry, nor overflow flag. */
545 TEST_INST_I32_I32 l.mulu, 0x80000000, 0x00000001
547 /* Check that range exceptions are never triggered. */
549 SET_SPR_SR_FLAGS SPR_SR_OVE, r2, r3
551 /* Check that what would cause an overflow alone in 2's complement
552 does not cause a RANGE Exception. */
553 TEST_INST_I32_I32 l.mulu, 0x00008000, 0x00010000
555 /* Check that a carry causes a RANGE Exception. */
556 TEST_INST_I32_I32 l.mulu, 0x00000002, 0xfffffffd
558 /* Check that what would cause an overflow and carry in 2's
559 complement causes a RANGE Exception. */
560 TEST_INST_I32_I32 l.mulu, 0xffff7fff, 0xffff0000
562 CLEAR_SPR_SR_FLAGS SPR_SR_OVE, r2, r3
565 RETURN_TO_LINK_REGISTER_R9