1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (C) 2005 The Android Open Source Project 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * you may not use this file except in compliance with the License. 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * You may obtain a copy of the License at 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * See the License for the specific language governing permissions and 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * limitations under the License. 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef ANDROID_GGL_FIXED_H 18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define ANDROID_GGL_FIXED_H 19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <math.h> 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <pixelflinger/pixelflinger.h> 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ---------------------------------------------------------------------------- 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define CONST __attribute__((const)) 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define ALWAYS_INLINE __attribute__((always_inline)) 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst GGLfixed FIXED_BITS = 16; 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst GGLfixed FIXED_EPSILON = 1; 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst GGLfixed FIXED_ONE = 1L<<FIXED_BITS; 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst GGLfixed FIXED_HALF = 1L<<(FIXED_BITS-1); 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst GGLfixed FIXED_MIN = 0x80000000L; 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst GGLfixed FIXED_MAX = 0x7FFFFFFFL; 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglIntToFixed(GGLfixed i) ALWAYS_INLINE ; 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglFixedToIntRound(GGLfixed f) ALWAYS_INLINE ; 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglFixedToIntFloor(GGLfixed f) ALWAYS_INLINE ; 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglFixedToIntCeil(GGLfixed f) ALWAYS_INLINE ; 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglFracx(GGLfixed v) ALWAYS_INLINE ; 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglFloorx(GGLfixed v) ALWAYS_INLINE ; 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglCeilx(GGLfixed v) ALWAYS_INLINE ; 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglCenterx(GGLfixed v) ALWAYS_INLINE ; 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglRoundx(GGLfixed v) ALWAYS_INLINE ; 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectGGLfixed gglIntToFixed(GGLfixed i) { 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return i<<FIXED_BITS; 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectGGLfixed gglFixedToIntRound(GGLfixed f) { 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return (f + FIXED_HALF)>>FIXED_BITS; 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectGGLfixed gglFixedToIntFloor(GGLfixed f) { 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return f>>FIXED_BITS; 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectGGLfixed gglFixedToIntCeil(GGLfixed f) { 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return (f + ((1<<FIXED_BITS) - 1))>>FIXED_BITS; 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectGGLfixed gglFracx(GGLfixed v) { 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return v & ((1<<FIXED_BITS)-1); 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectGGLfixed gglFloorx(GGLfixed v) { 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return gglFixedToIntFloor(v)<<FIXED_BITS; 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectGGLfixed gglCeilx(GGLfixed v) { 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return gglFixedToIntCeil(v)<<FIXED_BITS; 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectGGLfixed gglCenterx(GGLfixed v) { 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return gglFloorx(v + FIXED_HALF) | FIXED_HALF; 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectGGLfixed gglRoundx(GGLfixed v) { 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return gglFixedToIntRound(v)<<FIXED_BITS; 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// conversion from (unsigned) int, short, byte to fixed... 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define GGL_B_TO_X(_x) GGLfixed( ((int32_t(_x)+1)>>1)<<10 ) 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define GGL_S_TO_X(_x) GGLfixed( ((int32_t(_x)+1)>>1)<<2 ) 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define GGL_I_TO_X(_x) GGLfixed( ((int32_t(_x)>>1)+1)>>14 ) 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define GGL_UB_TO_X(_x) GGLfixed( uint32_t(_x) + \ 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (uint32_t(_x)<<8) + \ 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (uint32_t(_x)>>7) ) 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define GGL_US_TO_X(_x) GGLfixed( (_x) + ((_x)>>15) ) 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define GGL_UI_TO_X(_x) GGLfixed( (((_x)>>1)+1)>>15 ) 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ---------------------------------------------------------------------------- 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectGGLfixed gglPowx(GGLfixed x, GGLfixed y) CONST; 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectGGLfixed gglSqrtx(GGLfixed a) CONST; 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectGGLfixed gglSqrtRecipx(GGLfixed x) CONST; 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectGGLfixed gglFastDivx(GGLfixed n, GGLfixed d) CONST; 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint32_t gglMulDivi(int32_t a, int32_t b, int32_t c); 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint32_t gglRecipQNormalized(int32_t x, int* exponent); 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint32_t gglRecipQ(GGLfixed x, int q) CONST; 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglRecip(GGLfixed x) CONST; 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglRecip(GGLfixed x) { 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return gglRecipQ(x, 16); 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglRecip28(GGLfixed x) CONST; 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint32_t gglRecip28(GGLfixed x) { 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return gglRecipQ(x, 28); 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ---------------------------------------------------------------------------- 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if defined(__arm__) && !defined(__thumb__) 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// inline ARM implementations 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulx(GGLfixed x, GGLfixed y, int shift) CONST; 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulx(GGLfixed x, GGLfixed y, int shift) { 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project GGLfixed result, t; 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (__builtin_constant_p(shift)) { 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asm("smull %[lo], %[hi], %[x], %[y] \n" 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "movs %[lo], %[lo], lsr %[rshift] \n" 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "adc %[lo], %[lo], %[hi], lsl %[lshift] \n" 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project : [lo]"=r"(result), [hi]"=r"(t), [x]"=r"(x) 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project : "%[x]"(x), [y]"r"(y), [lshift] "I"(32-shift), [rshift] "I"(shift) 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project : "cc" 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ); 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asm("smull %[lo], %[hi], %[x], %[y] \n" 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "movs %[lo], %[lo], lsr %[rshift] \n" 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "adc %[lo], %[lo], %[hi], lsl %[lshift] \n" 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project : [lo]"=&r"(result), [hi]"=&r"(t), [x]"=&r"(x) 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project : "%[x]"(x), [y]"r"(y), [lshift] "r"(32-shift), [rshift] "r"(shift) 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project : "cc" 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ); 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return result; 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulAddx(GGLfixed x, GGLfixed y, GGLfixed a, int shift) CONST; 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulAddx(GGLfixed x, GGLfixed y, GGLfixed a, int shift) { 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project GGLfixed result, t; 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (__builtin_constant_p(shift)) { 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asm("smull %[lo], %[hi], %[x], %[y] \n" 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "add %[lo], %[a], %[lo], lsr %[rshift] \n" 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "add %[lo], %[lo], %[hi], lsl %[lshift] \n" 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project : [lo]"=&r"(result), [hi]"=&r"(t), [x]"=&r"(x) 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project : "%[x]"(x), [y]"r"(y), [a]"r"(a), [lshift] "I"(32-shift), [rshift] "I"(shift) 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ); 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asm("smull %[lo], %[hi], %[x], %[y] \n" 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "add %[lo], %[a], %[lo], lsr %[rshift] \n" 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "add %[lo], %[lo], %[hi], lsl %[lshift] \n" 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project : [lo]"=&r"(result), [hi]"=&r"(t), [x]"=&r"(x) 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project : "%[x]"(x), [y]"r"(y), [a]"r"(a), [lshift] "r"(32-shift), [rshift] "r"(shift) 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ); 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return result; 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulSubx(GGLfixed x, GGLfixed y, GGLfixed a, int shift) CONST; 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulSubx(GGLfixed x, GGLfixed y, GGLfixed a, int shift) { 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project GGLfixed result, t; 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (__builtin_constant_p(shift)) { 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asm("smull %[lo], %[hi], %[x], %[y] \n" 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "rsb %[lo], %[a], %[lo], lsr %[rshift] \n" 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "add %[lo], %[lo], %[hi], lsl %[lshift] \n" 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project : [lo]"=&r"(result), [hi]"=&r"(t), [x]"=&r"(x) 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project : "%[x]"(x), [y]"r"(y), [a]"r"(a), [lshift] "I"(32-shift), [rshift] "I"(shift) 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ); 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asm("smull %[lo], %[hi], %[x], %[y] \n" 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "rsb %[lo], %[a], %[lo], lsr %[rshift] \n" 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "add %[lo], %[lo], %[hi], lsl %[lshift] \n" 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project : [lo]"=&r"(result), [hi]"=&r"(t), [x]"=&r"(x) 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project : "%[x]"(x), [y]"r"(y), [a]"r"(a), [lshift] "r"(32-shift), [rshift] "r"(shift) 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ); 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return result; 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int64_t gglMulii(int32_t x, int32_t y) CONST; 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int64_t gglMulii(int32_t x, int32_t y) 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // 64-bits result: r0=low, r1=high 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project union { 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct { 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int32_t lo; 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int32_t hi; 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } s; 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int64_t res; 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project }; 186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asm("smull %0, %1, %2, %3 \n" 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project : "=r"(s.lo), "=&r"(s.hi) 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project : "%r"(x), "r"(y) 189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project : 190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ); 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return res; 192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else // ---------------------------------------------------------------------- 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulx(GGLfixed a, GGLfixed b, int shift) CONST; 197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulx(GGLfixed a, GGLfixed b, int shift) { 198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return GGLfixed((int64_t(a)*b + (1<<(shift-1)))>>shift); 199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulAddx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) CONST; 201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulAddx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) { 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return GGLfixed((int64_t(a)*b)>>shift) + c; 203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulSubx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) CONST; 205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulSubx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) { 206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return GGLfixed((int64_t(a)*b)>>shift) - c; 207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int64_t gglMulii(int32_t a, int32_t b) CONST; 209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int64_t gglMulii(int32_t a, int32_t b) { 210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return int64_t(a)*b; 211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ------------------------------------------------------------------------ 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulx(GGLfixed a, GGLfixed b) CONST; 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulx(GGLfixed a, GGLfixed b) { 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return gglMulx(a, b, 16); 220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulAddx(GGLfixed a, GGLfixed b, GGLfixed c) CONST; 222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulAddx(GGLfixed a, GGLfixed b, GGLfixed c) { 223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return gglMulAddx(a, b, c, 16); 224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulSubx(GGLfixed a, GGLfixed b, GGLfixed c) CONST; 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulSubx(GGLfixed a, GGLfixed b, GGLfixed c) { 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return gglMulSubx(a, b, c, 16); 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ------------------------------------------------------------------------ 231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int32_t gglClz(int32_t x) CONST; 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int32_t gglClz(int32_t x) 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if defined(__arm__) && !defined(__thumb__) 236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return __builtin_clz(x); 237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!x) return 32; 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int32_t exp = 31; 240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (x & 0xFFFF0000) { exp -=16; x >>= 16; } 241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (x & 0x0000ff00) { exp -= 8; x >>= 8; } 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (x & 0x000000f0) { exp -= 4; x >>= 4; } 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (x & 0x0000000c) { exp -= 2; x >>= 2; } 244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (x & 0x00000002) { exp -= 1; } 245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return exp; 246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ------------------------------------------------------------------------ 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint32_t gglDivQ(GGLfixed n, GGLfixed d, int32_t i) CONST; 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int32_t gglDivQ16(GGLfixed n, GGLfixed d) CONST; 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int32_t gglDivQ16(GGLfixed n, GGLfixed d) { 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return gglDivQ(n, d, 16); 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int32_t gglDivx(GGLfixed n, GGLfixed d) CONST; 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int32_t gglDivx(GGLfixed n, GGLfixed d) { 260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return gglDivQ(n, d, 16); 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ------------------------------------------------------------------------ 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglRecipFast(GGLfixed x) CONST; 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglRecipFast(GGLfixed x) 267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // This is a really bad approximation of 1/x, but it's also 269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // very fast. x must be strictly positive. 270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // if x between [0.5, 1[ , then 1/x = 3-2*x 271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // (we use 2.30 fixed-point) 272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const int32_t lz = gglClz(x); 273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return (0xC0000000 - (x << (lz - 1))) >> (30-lz); 274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ------------------------------------------------------------------------ 277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglClampx(GGLfixed c) CONST; 279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglClampx(GGLfixed c) 280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if defined(__thumb__) 282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // clamp without branches 283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project c &= ~(c>>31); c = FIXED_ONE - c; 284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project c &= ~(c>>31); c = FIXED_ONE - c; 285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if defined(__arm__) 287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // I don't know why gcc thinks its smarter than me! The code below 288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // clamps to zero in one instruction, but gcc won't generate it and 289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // replace it by a cmp + movlt (it's quite amazing actually). 290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asm("bic %0, %1, %1, asr #31\n" : "=r"(c) : "r"(c)); 291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project c &= ~(c>>31); 293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (c>FIXED_ONE) 295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project c = FIXED_ONE; 296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return c; 298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ------------------------------------------------------------------------ 301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif // ANDROID_GGL_FIXED_H 303