Home | History | Annotate | Download | only in fptest
      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*/
     85 uint64_t
     86 fcmps_fcc(unsigned int arg1, unsigned int arg2, unsigned int arg3)
     87 {
     88 	return (0);
     89 }
     90 
     91 #else
     92 
     93 .data
     94 
     95 fcmps_opr1 : .word 0
     96 .type fcmps_opr1,#object
     97 
     98 fcmps_opr2 : .word 0
     99 .type fcmps_opr2,#object
    100 
    101 fcmps_result : .word 0,0
    102 .type fcmps_result,#object
    103 
    104 ENTRY_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 
    127 fccn1 :
    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 
    138 fini :
    139   stx %fsr, [%l3]
    140   ldx [%l3], %i0
    141 
    142   ret
    143   restore
    144 SET_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*/
    165 uint64_t
    166 fcmpd_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 
    176 fcmpd_opr1 : .word 0,0
    177 .type fcmpd_opr1,#object
    178 
    179 fcmpd_opr2 : .word 0,0
    180 .type fcmpd_opr2,#object
    181 
    182 fcmpd_result : .word 0,0
    183 .type fcmpd_result,#object
    184 
    185 ENTRY_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 
    208 fccn2 :
    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 
    219 egress :
    220 
    221   stx %fsr, [%l3]
    222   ldx [%l3], %i0
    223 
    224 
    225   ret
    226   restore
    227 SET_SIZE(fcmpd_fcc)
    228 
    229 #endif
    230