fsr_test.s revision 6491:448e02e63395
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	.data
83
84fcmps_opr1 : .word 0
85.type fcmps_opr1,#object
86
87fcmps_opr2 : .word 0
88.type fcmps_opr2,#object
89
90fcmps_result : .word 0,0
91.type fcmps_result,#object
92
93ENTRY_NP(fcmps_fcc)
94  save    %sp, -SA(MINFRAME), %sp
95
96  setn fcmps_opr1, %l0, %l1	! Get addr of operand 1 holder
97  setn fcmps_opr2, %l0, %l2	! Get addr of operand 2 holder
98  setn fcmps_result, %l0, %l3   ! Get addr of result holder
99  setn fccn1, %l0, %o0		! Get addr of label fccn1
100
101  st   %i0, [%l1]		! Store operand 1 in memory
102  st   %i1, [%l2]		! Store operand 2 in memory
103  ld   [%l1], %f2		! Load operand 1 into FP reg
104  ld   [%l2], %f4		! Load operand 2 into FP reg
105
106  sll  %i2, 2, %o1		! Calculate the offset
107
108
109  ! DCTI couple
110  jmp  %o0 + %o1		! Jump to fccn1+offset
111  ba %ncc, fini			! After executing the target
112				! instruction of 'jmp', go to the
113				! end of the routine.
114
115
116fccn1 :
117
118  fcmps %fcc0, %f2, %f4
119
120  fcmps %fcc1, %f2, %f4
121
122  fcmps %fcc2, %f2, %f4
123
124  fcmps %fcc3, %f2, %f4
125
126
127fini :
128  stx %fsr, [%l3]
129  ldx [%l3], %i0
130
131  ret
132  restore
133SET_SIZE(fcmps_fcc)
134
135
136
137/*
138 *  uint64_t res_fsr = fcmpd_fcc(uint64_t val1, uint64_t val2,
139 *                               unsigned int fcc);
140 *
141 *  Double-precision FP comparision.
142 *
143 *  Operand 'fcc' indicates which fcc field of FSR to use.
144 *
145 *  In SPARC V8, uint64_t parameters are split and stored in
146 *  consecutive registers. For example, the first uint64_t
147 *  parameter of the function will be stored in %i0 and %i1.
148 *  This is not done in SPARC V9 as the registers are 64-bit.
149 */
150
151	.data
152	.align 8
153
154fcmpd_opr1 : .word 0,0
155.type fcmpd_opr1,#object
156
157fcmpd_opr2 : .word 0,0
158.type fcmpd_opr2,#object
159
160fcmpd_result : .word 0,0
161.type fcmpd_result,#object
162
163ENTRY_NP(fcmpd_fcc)
164  save    %sp, -SA(MINFRAME), %sp
165
166  setn fcmpd_opr1, %l0, %l1	! Get addr of operand 1 holder
167  setn fcmpd_opr2, %l0, %l2	! Get addr of operand 2 holder
168  setn fcmpd_result, %l0, %l3   ! Get addr of result holder
169  setn fccn2, %l0, %o0		! Get addr of label fccn2
170
171  stx   %i0, [%l1]		! Store operand 1 in memory
172  stx   %i1, [%l2]		! Store operand 2 in memory
173
174  ldd   [%l1], %f2		! Load operand 1 into FP reg
175  ldd   [%l2], %f4		! Load operand 2 into FP reg
176
177  sll  %i2, 2, %o1		! Calculate the offset
178
179  ! DCTI couple
180  jmp  %o0 + %o1		! Jump to fccn2+offset
181  ba %ncc, egress 		! After executing the target
182				! instruction of 'jmp', go to the
183				! end of the routine.
184
185
186fccn2 :
187
188  fcmpd %fcc0, %f2, %f4
189
190  fcmpd %fcc1, %f2, %f4
191
192  fcmpd %fcc2, %f2, %f4
193
194  fcmpd %fcc3, %f2, %f4
195
196
197egress :
198
199  stx %fsr, [%l3]
200  ldx [%l3], %i0
201
202
203  ret
204  restore
205SET_SIZE(fcmpd_fcc)
206