Home | History | Annotate | Download | only in arm
      1 /*
      2  * Copyright (c) 2013-2014, NVIDIA Corporation.  All rights reserved.
      3  * Johnny Qiu <joqiu (at) nvidia.com>
      4  * Shu Zhang <chazhang (at) nvidia.com>
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions are
      8  * met:
      9  *     * Redistributions of source code must retain the above copyright
     10  *       notice, this list of conditions and the following disclaimer.
     11  *     * Redistributions in binary form must reproduce the above
     12  *       copyright notice, this list of conditions and the following
     13  *       disclaimer in the documentation and/or other materials provided
     14  *       with the distribution.
     15  *     * Neither the name of The Linux Foundation nor the names of its
     16  *       contributors may be used to endorse or promote products derived
     17  *       from this software without specific prior written permission.
     18  *
     19  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
     20  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     21  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
     22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     26  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     28  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     29  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 #include <float.h>
     33 #include <private/bionic_asm.h>
     34 
     35 ENTRY(floor)    /* x in r0, r1 */
     36 
     37         and             r3, r1, #0x80000000     /* sign(x) */
     38         bic             r1, r1, #0x80000000     /* x = abs(x) */
     39 
     40         /* extract exp of x */
     41         lsr             r2, r1, #20
     42         sub             r2, r2, #0x3fc
     43         subs            r2, r2, #0x3            /* r2 <- exp */
     44 
     45         /* |x| < 1.0? */
     46         blt             .Lx_lt_one
     47 
     48         /* x < 0? */
     49         cmp             r3, #0
     50         bne             .Lclr_frac_neg
     51 
     52         /* |x| <= 2^20? */
     53         cmp             r2, #20
     54         ble             .Lclr_frac_r1
     55 
     56         /* |x| < 2^52? */
     57         cmp             r2, #52
     58         blt             .Lclr_frac_r0
     59 
     60         /* return x */
     61         bx              lr
     62 
     63 .Lclr_frac_r1:
     64         rsb             r2, r2, #20
     65         lsr             r1, r1, r2
     66         lsl             r1, r1, r2
     67         mov             r0, #0
     68         bx              lr
     69 
     70 .Lclr_frac_r0:
     71         rsb             r2, r2, #52
     72         lsr             r0, r0, r2
     73         lsl             r0, r0, r2
     74         bx              lr
     75 
     76 .Lclr_frac_neg:
     77         /* |x| <= 2^20? */
     78         cmp             r2, #20
     79         ble             .Lclr_frac_r1_neg
     80 
     81         /* |x| < 2^52? */
     82         cmp             r2, #52
     83         blt             .Lclr_frac_r0_neg
     84 
     85         /* return x */
     86         orr             r1, r1, #0x80000000
     87         bx              lr
     88 
     89 .Lclr_frac_r1_neg:
     90         rsb             r2, r2, #20
     91         mov             r3, #1
     92         lsl             r3, r3, r2
     93         sub             r3, r3, #1
     94         and             r3, r1, r3
     95         orr             r3, r3, r0
     96         lsr             r1, r1, r2
     97         lsl             r1, r1, r2
     98         mov             r0, #0
     99         b               .Lreturn_x_neg
    100 
    101 .Lclr_frac_r0_neg:
    102         rsb             r2, r2, #52
    103         mov             r3, #1
    104         lsl             r3, r3, r2
    105         sub             r3, r3, #1
    106         and             r3, r0, r3
    107         lsr             r0, r0, r2
    108         lsl             r0, r0, r2
    109         b               .Lreturn_x_neg
    110 
    111 .Lx_lt_one:
    112         /* x == +-0? */
    113         cmp             r0, #0
    114         cmpeq           r1, #0
    115         orreq           r1, r1, r3
    116         bxeq            lr
    117 
    118         /* (x > 0) ? 0 : -1 */
    119         mov             r1, #0x00100000
    120         mov             r0, #0
    121         cmp             r3, #0
    122         movne           r1, #0xc0000000
    123         sub             r1, r1, #0x00100000
    124         bx              lr
    125 
    126 .Lreturn_x_neg:
    127         cmp             r3, #0
    128         orr             r1, r1, #0x80000000
    129         bxeq            lr
    130 
    131         vmov            d16, r0, r1
    132         vmov.f64        d18, #1.0
    133         vsub.f64        d16, d16, d18
    134         vmov            r0, r1, d16
    135         bx              lr
    136 
    137 END(floor)
    138 
    139 ALIAS_SYMBOL(floorl, floor);
    140