1/* Tests the multiply instructions.
2
3   Copyright (C) 2017-2023 Free Software Foundation, Inc.
4
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.
9
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.
14
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/>.  */
17
18# mach: or1k
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
25# output: \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
32# output: \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
39# output: \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
46# output: \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
53# output: \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
60# output: \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
67# output: \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
74# output: \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
81# output: \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
88# output: \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
95# output: \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
102# output: \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
109# output: \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
116# output: \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
123# output: \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
130# output: \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
137# output: \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
144# output: \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
151# output: \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
158# output: \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
165# output: \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
172# output: \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
179# output: \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
186# output: \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
193# output: \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
200# output: \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
207# output: \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
214# output: \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
221# output: \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
228# output: \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
235# output: \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
242# output: \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
249# output: \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
256# output: \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
263# output: \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
270# output: \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
277# output: \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
284# output: \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
291# output: \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
298# output: \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
305# output: \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
312# output: \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
319# output: \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
326# output: \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
333# output: \n
334# output: exit(0)\n
335
336#include "or1k-asm-test-helpers.h"
337
338	STANDARD_TEST_ENVIRONMENT
339
340	.section .exception_vectors
341
342	/* Range exception.  */
343	.org	0xb00
344
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
349	PUSH r2
350	PUSH r3
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  */
354	l.sw	0(r2), r3
355	POP r3
356	POP r2
357	l.addi r1, r1, EXCEPTION_STACK_SKIP_SIZE
358	l.rfe
359
360	.section .text
361start_tests:
362	PUSH LINK_REGISTER_R9
363
364	/* Test l.mul  */
365
366	/* Multiply two small positive numbers.  This should set no flags.
367	   */
368	TEST_INST_I32_I32 l.mul, 0x00000002, 0x00000003
369
370	/* Multiply two quite large positive numbers.  This should set no
371	   flags  */
372	TEST_INST_I32_I32 l.mul, 0x00008001, 0x0000fffe
373
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
377
378	/* Multiply two large positive numbers.  This should set the
379	   overflow flags (even though the result is not a negative
380	   number.  */
381	TEST_INST_I32_I32 l.mul, 0x00010000, 0x00010000
382
383	/* Multiply two small negative numbers.  This will set no flags.  */
384	TEST_INST_I32_I32 l.mul, 0xfffffffe, 0xfffffffd
385
386	/* Multiply two quite large negative numbers.  This will no flags.  */
387	TEST_INST_I32_I32 l.mul, 0xffff7fff, 0xffff0002
388
389	/* Multiply two slightly too large negative numbers.  This should
390	   set the overflow flag.  */
391	TEST_INST_I32_I32 l.mul, 0xffff7fff, 0xffff0000
392
393	/* Multiply two large negative numbers.  This should set the
394	   both the carry and overflow flags (even though the result is a
395	   positive number.  */
396	TEST_INST_I32_I32 l.mul, 0xffff0000, 0xfffeffff
397
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
401
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
405
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
409
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
413
414	/* Check that range exceptions are triggered.  */
415
416	SET_SPR_SR_FLAGS SPR_SR_OVE, r2, r3
417
418	/* Check that an overflow alone causes a RANGE Exception.  */
419	TEST_INST_I32_I32 l.mul, 0x00008000, 0x00010000
420
421	/* Check multiply of a negative and positive does not cause a RANGE
422	   Exception.  */
423	TEST_INST_I32_I32 l.mul, 0x00000002, 0xfffffffd
424
425	/* Check that negative overflow causes a RANGE exception.  */
426	TEST_INST_I32_I32 l.mul, 0xffff7fff, 0xffff0000
427
428	CLEAR_SPR_SR_FLAGS SPR_SR_OVE, r2, r3
429
430
431	/* Test l.muli  */
432
433	/* Multiply two small positive numbers.  This should set no flags.  */
434	TEST_INST_I32_I16 l.muli, 0x00000002, 0x0003
435
436	/* Multiply two quite large positive numbers.  This should set no
437	   flags */
438	TEST_INST_I32_I16 l.muli, 0x00010002, 0x7fff
439
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
443
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
447
448	/* Multiply two small negative numbers.  This should set no flags.  */
449	TEST_INST_I32_I16 l.muli, 0xfffffffe, 0xfffd
450
451	/* Multiply two quite large negative numbers.  This will set no
452	   flags.  */
453	TEST_INST_I32_I16 l.muli, 0xfffefffe, 0x8001
454
455	/* Multiply two slightly too large negative numbers.  This should
456	   set the overflow flag.  */
457	TEST_INST_I32_I16 l.muli, 0xfffe0000, 0xbfff
458
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
462
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
466
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
470
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
474
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
478
479	/* Check that range exceptions are triggered.  */
480
481	SET_SPR_SR_FLAGS SPR_SR_OVE, r2, r3
482
483	/* Check that an overflow alone causes a RANGE Exception.  */
484	TEST_INST_I32_I16 l.muli, 0x00020000, 0x4000
485
486	/* Check that two negatives will not cause a RANGE Exception.  */
487	TEST_INST_I32_I16 l.muli, 0xfffffffe, 0xfffd
488
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
492
493	CLEAR_SPR_SR_FLAGS SPR_SR_OVE, r2, r3
494
495	/* Test l.mulu  */
496
497	/* Multiply two small positive numbers.  This should set no flags.  */
498	TEST_INST_I32_I32 l.mulu, 0x00000002, 0x00000003
499
500	/* Multiply two quite large positive numbers.  This should set no
501	   flags.  */
502	TEST_INST_I32_I32 l.mulu, 0x00008001, 0x0000fffe
503
504	/* Multiply two slightly too large positive numbers.  This will set
505	   no flags.  */
506	TEST_INST_I32_I32 l.mulu, 0x00008000, 0x00010000
507
508	/* Multiply two large positive numbers.  This will set the overflow
509	   flag.  */
510	TEST_INST_I32_I32 l.mulu, 0x00010000, 0x00010000
511
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
515
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
519
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
523
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
527
528	/* Multiply one small negative number and one small positive
529	   number.  This will set the carry flag, but not the overflow
530	   flag.  */
531	TEST_INST_I32_I32 l.mulu, 0x00000002, 0xfffffffd
532
533	/* Multiply one quite large negative number and one quite large
534	   positive number.  This will set the carry flag, but not the
535	   overflow flag.  */
536	TEST_INST_I32_I32 l.mulu, 0xffff8000, 0x00010000
537
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
542
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
546
547	/* Check that range exceptions are never triggered.  */
548
549	SET_SPR_SR_FLAGS SPR_SR_OVE, r2, r3
550
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
554
555	/* Check that a carry causes a RANGE Exception.  */
556	TEST_INST_I32_I32 l.mulu, 0x00000002, 0xfffffffd
557
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
561
562	CLEAR_SPR_SR_FLAGS SPR_SR_OVE, r2, r3
563
564	POP LINK_REGISTER_R9
565	RETURN_TO_LINK_REGISTER_R9
566