16429Svs195195/* 26429Svs195195 * CDDL HEADER START 36429Svs195195 * 46429Svs195195 * The contents of this file are subject to the terms of the 56429Svs195195 * Common Development and Distribution License (the "License"). 66429Svs195195 * You may not use this file except in compliance with the License. 76429Svs195195 * 86429Svs195195 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 96429Svs195195 * or http://www.opensolaris.org/os/licensing. 106429Svs195195 * See the License for the specific language governing permissions 116429Svs195195 * and limitations under the License. 126429Svs195195 * 136429Svs195195 * When distributing Covered Code, include this CDDL HEADER in each 146429Svs195195 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 156429Svs195195 * If applicable, add the following below this CDDL HEADER, with the 166429Svs195195 * fields enclosed by brackets "[]" replaced with your own identifying 176429Svs195195 * information: Portions Copyright [yyyy] [name of copyright owner] 186429Svs195195 * 196429Svs195195 * CDDL HEADER END 206429Svs195195 */ 216429Svs195195 226429Svs195195/* 236491Sia112686 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 246429Svs195195 * Use is subject to license terms. 256429Svs195195 */ 266429Svs195195 276429Svs195195#pragma ident "%Z%%M% %I% %E% SMI" 286429Svs195195 296429Svs195195/* 306429Svs195195 * Assembly routines used in the FSR testing. 316429Svs195195 */ 326429Svs195195 336429Svs195195 346429Svs195195/* 356429Svs195195 * DCTI couple for instruction picking 366429Svs195195 * =================================== 376429Svs195195 * 386429Svs195195 * The routines fcmps_fcc() and fcmpd_fcc() use a DCTI couple 396429Svs195195 * for choosing a specific instruction from a set of instructions. 406429Svs195195 * DCTI : Delayed Control Transfer Instruction. A DCTI couple 416429Svs195195 * contains a control transfer instruction in the delay slot of 426429Svs195195 * another control transfer instruction and the entire setup 436429Svs195195 * looks something like this : 446429Svs195195 * 456429Svs195195 * jmp <tgt1> 466429Svs195195 * ba <tgt2> 476429Svs195195 * 486429Svs195195 * . . . 496429Svs195195 * 506429Svs195195 * table : ! Table of instructions. tgt1 will be pointing 516429Svs195195 * ! to one of the instructions in it. 526429Svs195195 * 536429Svs195195 * . . . 546429Svs195195 * 556429Svs195195 * tgt2 : 566429Svs195195 * . . . 576429Svs195195 * 586429Svs195195 * This functionality is explained below using the value of PC and 596429Svs195195 * nPC. We start with the jmp instruction. 606429Svs195195 * 616429Svs195195 * step1 : PC='jmp' nPC='ba' 626429Svs195195 * step2 : PC='ba' nPC='tgt1' ! jmp changes the nPC 636429Svs195195 * step3 : PC='tgt1' nPC='tgt2' ! ba changes the nPC 646429Svs195195 * step4 : PC='tgt2' nPC=... 656429Svs195195 * 666429Svs195195 */ 676429Svs195195 686429Svs195195 696429Svs195195# include <sys/asm_linkage.h> 706429Svs195195 716429Svs195195 726429Svs195195 736429Svs195195/* 746429Svs195195 * uint64_t res_fsr = fcmps_fcc(unsigned int val1, unsigned int val2, 756429Svs195195 * unsigned int fcc); 766429Svs195195 * 776429Svs195195 * Single-precision FP comparision. 786429Svs195195 * 796429Svs195195 * Operand 'fcc' indicates which fcc field of FSR to use. 806429Svs195195 */ 816429Svs195195 82*7186Skk158166#ifdef __lint 83*7186Skk158166 84*7186Skk158166/*ARGSUSED*/ 85*7186Skk158166uint64_t 86*7186Skk158166fcmps_fcc(unsigned int arg1, unsigned int arg2, unsigned int arg3) 87*7186Skk158166{ 88*7186Skk158166 return (0); 89*7186Skk158166} 90*7186Skk158166 91*7186Skk158166#else 92*7186Skk158166 93*7186Skk158166.data 946429Svs195195 956429Svs195195fcmps_opr1 : .word 0 966429Svs195195.type fcmps_opr1,#object 976429Svs195195 986429Svs195195fcmps_opr2 : .word 0 996429Svs195195.type fcmps_opr2,#object 1006429Svs195195 1016429Svs195195fcmps_result : .word 0,0 1026429Svs195195.type fcmps_result,#object 1036429Svs195195 1046429Svs195195ENTRY_NP(fcmps_fcc) 1056429Svs195195 save %sp, -SA(MINFRAME), %sp 1066429Svs195195 1076429Svs195195 setn fcmps_opr1, %l0, %l1 ! Get addr of operand 1 holder 1086429Svs195195 setn fcmps_opr2, %l0, %l2 ! Get addr of operand 2 holder 1096429Svs195195 setn fcmps_result, %l0, %l3 ! Get addr of result holder 1106429Svs195195 setn fccn1, %l0, %o0 ! Get addr of label fccn1 1116429Svs195195 1126429Svs195195 st %i0, [%l1] ! Store operand 1 in memory 1136429Svs195195 st %i1, [%l2] ! Store operand 2 in memory 1146429Svs195195 ld [%l1], %f2 ! Load operand 1 into FP reg 1156429Svs195195 ld [%l2], %f4 ! Load operand 2 into FP reg 1166429Svs195195 1176429Svs195195 sll %i2, 2, %o1 ! Calculate the offset 1186429Svs195195 1196429Svs195195 1206429Svs195195 ! DCTI couple 1216429Svs195195 jmp %o0 + %o1 ! Jump to fccn1+offset 1226429Svs195195 ba %ncc, fini ! After executing the target 1236429Svs195195 ! instruction of 'jmp', go to the 1246429Svs195195 ! end of the routine. 1256429Svs195195 1266429Svs195195 1276429Svs195195fccn1 : 1286429Svs195195 1296429Svs195195 fcmps %fcc0, %f2, %f4 1306429Svs195195 1316429Svs195195 fcmps %fcc1, %f2, %f4 1326429Svs195195 1336429Svs195195 fcmps %fcc2, %f2, %f4 1346429Svs195195 1356429Svs195195 fcmps %fcc3, %f2, %f4 1366429Svs195195 1376429Svs195195 1386429Svs195195fini : 1396429Svs195195 stx %fsr, [%l3] 1406429Svs195195 ldx [%l3], %i0 1416429Svs195195 1426429Svs195195 ret 1436429Svs195195 restore 1446429Svs195195SET_SIZE(fcmps_fcc) 1456429Svs195195 146*7186Skk158166#endif 1476429Svs195195 1486429Svs195195/* 1496429Svs195195 * uint64_t res_fsr = fcmpd_fcc(uint64_t val1, uint64_t val2, 1506429Svs195195 * unsigned int fcc); 1516429Svs195195 * 1526429Svs195195 * Double-precision FP comparision. 1536429Svs195195 * 1546429Svs195195 * Operand 'fcc' indicates which fcc field of FSR to use. 1556429Svs195195 * 1566429Svs195195 * In SPARC V8, uint64_t parameters are split and stored in 1576429Svs195195 * consecutive registers. For example, the first uint64_t 1586429Svs195195 * parameter of the function will be stored in %i0 and %i1. 1596429Svs195195 * This is not done in SPARC V9 as the registers are 64-bit. 1606429Svs195195 */ 1616429Svs195195 162*7186Skk158166#ifdef __lint 163*7186Skk158166 164*7186Skk158166/*ARGSUSED*/ 165*7186Skk158166uint64_t 166*7186Skk158166fcmpd_fcc(uint64_t arg1, uint64_t arg2, unsigned int arg3) 167*7186Skk158166{ 168*7186Skk158166 return (0); 169*7186Skk158166} 170*7186Skk158166 171*7186Skk158166#else 172*7186Skk158166 173*7186Skk158166.data 174*7186Skk158166.align 8 1756429Svs195195 1766429Svs195195fcmpd_opr1 : .word 0,0 1776429Svs195195.type fcmpd_opr1,#object 1786429Svs195195 1796429Svs195195fcmpd_opr2 : .word 0,0 1806429Svs195195.type fcmpd_opr2,#object 1816429Svs195195 1826429Svs195195fcmpd_result : .word 0,0 1836429Svs195195.type fcmpd_result,#object 1846429Svs195195 1856429Svs195195ENTRY_NP(fcmpd_fcc) 1866429Svs195195 save %sp, -SA(MINFRAME), %sp 1876429Svs195195 1886429Svs195195 setn fcmpd_opr1, %l0, %l1 ! Get addr of operand 1 holder 1896429Svs195195 setn fcmpd_opr2, %l0, %l2 ! Get addr of operand 2 holder 1906429Svs195195 setn fcmpd_result, %l0, %l3 ! Get addr of result holder 1916429Svs195195 setn fccn2, %l0, %o0 ! Get addr of label fccn2 1926429Svs195195 1936429Svs195195 stx %i0, [%l1] ! Store operand 1 in memory 1946429Svs195195 stx %i1, [%l2] ! Store operand 2 in memory 1956429Svs195195 1966429Svs195195 ldd [%l1], %f2 ! Load operand 1 into FP reg 1976429Svs195195 ldd [%l2], %f4 ! Load operand 2 into FP reg 1986429Svs195195 1996429Svs195195 sll %i2, 2, %o1 ! Calculate the offset 2006429Svs195195 2016429Svs195195 ! DCTI couple 2026429Svs195195 jmp %o0 + %o1 ! Jump to fccn2+offset 2036429Svs195195 ba %ncc, egress ! After executing the target 2046429Svs195195 ! instruction of 'jmp', go to the 2056429Svs195195 ! end of the routine. 2066429Svs195195 2076429Svs195195 2086429Svs195195fccn2 : 2096429Svs195195 2106429Svs195195 fcmpd %fcc0, %f2, %f4 2116429Svs195195 2126429Svs195195 fcmpd %fcc1, %f2, %f4 2136429Svs195195 2146429Svs195195 fcmpd %fcc2, %f2, %f4 2156429Svs195195 2166429Svs195195 fcmpd %fcc3, %f2, %f4 2176429Svs195195 2186429Svs195195 2196429Svs195195egress : 2206429Svs195195 2216429Svs195195 stx %fsr, [%l3] 2226429Svs195195 ldx [%l3], %i0 2236429Svs195195 2246429Svs195195 2256429Svs195195 ret 2266429Svs195195 restore 2276429Svs195195SET_SIZE(fcmpd_fcc) 228*7186Skk158166 229*7186Skk158166#endif 230