📄 ppc_dtof.s
字号:
/* fpopt/ppc_dtof.S, pl_FPE_common, pl_linux 11/24/03 16:17:23 */
/*----------------------------------------------------------------------------- */
/* Copyright (c) 2003, IBM Corporation */
/* All rights reserved. */
/* */
/* Redistribution and use in source and binary forms, with or */
/* without modification, are permitted provided that the following */
/* conditions are met: */
/* */
/* * Redistributions of source code must retain the above */
/* copyright notice, this list of conditions and the following */
/* disclaimer. */
/* * Redistributions in binary form must reproduce the above */
/* copyright notice, this list of conditions and the following */
/* disclaimer in the documentation and/or other materials */
/* provided with the distribution. */
/* * Neither the name of IBM nor the names of its contributors */
/* may be used to endorse or promote products derived from this */
/* software without specific prior written permission. */
/* */
/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND */
/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, */
/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS */
/* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, */
/* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, */
/* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR */
/* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */
/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE */
/* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
/* */
/*----------------------------------------------------------------------------- */
/* */
/* Function: convert double floating point to single floating point */
/* Input: r3,r4 */
/* Output: r3 */
/* Notes: 1. No stack frame is created for this function, so the following */
/* registers must be preserved, as required by ABI specification: */
/* LR, CR0, R1, R2, R13-R31 */
/* 2. operation performed according to IEEE754-1985 standard with */
/* rounding mode = nearest even. */
/* */
/*----------------------------------------------------------------------------- */
#include <ppc4xx.inc>
#include "fpeLib.inc"
function_prolog(__truncdfsf2)
/* use r11 to save CR */
mfcr r11
/* r8 = exp r9 = hifrac r4 = lofrac */
rlwinm r9,r3,3,0x007FFFF8 /* word[9:28] = FRS[12:31] */
rlwimi r9,r4,3,0x00000007 /* word[29:31] = FRS[32:34] */
rlwinm. r8,r3,12,0x000007FF /* extract exponent */
rlwinm r5,r3,0,0x80000000 /* pick up sign */
/* exponent test */
beq maybe_Zero /* if exponent=0 */
cmpwi cr0,r8,896
ble dN /* denormalized number */
cmpwi cr0,r8,1150
bgt special /* infinity or NaN or overflow */
reg_num: /* Normal numbers */
/* do rounding, guard = bit3, round = bit4, sticky=bits5-31 of frs.lo */
rlwinm r4,r4,0,0x1fffffff /* isolate grs and lower bits */
lis r6,0x1000 /* guard bit mask */
cmplw cr1,r4,r6 /* cr1 = guard bit set */
blt cr1,noround /* no guard, so no round */
andi. r0,r9,0x00000001 /* if frs.lobit==0 && t */
crand cr0_2,cr0_2,cr1_2 /* no guard or sticky */
beq noround
addic. r9,r9,1 /* round up */
/* check for carry out from rounding */
lis r6,0x0080
cmpw cr0,r9,r6
bne noround
addi r8,r8,1 /* increment exponent */
noround:
addi r8,r8,-896
rlwinm r3,r5,0,0x80000000 /* pick up sign in result */
rlwimi r3,r8,23,0x7f800000 /* pick up exponent */
rlwimi r3,r9,0,0x007fffff /* pick up rounded fraction */
mtcr r11 /* restore condition register */
blr
maybe_Zero:
or. r0,r9,r4 /* test hi and low frac against 0 */
bne dN /* no, so handle as denormal */
mr r3,r9
rlwimi r3,r5,0,0x80000000 /* move in saved sign */
mtcr r11 /* restore condition register */
blr
dN: /* denormal */
/* denormalized op here */
addi r8,r8,-1023 /* exp = exp - 1023 */
/* use reg 9, 4 as frac pair (only r9 contributes to final result) */
rlwinm r9,r3,11,0x7FFFF800 /* r9[1:20] = r3[12:31] */
rlwimi r9,r4,11,0x000007FF /* r9[21:31] = r4[0:10] */
rlwinm. r4,r4,0,0x001fffff
cror cr2_2,cr0_2,cr0_2 /* set ~sticky flag for rounding later */
oris r9,r9,0x8000 /* set hi order bit of r9 (implicit one)*/
b test
loop:
/* shift frac right by 1, zero fill */
andi. r0,r9,0x0001 /* losing precision */
crand cr2_2,cr2_2,cr0_2 /* ~sticky bit flag */
rlwinm r9,r9,31,0x7FFFFFFF /* shift hifrac right by 1, zero fill */
addi r8,r8,1 /* increment exponent */
test:
cmpwi cr0,r8,-126
blt loop
/* do rounding, guard = bit24, round = bit25, sticky=bits26-31 and frs.lo */
rlwinm r7,r9,0,0x000000ff /* isolate grs and lower bits */
li r6,0x0080 /* guard bit mask */
cmplw cr1,r7,r6 /* cr1 = guard bit set */
blt cr1,noround2 /* no guard, so no round */
andi. r0,r9,0x00000100 /* if frs.lobit==0 && t */
crand cr0_2,cr0_2,cr1_2 /* no guard or sticky */
crand cr0_2,cr0_2,cr2_2
beq noround2
addic. r9,r9,0x00000100 /* round up */
/* check for carry out from rounding */
bge noround2
oris r5,r5,0x0080 /* biased exponent = 1 */
noround2:
rlwimi r5,r9,24,0x007FFFFF /* word[9:31] = frac[1:23] */
mr r3,r5 /* results register */
mtcr r11 /* restore condition register */
blr
special:
cmpwi cr0,r8,0x07ff
beq inf_or_nan
/* rounding case force to infinity */
oris r3,r5,0x7f80 /* combine sign and infinity */
mtcr r11 /* restore condition register */
blr
inf_or_nan:
or. r0,r9,r4 /* test hi and low frac against 0 */
bne nan
oris r3,r5,0x7f80 /* combine sign and infinity */
mtcr r11 /* restore condition register */
blr
nan:
oris r3,r5,0x7fc0 /* or in QNAN value */
mtcr r11 /* restore condition register */
blr
function_epilog(__truncdfsf2)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -