Home | History | Annotate | Download | only in libagl
      1 /* libs/opengles/fixed_asm.S
      2 **
      3 ** Copyright 2006, The Android Open Source Project
      4 **
      5 ** Licensed under the Apache License, Version 2.0 (the "License");
      6 ** you may not use this file except in compliance with the License.
      7 ** You may obtain a copy of the License at
      8 **
      9 **     http://www.apache.org/licenses/LICENSE-2.0
     10 **
     11 ** Unless required by applicable law or agreed to in writing, software
     12 ** distributed under the License is distributed on an "AS IS" BASIS,
     13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 ** See the License for the specific language governing permissions and
     15 ** limitations under the License.
     16 */
     17 
     18 
     19     .text
     20     .align
     21 
     22     .global gglFloatToFixed
     23     .type gglFloatToFixed, %function
     24     .global gglFloatToFixedFast
     25     .type gglFloatToFixedFast, %function
     26 
     27 
     28 /*
     29  * Converts a float to a s15.16 fixed-point number.
     30  * this doesn't handle floats out of the [-32768, +32768[ range
     31  * and doesn't performs round-to-nearest.
     32  * however, it's very fast :-)
     33  */
     34 
     35 gglFloatToFixedFast:
     36         movs    r1, r0, lsl #1          /* remove bit sign */
     37         mov     r2, #0x8E               /* 127 + 15 */
     38         sub     r1, r2, r1, lsr #24     /* compute shift */
     39         mov     r2, r0, lsl #8          /* mantissa<<8 */
     40         orr     r2, r2, #0x80000000     /* add the missing 1 */
     41         mov     r0, r2, lsr r1          /* scale to 16.16 */
     42         rsbcs   r0, r0, #0              /* negate if needed */
     43         bx      lr
     44 
     45 /*
     46  * this version rounds-to-nearest and saturates numbers
     47  * outside the range (but not NaNs).
     48  */
     49 
     50 gglFloatToFixed:
     51         mov     r1, r0, lsl #1          /* remove bit sign */
     52         mov     r2, #0x8E               /* 127 + 15 */
     53         subs    r1, r2, r1, lsr #24     /* compute shift */
     54         bls     0f                      /* too big */
     55         mov     r2, r0, lsl #8          /* mantissa<<8 */
     56         orr     r2, r2, #0x80000000     /* add the missing 1 */
     57         mov     r3, r0
     58         movs    r0, r2, lsr r1          /* scale to 16.16 */
     59         addcs   r0, r0, #1              /* round-to-nearest */
     60         tst     r3, #0x80000000         /* negative? */
     61         rsbne   r0, r0, #0              /* negate if needed */
     62         bx      lr
     63 
     64 0:      ands    r0, r0, #0x80000000     /* keep only the sign bit */
     65         moveq   r0, #0x7fffffff         /* positive, maximum value */
     66         bx      lr
     67 
     68