gnu / gcc / 4a0fed0c0c7241562eaa5f1a4c916b689429ad86 / . / libgcc / config / arc / ieee-754 / truncdfsf2.S

/* Copyright (C) 2006-2021 Free Software Foundation, Inc. | |

Contributor: Joern Rennecke <joern.rennecke@embecosm.com> | |

on behalf of Synopsys Inc. | |

This file is part of GCC. | |

GCC is free software; you can redistribute it and/or modify it under | |

the terms of the GNU General Public License as published by the Free | |

Software Foundation; either version 3, or (at your option) any later | |

version. | |

GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |

WARRANTY; without even the implied warranty of MERCHANTABILITY or | |

FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |

for more details. | |

Under Section 7 of GPL version 3, you are granted additional | |

permissions described in the GCC Runtime Library Exception, version | |

3.1, as published by the Free Software Foundation. | |

You should have received a copy of the GNU General Public License and | |

a copy of the GCC Runtime Library Exception along with this program; | |

see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |

<http://www.gnu.org/licenses/>. */ | |

#include "arc-ieee-754.h" | |

#if 0 /* DEBUG */ | |

FUNC(__truncdfsf2) | |

.global __truncdfsf2 | |

.balign 4 | |

__truncdfsf2: | |

push_s blink | |

push_s r0 | |

bl.d __truncdfsf2_c | |

push_s r1 | |

mov_s r2,r0 | |

pop_s r1 | |

ld r0,[sp] | |

bl.d __truncdfsf2_asm | |

st r2,[sp] | |

pop_s r1 | |

pop_s blink | |

cmp r0,r1 | |

jeq_s [blink] | |

and r12,r0,r1 | |

bic.f 0,0x7f800000,r12 | |

bne 0f | |

bmsk.f 0,r0,22 | |

bmsk.ne.f r1,r1,22 | |

jne_s [blink] ; both NaN -> OK | |

0: bl abort | |

ENDFUNC(__truncdfsf2) | |

#define __truncdfsf2 __truncdfsf2_asm | |

#endif /* DEBUG */ | |

.global __truncdfsf2 | |

.balign 4 | |

FUNC(__truncdfsf2) | |

__truncdfsf2: | |

lsr r2,DBL0H,20 | |

asl_s DBL0H,DBL0H,12 | |

sub r12,r2,0x380 | |

bclr.f r3,r12,11 | |

brhs r3,0xff,.Lill_exp | |

beq_l .Ldenorm0 | |

asl_s r12,r12,23 | |

tst DBL0L, \ | |

0x2fffffff /* Check if msb guard bit wants rounding up. */ | |

lsr_s DBL0L,DBL0L,28 | |

lsr_s DBL0H,DBL0H,8 | |

add.ne DBL0L,DBL0L,1 | |

add_s DBL0H,DBL0H,DBL0L | |

lsr_s DBL0H,DBL0H | |

btst_s r2,11 | |

add_s r0,DBL0H,r12 | |

j_s.d [blink] | |

bxor.ne r0,r0,31 | |

.balign 4 | |

.Lill_exp: | |

bbit1 r2,10,.Linf_nan | |

bmsk_s r12,r12,9 | |

rsub.f r12,r12,8+0x400-32 ; Go from 9 to 1 guard bit in MSW. */ | |

bhs_s .Lzero | |

lsr r3,DBL0L,21 | |

rrc DBL0H,DBL0H ; insert leading 1 | |

asl.f 0,DBL0L,8 ; check lower 24 guard bits | |

add_s r3,DBL0H,r3 | |

add.pnz r3,r3,1 ; assemble fraction with compressed guard bits. | |

lsr r0,r3,r12 | |

neg_s r12,r12 | |

btst_s r0,1 | |

asl.eq.f r3,r3,r12 | |

add.ne r0,r0,1 | |

btst_s r2,11 | |

lsr_s r0,r0 | |

j_s.d [blink] | |

bxor.ne r0,r0,31 | |

.Lzero: | |

lsr_s r2,r2,11 | |

j_s.d [blink] | |

asl r0,r2,31 | |

.Ldenorm0: | |

asl_s r12,r12,20 | |

tst DBL0L, \ | |

0x5fffffff /* Check if msb guard bit wants rounding up. */ | |

lsr_s DBL0L,DBL0L,29 | |

lsr_s DBL0H,DBL0H,9 | |

add.ne DBL0L,DBL0L,1 | |

bset_s DBL0H,DBL0H,23 | |

add_s DBL0H,DBL0H,DBL0L | |

lsr_s DBL0H,DBL0H | |

j_s.d [blink] | |

add_l r0,DBL0H,r12 | |

/* We would generally say that NaNs must have a non-zero high fraction part, | |

but to allow hardware double precision floating point to interoperate | |

with single precision software floating point, we make an exception here. | |

The cost is to replace a tst_s DBL0H with an or.f DBL0L,DBL0L,DBL0H . | |

As we start out unaligned, and there is an odd number of other short insns, | |

we have a choice of letting this cost us a misalign penalty or | |

4 more bytes (if we align the code). We choose the former here because | |

infinity / NaN is not expected to be prevalent in time-critical code. */ | |

.Linf_nan: | |

or.f DBL0L,DBL0L,DBL0H | |

mov_s r0,1 | |

add.ne r2,r2,1 | |

tst r2,0x7ff | |

asl.ne r0,r0,23 | |

btst_s r12,11 | |

neg r0,r0 | |

j_s.d [blink] | |

bxor.eq r0,r0,31 | |

ENDFUNC(__truncdfsf2) |