xref: /onnv-gate/usr/src/cmd/fps/fptest/fsr_test.s (revision 7186:e728311aafb0)
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#pragma ident	"%Z%%M%	%I%	%E% SMI"
28
29/*
30 * Assembly routines used in the FSR testing.
31 */
32
33
34/*
35 *  DCTI couple for instruction picking
36 *  ===================================
37 *
38 *  The routines fcmps_fcc() and fcmpd_fcc() use a DCTI couple
39 *  for choosing a specific instruction from a set of instructions.
40 *  DCTI : Delayed Control Transfer Instruction. A DCTI couple
41 *  contains a control transfer instruction in the delay slot of
42 *  another control transfer instruction and the entire setup
43 *  looks something like this :
44 *
45 *		jmp	<tgt1>
46 *		ba	<tgt2>
47 *
48 *		.  .  .
49 *
50 *	table :		! Table of instructions. tgt1 will be pointing
51 *			! to one of the instructions in it.
52 *
53 *		.  .  .
54 *
55 *	tgt2 :
56 *		.  .  .
57 *
58 *  This functionality is explained below using the value of PC and
59 *  nPC. We start with the jmp instruction.
60 *
61 *	step1 :  PC='jmp'    nPC='ba'
62 *	step2 :  PC='ba'     nPC='tgt1'  ! jmp changes the nPC
63 *	step3 :  PC='tgt1'   nPC='tgt2'  ! ba changes the nPC
64 *	step4 :  PC='tgt2'   nPC=...
65 *
66 */
67
68
69# include <sys/asm_linkage.h>
70
71
72
73/*
74 *  uint64_t res_fsr = fcmps_fcc(unsigned int val1, unsigned int val2,
75 *                               unsigned int fcc);
76 *
77 *  Single-precision FP comparision.
78 *
79 *  Operand 'fcc' indicates which fcc field of FSR to use.
80 */
81
82#ifdef __lint
83
84/*ARGSUSED*/
85uint64_t
86fcmps_fcc(unsigned int arg1, unsigned int arg2, unsigned int arg3)
87{
88	return (0);
89}
90
91#else
92
93.data
94
95fcmps_opr1 : .word 0
96.type fcmps_opr1,#object
97
98fcmps_opr2 : .word 0
99.type fcmps_opr2,#object
100
101fcmps_result : .word 0,0
102.type fcmps_result,#object
103
104ENTRY_NP(fcmps_fcc)
105  save    %sp, -SA(MINFRAME), %sp
106
107  setn fcmps_opr1, %l0, %l1	! Get addr of operand 1 holder
108  setn fcmps_opr2, %l0, %l2	! Get addr of operand 2 holder
109  setn fcmps_result, %l0, %l3   ! Get addr of result holder
110  setn fccn1, %l0, %o0		! Get addr of label fccn1
111
112  st   %i0, [%l1]		! Store operand 1 in memory
113  st   %i1, [%l2]		! Store operand 2 in memory
114  ld   [%l1], %f2		! Load operand 1 into FP reg
115  ld   [%l2], %f4		! Load operand 2 into FP reg
116
117  sll  %i2, 2, %o1		! Calculate the offset
118
119
120  ! DCTI couple
121  jmp  %o0 + %o1		! Jump to fccn1+offset
122  ba %ncc, fini			! After executing the target
123				! instruction of 'jmp', go to the
124				! end of the routine.
125
126
127fccn1 :
128
129  fcmps %fcc0, %f2, %f4
130
131  fcmps %fcc1, %f2, %f4
132
133  fcmps %fcc2, %f2, %f4
134
135  fcmps %fcc3, %f2, %f4
136
137
138fini :
139  stx %fsr, [%l3]
140  ldx [%l3], %i0
141
142  ret
143  restore
144SET_SIZE(fcmps_fcc)
145
146#endif
147
148/*
149 *  uint64_t res_fsr = fcmpd_fcc(uint64_t val1, uint64_t val2,
150 *                               unsigned int fcc);
151 *
152 *  Double-precision FP comparision.
153 *
154 *  Operand 'fcc' indicates which fcc field of FSR to use.
155 *
156 *  In SPARC V8, uint64_t parameters are split and stored in
157 *  consecutive registers. For example, the first uint64_t
158 *  parameter of the function will be stored in %i0 and %i1.
159 *  This is not done in SPARC V9 as the registers are 64-bit.
160 */
161
162#ifdef __lint
163
164/*ARGSUSED*/
165uint64_t
166fcmpd_fcc(uint64_t arg1, uint64_t arg2, unsigned int arg3)
167{
168	return (0);
169}
170
171#else
172
173.data
174.align 8
175
176fcmpd_opr1 : .word 0,0
177.type fcmpd_opr1,#object
178
179fcmpd_opr2 : .word 0,0
180.type fcmpd_opr2,#object
181
182fcmpd_result : .word 0,0
183.type fcmpd_result,#object
184
185ENTRY_NP(fcmpd_fcc)
186  save    %sp, -SA(MINFRAME), %sp
187
188  setn fcmpd_opr1, %l0, %l1	! Get addr of operand 1 holder
189  setn fcmpd_opr2, %l0, %l2	! Get addr of operand 2 holder
190  setn fcmpd_result, %l0, %l3   ! Get addr of result holder
191  setn fccn2, %l0, %o0		! Get addr of label fccn2
192
193  stx   %i0, [%l1]		! Store operand 1 in memory
194  stx   %i1, [%l2]		! Store operand 2 in memory
195
196  ldd   [%l1], %f2		! Load operand 1 into FP reg
197  ldd   [%l2], %f4		! Load operand 2 into FP reg
198
199  sll  %i2, 2, %o1		! Calculate the offset
200
201  ! DCTI couple
202  jmp  %o0 + %o1		! Jump to fccn2+offset
203  ba %ncc, egress 		! After executing the target
204				! instruction of 'jmp', go to the
205				! end of the routine.
206
207
208fccn2 :
209
210  fcmpd %fcc0, %f2, %f4
211
212  fcmpd %fcc1, %f2, %f4
213
214  fcmpd %fcc2, %f2, %f4
215
216  fcmpd %fcc3, %f2, %f4
217
218
219egress :
220
221  stx %fsr, [%l3]
222  ldx [%l3], %i0
223
224
225  ret
226  restore
227SET_SIZE(fcmpd_fcc)
228
229#endif
230