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