sub.S revision 1.1.1.1
1/* Tests instruction l.sub.
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(0x00000003);\n
20# output: report(0x00000002);\n
21# output: report(0x00000001);\n
22# output: report(0x00000000);\n
23# output: report(0x00000000);\n
24# output: report(0x00000000);\n
25# output: \n
26# output: report(0x00000001);\n
27# output: report(0x00000002);\n
28# output: report(0xffffffff);\n
29# output: report(0x00000001);\n
30# output: report(0x00000000);\n
31# output: report(0x00000000);\n
32# output: \n
33# output: report(0x00000003);\n
34# output: report(0x00000002);\n
35# output: report(0x00000001);\n
36# output: report(0x00000000);\n
37# output: report(0x00000000);\n
38# output: report(0x00000000);\n
39# output: \n
40# output: report(0xfffffffd);\n
41# output: report(0xfffffffe);\n
42# output: report(0xffffffff);\n
43# output: report(0x00000001);\n
44# output: report(0x00000000);\n
45# output: report(0x00000000);\n
46# output: \n
47# output: report(0xffffffff);\n
48# output: report(0xfffffffe);\n
49# output: report(0x00000001);\n
50# output: report(0x00000000);\n
51# output: report(0x00000000);\n
52# output: report(0x00000000);\n
53# output: \n
54# output: report(0x7fffffff);\n
55# output: report(0x3fffffff);\n
56# output: report(0x40000000);\n
57# output: report(0x00000000);\n
58# output: report(0x00000000);\n
59# output: report(0x00000000);\n
60# output: \n
61# output: report(0x40000000);\n
62# output: report(0x40000000);\n
63# output: report(0x00000000);\n
64# output: report(0x00000000);\n
65# output: report(0x00000000);\n
66# output: report(0x00000000);\n
67# output: \n
68# output: report(0x3fffffff);\n
69# output: report(0x40000000);\n
70# output: report(0xffffffff);\n
71# output: report(0x00000001);\n
72# output: report(0x00000000);\n
73# output: report(0x00000000);\n
74# output: \n
75# output: report(0x40000000);\n
76# output: report(0x3fffffff);\n
77# output: report(0x00000001);\n
78# output: report(0x00000000);\n
79# output: report(0x00000000);\n
80# output: report(0x00000000);\n
81# output: \n
82# output: report(0x80000000);\n
83# output: report(0x7fffffff);\n
84# output: report(0x00000001);\n
85# output: report(0x00000000);\n
86# output: report(0x00000001);\n
87# output: report(0x00000000);\n
88# output: \n
89# output: report(0x7fffffff);\n
90# output: report(0x80000000);\n
91# output: report(0xffffffff);\n
92# output: report(0x00000001);\n
93# output: report(0x00000001);\n
94# output: report(0x00000000);\n
95# output: \n
96# output: report(0x80000000);\n
97# output: report(0x7fffffff);\n
98# output: report(0x00000001);\n
99# output: report(0x00000000);\n
100# output: report(0x00000001);\n
101# output: report(0x00000001);\n
102# output: \n
103# output: report(0x3fffffff);\n
104# output: report(0x40000000);\n
105# output: report(0xffffffff);\n
106# output: report(0x00000001);\n
107# output: report(0x00000000);\n
108# output: report(0x00000000);\n
109# output: \n
110# output: report(0x7fffffff);\n
111# output: report(0x80000000);\n
112# output: report(0xffffffff);\n
113# output: report(0x00000001);\n
114# output: report(0x00000001);\n
115# output: report(0x00000001);\n
116# output: \n
117# output: exit(0)\n
118
119#include "or1k-asm-test-helpers.h"
120
121	STANDARD_TEST_ENVIRONMENT
122
123	.section .exception_vectors
124
125	/* Range exception.  */
126	.org	0xb00
127
128	/* The handling is a bit dubious at present.  We just patch the
129	   instruction with l.nop and restart.  This will go wrong in branch
130	   delay slots.  But we don't have those in this test.  */
131	l.addi r1, r1, -EXCEPTION_STACK_SKIP_SIZE
132	PUSH r2
133	PUSH r3
134	/* Save the address of the instruction that caused the problem.  */
135	MOVE_FROM_SPR r2, SPR_EPCR_BASE
136	LOAD_IMMEDIATE r3, 0x15000000 /* Opcode for l.nop  */
137	l.sw	0(r2), r3
138	POP r3
139	POP r2
140	l.addi r1, r1, EXCEPTION_STACK_SKIP_SIZE
141	l.rfe
142
143	.section .text
144start_tests:
145	PUSH LINK_REGISTER_R9
146
147	/* Test l.sub */
148
149	/* Subtract two small positive numbers.  Sets the carry, but never
150	   the overflow if the result is negative.  */
151	TEST_INST_FF_I32_I32 0, SPR_SR_CY | SPR_SR_OV, l.sub, 0x00000003, \
152	  0x00000002
153	TEST_INST_FF_I32_I32 0, SPR_SR_CY | SPR_SR_OV, l.sub, 0x00000001, \
154	  0x00000002
155
156	/* Check carry in is ignored.  */
157	TEST_INST_FF_I32_I32 SPR_SR_CY, SPR_SR_OV, l.sub, 0x00000003, 0x00000002
158
159	/* Subtract two small negative numbers.  Sets the carry flag if
160	   the result is negative, but never the overflow flag.  */
161	TEST_INST_FF_I32_I32 0, SPR_SR_CY | SPR_SR_OV, l.sub, 0xfffffffd, \
162	  0xfffffffe
163	TEST_INST_FF_I32_I32 0, SPR_SR_CY | SPR_SR_OV, l.sub, 0xffffffff, \
164	  0xfffffffe
165
166	/* Subtract two quite large positive numbers.  Should set neither
167	   the overflow nor the carry flag.  */
168	TEST_INST_FF_I32_I32 0, SPR_SR_CY | SPR_SR_OV, l.sub, 0x7fffffff, \
169	  0x3fffffff
170
171	/* Subtract two quite large negative numbers.  Should set neither
172	   the overflow nor the carry flag.  */
173	TEST_INST_FF_I32_I32 0, SPR_SR_CY | SPR_SR_OV, l.sub, 0x40000000, \
174	  0x40000000
175
176	/* Subtract two large positive numbers with a negative result.
177	   Should set the carry, but not the overflow flag.  */
178	TEST_INST_FF_I32_I32 0, SPR_SR_CY | SPR_SR_OV, l.sub, 0x3fffffff, \
179	  0x40000000
180
181	/* Subtract two large negative numbers with a positive result.
182	   Should set neither the carry nor the overflow flag.  */
183	TEST_INST_FF_I32_I32 0, SPR_SR_CY | SPR_SR_OV, l.sub, 0x40000000, \
184	  0x3fffffff
185
186	/* Subtract a large positive from a large negative number.  Should
187	   set overflow but not the carry flag.  */
188	TEST_INST_FF_I32_I32 0, SPR_SR_CY | SPR_SR_OV, l.sub, 0x80000000, \
189	  0x7fffffff
190
191	/* Subtract a large negative from a large positive number.  Should
192	   set both the overflow and carry flags.  */
193	TEST_INST_FF_I32_I32 0, SPR_SR_CY | SPR_SR_OV, l.sub, 0x7fffffff, \
194	  0x80000000
195
196	/* Check that range exceptions are triggered.  */
197
198	SET_SPR_SR_FLAGS SPR_SR_OVE, r2, r3
199
200	/* Check that an overflow alone causes a RANGE Exception.  */
201	TEST_INST_FF_I32_I32 0, SPR_SR_CY | SPR_SR_OV, l.sub, 0x80000000, \
202	  0x7fffffff
203
204	/* Check that a carry alone does not cause a RANGE Exception.  */
205	TEST_INST_FF_I32_I32 0, SPR_SR_CY | SPR_SR_OV, l.sub, 0x3fffffff, \
206	  0x40000000
207
208	/* Check that carry and overflow together cause an exception.  */
209	TEST_INST_FF_I32_I32 0, SPR_SR_CY | SPR_SR_OV, l.sub, 0x7fffffff, \
210	  0x80000000
211
212	CLEAR_SPR_SR_FLAGS SPR_SR_OVE, r2, r3
213
214	POP LINK_REGISTER_R9
215	RETURN_TO_LINK_REGISTER_R9
216