1.file "libm_frexp_4l.s" 2 3// Copyright (C) 2000, 2001, Intel Corporation 4// All rights reserved. 5// 6// 7// Redistribution and use in source and binary forms, with or without 8// modification, are permitted provided that the following conditions are 9// met: 10// 11// * Redistributions of source code must retain the above copyright 12// notice, this list of conditions and the following disclaimer. 13// 14// * Redistributions in binary form must reproduce the above copyright 15// notice, this list of conditions and the following disclaimer in the 16// documentation and/or other materials provided with the distribution. 17// 18// * The name of Intel Corporation may not be used to endorse or promote 19// products derived from this software without specific prior written 20// permission. 21// 22// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 25// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR ITS 26// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 27// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 28// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 29// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 30// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR TORT (INCLUDING 31// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33// 34// Intel Corporation is the author of this code, and requests that all 35// problem reports or change requests be submitted to it directly at 36// http://developer.intel.com/opensource. 37// 38// History 39//============================================================== 40// 3/20/00: Initial version 41// 6/01/00: Fixed bug when x a double-extended denormal 42// 12/08/00 Corrected label on .endp 43// 44// API 45//============================================================== 46// long double frexpl(long double x, int* y) 47// long double __libm_frexp_4l(long double x, int* y) 48// where int* y is a 32-bit integer 49// 50// Overview of operation 51//============================================================== 52// break a floating point x number into fraction and an exponent 53// The fraction is returned as a long double 54// The exponent is returned as an integer pointed to by y 55// This is a true (not a biased exponent) but 0fffe is subtracted 56// as a bias instead of 0xffff. This is because the fraction returned 57// is between 0.5 and 1.0, not the expected IEEE range. 58// 59// The fraction is 0.5 <= fraction < 1.0 60// 61// Registers used 62//============================================================== 63// 64// general registers: 65// r14 exponent bias for x negative 66// r15 exponent bias for x positive 67// r16 signexp of x 68// r17 exponent mask 69// r18 exponent of x 70// r19 exponent result 71// r20 signexp of 2^64 72// r32-33 on input contains the 80-bit IEEE long double that is in f8 73// r34 on input pointer to 32-bit integer for exponent 74// 75// predicate registers: 76// p6 set if x is Nan, zero, or infinity 77// p7 set if x negative 78// p8 set if x positive 79// p9 set if x double-extended denormal 80// 81// floating-point registers: 82// f8 input, output 83// f9 normalized x 84// f10 signexp for significand result for x positive 85// f11 signexp for significand result for x negative 86// f12 2^64 87 88#include "libm_support.h" 89 90.align 32 91.global __libm_frexp_4l# 92 93.section .text 94.proc __libm_frexp_4l# 95.align 32 96 97__libm_frexp_4l: 98 99// Set signexp for significand result for x>0 100// If x is a NaN, zero, or infinity, return it. 101// Put 0 in the int pointer. 102// x NAN, ZERO, INFINITY? 103// Set signexp for significand result for x<0 104{ .mfi 105(p0) mov r15 = 0x0fffe 106(p0) fclass.m.unc p6,p0 = f8, 0xe7 107(p0) mov r14 = 0x2fffe 108} 109// Form signexp of 2^64 in case x double-extended denormal 110// Save the normalized value of input in f9 111// The normalization also sets fault flags and takes faults if necessary 112{ .mfi 113(p0) mov r20 = 0x1003f 114(p0) fnorm f9 = f8 115 nop.i 999 ;; 116} 117 118// Move signexp for significand result for x>0 to FP reg 119// Form 2^64 in case x double-extended denormal 120{ .mmi 121(p0) setf.exp f10 = r15 122(p0) setf.exp f12 = r20 123 nop.i 999 ;; 124} 125 126// Move signexp for significand result for x<0 to FP reg 127// If x NAN, ZERO, INFINITY, set *y=0 as a 32-bit integer, and exit 128{ .mmb 129(p0) setf.exp f11 = r14 130(p6) st4 [r34] = r0 131(p6) br.ret.spnt b0 ;; 132} 133 134// Form exponent mask 135// p7 if x<0, else p8 136{ .mfi 137(p0) mov r17 = 0x1ffff 138(p0) fcmp.lt.unc p7,p8 = f8,f0 139 nop.i 999 ;; 140} 141 142// Test for fnorm(x) denormal, means x double-extended denormal 143{ .mfi 144 nop.m 999 145(p0) fclass.m.unc p9,p0 = f9, 0x0b 146 nop.i 999 ;; 147} 148 149// If x double-extended denormal add 64 to exponent bias for scaling 150// If x double-extended denormal multiply x * 2^64 which is normal 151{ .mfi 152(p9) add r15 = 64, r15 153(p9) fmpy f9 = f9, f12 154 nop.i 999 ;; 155} 156 157// true exponent stored to int pointer 158// the bias is treated as 0xfffe instead of 159// normal 0xffff because we want the significand 160// to be in the range <=0.5 sig < 1.0 161// Store the value of the exponent at the pointer in r34 162 163// If x>0 form significand result 164{ .mfi 165 nop.m 999 166(p8) fmerge.se f8 = f10,f9 167 nop.i 999 ;; 168} 169 170// Get signexp of normalized x 171// If x<0 form significand result 172{ .mfi 173(p0) getf.exp r16 = f9 174(p7) fmerge.se f8 = f11,f9 175 nop.i 999 ;; 176} 177 178// Get exp of normalized x 179// Subtract off bias to get true exponent of x 180{ .mmi 181(p0) and r18 = r17,r16 ;; 182(p0) sub r19 = r18,r15 183 nop.i 999 ;; 184} 185 186// Store int y as a 32-bit integer 187// Make the value a long double 188{ .mfb 189(p0) st4 [r34] = r19 190(p0) fnorm f8 = f8 191(p0) br.ret.sptk b0 ;; 192} 193 194.endp __libm_frexp_4l 195ASM_SIZE_DIRECTIVE(__libm_frexp_4l) 196strong_alias(__libm_frexp_4l, _GI___libm_frexp_4l) 197