fsr_test.s revision 7186:e728311aafb0
1130803Smarcel/*
2130803Smarcel * CDDL HEADER START
3130803Smarcel *
4130803Smarcel * The contents of this file are subject to the terms of the
5130803Smarcel * Common Development and Distribution License (the "License").
6130803Smarcel * You may not use this file except in compliance with the License.
7130803Smarcel *
8130803Smarcel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9130803Smarcel * or http://www.opensolaris.org/os/licensing.
10130803Smarcel * See the License for the specific language governing permissions
11130803Smarcel * and limitations under the License.
12130803Smarcel *
13130803Smarcel * When distributing Covered Code, include this CDDL HEADER in each
14130803Smarcel * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15130803Smarcel * If applicable, add the following below this CDDL HEADER, with the
16130803Smarcel * fields enclosed by brackets "[]" replaced with your own identifying
17130803Smarcel * information: Portions Copyright [yyyy] [name of copyright owner]
18130803Smarcel *
19130803Smarcel * CDDL HEADER END
20130803Smarcel */
21130803Smarcel
22130803Smarcel/*
23130803Smarcel * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24130803Smarcel * Use is subject to license terms.
25130803Smarcel */
26130803Smarcel
27130803Smarcel#pragma ident	"%Z%%M%	%I%	%E% SMI"
28130803Smarcel
29130803Smarcel/*
30130803Smarcel * Assembly routines used in the FSR testing.
31130803Smarcel */
32258887Skib
33130803Smarcel
34130803Smarcel/*
35130803Smarcel *  DCTI couple for instruction picking
36130803Smarcel *  ===================================
37130803Smarcel *
38130803Smarcel *  The routines fcmps_fcc() and fcmpd_fcc() use a DCTI couple
39130803Smarcel *  for choosing a specific instruction from a set of instructions.
40130803Smarcel *  DCTI : Delayed Control Transfer Instruction. A DCTI couple
41130803Smarcel *  contains a control transfer instruction in the delay slot of
42130803Smarcel *  another control transfer instruction and the entire setup
43130803Smarcel *  looks something like this :
44130803Smarcel *
45130803Smarcel *		jmp	<tgt1>
46130803Smarcel *		ba	<tgt2>
47130803Smarcel *
48130803Smarcel *		.  .  .
49130803Smarcel *
50130803Smarcel *	table :		! Table of instructions. tgt1 will be pointing
51130803Smarcel *			! to one of the instructions in it.
52130803Smarcel *
53130803Smarcel *		.  .  .
54130803Smarcel *
55130803Smarcel *	tgt2 :
56130803Smarcel *		.  .  .
57130803Smarcel *
58130803Smarcel *  This functionality is explained below using the value of PC and
59130803Smarcel *  nPC. We start with the jmp instruction.
60130803Smarcel *
61130803Smarcel *	step1 :  PC='jmp'    nPC='ba'
62130803Smarcel *	step2 :  PC='ba'     nPC='tgt1'  ! jmp changes the nPC
63130803Smarcel *	step3 :  PC='tgt1'   nPC='tgt2'  ! ba changes the nPC
64130803Smarcel *	step4 :  PC='tgt2'   nPC=...
65130803Smarcel *
66130803Smarcel */
67130803Smarcel
68130803Smarcel
69130803Smarcel# include <sys/asm_linkage.h>
70130803Smarcel
71130803Smarcel
72130803Smarcel
73130803Smarcel/*
74130803Smarcel *  uint64_t res_fsr = fcmps_fcc(unsigned int val1, unsigned int val2,
75130803Smarcel *                               unsigned int fcc);
76130803Smarcel *
77130803Smarcel *  Single-precision FP comparision.
78130803Smarcel *
79130803Smarcel *  Operand 'fcc' indicates which fcc field of FSR to use.
80130803Smarcel */
81130803Smarcel
82130803Smarcel#ifdef __lint
83130803Smarcel
84130803Smarcel/*ARGSUSED*/
85130803Smarceluint64_t
86130803Smarcelfcmps_fcc(unsigned int arg1, unsigned int arg2, unsigned int arg3)
87130803Smarcel{
88130803Smarcel	return (0);
89130803Smarcel}
90130803Smarcel
91130803Smarcel#else
92130803Smarcel
93130803Smarcel.data
94130803Smarcel
95130803Smarcelfcmps_opr1 : .word 0
96130803Smarcel.type fcmps_opr1,#object
97130803Smarcel
98130803Smarcelfcmps_opr2 : .word 0
99130803Smarcel.type fcmps_opr2,#object
100130803Smarcel
101130803Smarcelfcmps_result : .word 0,0
102130803Smarcel.type fcmps_result,#object
103130803Smarcel
104130803SmarcelENTRY_NP(fcmps_fcc)
105130803Smarcel  save    %sp, -SA(MINFRAME), %sp
106130803Smarcel
107130803Smarcel  setn fcmps_opr1, %l0, %l1	! Get addr of operand 1 holder
108130803Smarcel  setn fcmps_opr2, %l0, %l2	! Get addr of operand 2 holder
109130803Smarcel  setn fcmps_result, %l0, %l3   ! Get addr of result holder
110130803Smarcel  setn fccn1, %l0, %o0		! Get addr of label fccn1
111130803Smarcel
112130803Smarcel  st   %i0, [%l1]		! Store operand 1 in memory
113130803Smarcel  st   %i1, [%l2]		! Store operand 2 in memory
114130803Smarcel  ld   [%l1], %f2		! Load operand 1 into FP reg
115130803Smarcel  ld   [%l2], %f4		! Load operand 2 into FP reg
116130803Smarcel
117130803Smarcel  sll  %i2, 2, %o1		! Calculate the offset
118130803Smarcel
119130803Smarcel
120130803Smarcel  ! DCTI couple
121130803Smarcel  jmp  %o0 + %o1		! Jump to fccn1+offset
122130803Smarcel  ba %ncc, fini			! After executing the target
123130803Smarcel				! instruction of 'jmp', go to the
124130803Smarcel				! end of the routine.
125130803Smarcel
126130803Smarcel
127130803Smarcelfccn1 :
128130803Smarcel
129130803Smarcel  fcmps %fcc0, %f2, %f4
130130803Smarcel
131130803Smarcel  fcmps %fcc1, %f2, %f4
132130803Smarcel
133130803Smarcel  fcmps %fcc2, %f2, %f4
134130803Smarcel
135130803Smarcel  fcmps %fcc3, %f2, %f4
136130803Smarcel
137130803Smarcel
138130803Smarcelfini :
139130803Smarcel  stx %fsr, [%l3]
140130803Smarcel  ldx [%l3], %i0
141130803Smarcel
142130803Smarcel  ret
143130803Smarcel  restore
144130803SmarcelSET_SIZE(fcmps_fcc)
145130803Smarcel
146130803Smarcel#endif
147130803Smarcel
148130803Smarcel/*
149130803Smarcel *  uint64_t res_fsr = fcmpd_fcc(uint64_t val1, uint64_t val2,
150130803Smarcel *                               unsigned int fcc);
151130803Smarcel *
152130803Smarcel *  Double-precision FP comparision.
153130803Smarcel *
154130803Smarcel *  Operand 'fcc' indicates which fcc field of FSR to use.
155130803Smarcel *
156130803Smarcel *  In SPARC V8, uint64_t parameters are split and stored in
157130803Smarcel *  consecutive registers. For example, the first uint64_t
158130803Smarcel *  parameter of the function will be stored in %i0 and %i1.
159130803Smarcel *  This is not done in SPARC V9 as the registers are 64-bit.
160130803Smarcel */
161130803Smarcel
162130803Smarcel#ifdef __lint
163130803Smarcel
164130803Smarcel/*ARGSUSED*/
165130803Smarceluint64_t
166130803Smarcelfcmpd_fcc(uint64_t arg1, uint64_t arg2, unsigned int arg3)
167130803Smarcel{
168130803Smarcel	return (0);
169130803Smarcel}
170130803Smarcel
171130803Smarcel#else
172130803Smarcel
173130803Smarcel.data
174130803Smarcel.align 8
175130803Smarcel
176130803Smarcelfcmpd_opr1 : .word 0,0
177130803Smarcel.type fcmpd_opr1,#object
178130803Smarcel
179130803Smarcelfcmpd_opr2 : .word 0,0
180130803Smarcel.type fcmpd_opr2,#object
181130803Smarcel
182130803Smarcelfcmpd_result : .word 0,0
183130803Smarcel.type fcmpd_result,#object
184130803Smarcel
185130803SmarcelENTRY_NP(fcmpd_fcc)
186130803Smarcel  save    %sp, -SA(MINFRAME), %sp
187130803Smarcel
188130803Smarcel  setn fcmpd_opr1, %l0, %l1	! Get addr of operand 1 holder
189130803Smarcel  setn fcmpd_opr2, %l0, %l2	! Get addr of operand 2 holder
190130803Smarcel  setn fcmpd_result, %l0, %l3   ! Get addr of result holder
191130803Smarcel  setn fccn2, %l0, %o0		! Get addr of label fccn2
192130803Smarcel
193130803Smarcel  stx   %i0, [%l1]		! Store operand 1 in memory
194130803Smarcel  stx   %i1, [%l2]		! Store operand 2 in memory
195130803Smarcel
196130803Smarcel  ldd   [%l1], %f2		! Load operand 1 into FP reg
197130803Smarcel  ldd   [%l2], %f4		! Load operand 2 into FP reg
198130803Smarcel
199130803Smarcel  sll  %i2, 2, %o1		! Calculate the offset
200130803Smarcel
201130803Smarcel  ! DCTI couple
202130803Smarcel  jmp  %o0 + %o1		! Jump to fccn2+offset
203130803Smarcel  ba %ncc, egress 		! After executing the target
204130803Smarcel				! instruction of 'jmp', go to the
205130803Smarcel				! end of the routine.
206130803Smarcel
207130803Smarcel
208130803Smarcelfccn2 :
209130803Smarcel
210130803Smarcel  fcmpd %fcc0, %f2, %f4
211130803Smarcel
212130803Smarcel  fcmpd %fcc1, %f2, %f4
213130803Smarcel
214130803Smarcel  fcmpd %fcc2, %f2, %f4
215130803Smarcel
216258887Skib  fcmpd %fcc3, %f2, %f4
217130803Smarcel
218258887Skib
219130803Smarcelegress :
220258887Skib
221258887Skib  stx %fsr, [%l3]
222130803Smarcel  ldx [%l3], %i0
223130803Smarcel
224130803Smarcel
225258887Skib  ret
226258887Skib  restore
227258887SkibSET_SIZE(fcmpd_fcc)
228258887Skib
229258887Skib#endif
230130803Smarcel