1/* Tests some basic fpu 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(0x00007ab7);\n
20# output: report(0xffffd8f0);\n
21# output: report(0x46f56e00);\n
22# output: report(0xc61c4000);\n
23# output: report(0x00007ab7);\n
24# output: report(0xffffd8f0);\n
25# output: \n
26# output: report(0xc0490e56);\n
27# output: report(0xfffffffd);\n
28# output: \n
29# output: report(0x4e6b4bbb);\n
30# output: \n
31# output: report(0xbdc0be40);\n
32# output: \n
33# output: report(0x00000001);\n
34# output: \n
35# output: WARNING: ignoring fpu error caught in fast mode.\n
36# output: report(0x00000000);\n
37# output: \n
38# output: exit(0)\n
39
40#include "or1k-asm-test-helpers.h"
41
42	STANDARD_TEST_ENVIRONMENT
43
44	.section .exception_vectors
45
46	/* Floating point exception.  */
47	.org	0xd00
48
49	/* The handling is a bit dubious at present.  We just patch the
50	   instruction with l.nop and restart.  This will go wrong in branch
51	   delay slots.  But we don't have those in this test.  */
52	l.addi r1, r1, -EXCEPTION_STACK_SKIP_SIZE
53	PUSH r2
54	PUSH r3
55	/* Save the address of the instruction that caused the problem.  */
56	MOVE_FROM_SPR r2, SPR_EPCR_BASE
57	LOAD_IMMEDIATE r3, 0x15000000 /* Opcode for l.nop  */
58	l.sw	-4(r2), r3
59	POP r3
60	POP r2
61	l.addi r1, r1, EXCEPTION_STACK_SKIP_SIZE
62	l.rfe
63
64	.section .text
65start_tests:
66	PUSH LINK_REGISTER_R9
67
68	/* Test lf.itof.s int to float conversion.  Setting up:
69	 *  r10  31415.0f
70	 *  r12	-10000.0f
71	 */
72	l.ori	r11, r0, 31415
73	l.ori	r13, r0, -10000
74	l.movhi	r15, 0xffff
75	l.or	r13, r13, r15
76
77	REPORT_REG_TO_CONSOLE r11
78	REPORT_REG_TO_CONSOLE r13
79	lf.itof.s r10, r11
80	lf.itof.s r12, r13
81	REPORT_REG_TO_CONSOLE r10
82	REPORT_REG_TO_CONSOLE r12
83
84	/* Test lf.ftoi.s float to int conversion.  */
85	lf.ftoi.s r11, r10
86	lf.ftoi.s r13, r12
87	REPORT_REG_TO_CONSOLE r11
88	REPORT_REG_TO_CONSOLE r13
89	PRINT_NEWLINE_TO_CONSOLE
90
91	/* Test lf.div.s divide 31415 by -1000 to get -pi.  Setting up:
92	 *  r8	-3.1415f
93	 */
94	lf.div.s r8, r10, r12
95	REPORT_REG_TO_CONSOLE r8
96
97	lf.ftoi.s r11, r8
98	REPORT_REG_TO_CONSOLE r11
99	PRINT_NEWLINE_TO_CONSOLE
100
101	/* Test lf.mul.s multiply -pi x -10000 x 31415.  Setting up:
102	 *  r6	 986902225
103	 */
104	lf.mul.s r6, r8, r12
105	lf.mul.s r6, r6, r10
106	REPORT_REG_TO_CONSOLE r6
107	PRINT_NEWLINE_TO_CONSOLE
108
109	/* Test lf.rem.s remainder of 986902225 / -pi.  */
110	lf.rem.s r2, r6, r8
111	REPORT_REG_TO_CONSOLE r2
112	PRINT_NEWLINE_TO_CONSOLE
113
114	/* Test lf.sfge.s set flag if r6 >= r10.  */
115	lf.sfge.s r6, r10
116	MOVE_FROM_SPR r2, SPR_SR
117	REPORT_BIT_TO_CONSOLE r2, SPR_SR_F
118	PRINT_NEWLINE_TO_CONSOLE
119
120	/* Test raising an exception by dividing by 0.  */
121	MOVE_FROM_SPR r2, SPR_FPCSR
122	l.ori	r2, r2, 0x1
123	MOVE_TO_SPR SPR_FPCSR, r2
124div0:	lf.div.s r2, r8, r0
125	REPORT_EXCEPTION div0
126	PRINT_NEWLINE_TO_CONSOLE
127
128	POP LINK_REGISTER_R9
129	RETURN_TO_LINK_REGISTER_R9
130