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} 193734f50c2fe5b8778370b687c29401effcb254862Duane Sand#elif defined(__mips__) && __mips_isa_rev < 6 194096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand 195096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand/*inline MIPS implementations*/ 196096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sandinline GGLfixed gglMulx(GGLfixed a, GGLfixed b, int shift) CONST; 197096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sandinline GGLfixed gglMulx(GGLfixed a, GGLfixed b, int shift) { 198096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand GGLfixed result,tmp,tmp1,tmp2; 199096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand 200096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand if (__builtin_constant_p(shift)) { 201096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand if (shift == 0) { 202096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand asm ("mult %[a], %[b] \t\n" 203096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "mflo %[res] \t\n" 204096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : [res]"=&r"(result),[tmp]"=&r"(tmp) 205096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : [a]"r"(a),[b]"r"(b) 206096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : "%hi","%lo" 207096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand ); 208096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand } else if (shift == 32) 209096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand { 210096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand asm ("mult %[a], %[b] \t\n" 211096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "li %[tmp],1\t\n" 212096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "sll %[tmp],%[tmp],0x1f\t\n" 213096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "mflo %[res] \t\n" 214096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "addu %[tmp1],%[tmp],%[res] \t\n" 215096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "sltu %[tmp1],%[tmp1],%[tmp]\t\n" /*obit*/ 216096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "sra %[tmp],%[tmp],0x1f \t\n" 217096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "mfhi %[res] \t\n" 218096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "addu %[res],%[res],%[tmp]\t\n" 219096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "addu %[res],%[res],%[tmp1]\t\n" 220096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : [res]"=&r"(result),[tmp]"=&r"(tmp),[tmp1]"=&r"(tmp1) 221096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : [a]"r"(a),[b]"r"(b),[shift]"I"(shift) 222096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : "%hi","%lo" 223096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand ); 224096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand } else if ((shift >0) && (shift < 32)) 225096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand { 226096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand asm ("mult %[a], %[b] \t\n" 227096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "li %[tmp],1 \t\n" 228096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "sll %[tmp],%[tmp],%[shiftm1] \t\n" 229096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "mflo %[res] \t\n" 230096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "addu %[tmp1],%[tmp],%[res] \t\n" 231096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "sltu %[tmp1],%[tmp1],%[tmp] \t\n" /*obit?*/ 232096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "addu %[res],%[res],%[tmp] \t\n" 233096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "mfhi %[tmp] \t\n" 234096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "addu %[tmp],%[tmp],%[tmp1] \t\n" 235096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "sll %[tmp],%[tmp],%[lshift] \t\n" 236096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "srl %[res],%[res],%[rshift] \t\n" 237096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "or %[res],%[res],%[tmp] \t\n" 238096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : [res]"=&r"(result),[tmp]"=&r"(tmp),[tmp1]"=&r"(tmp1),[tmp2]"=&r"(tmp2) 239096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : [a]"r"(a),[b]"r"(b),[lshift]"I"(32-shift),[rshift]"I"(shift),[shiftm1]"I"(shift-1) 240096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : "%hi","%lo" 241096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand ); 242096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand } else { 243096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand asm ("mult %[a], %[b] \t\n" 244096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "li %[tmp],1 \t\n" 245096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "sll %[tmp],%[tmp],%[shiftm1] \t\n" 246096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "mflo %[res] \t\n" 247096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "addu %[tmp1],%[tmp],%[res] \t\n" 248096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "sltu %[tmp1],%[tmp1],%[tmp] \t\n" /*obit?*/ 249096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "sra %[tmp2],%[tmp],0x1f \t\n" 250096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "addu %[res],%[res],%[tmp] \t\n" 251096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "mfhi %[tmp] \t\n" 252096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "addu %[tmp],%[tmp],%[tmp2] \t\n" 253096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "addu %[tmp],%[tmp],%[tmp1] \t\n" /*tmp=hi*/ 254096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "srl %[tmp2],%[res],%[rshift] \t\n" 255096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "srav %[res], %[tmp],%[rshift]\t\n" 256096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "sll %[tmp],%[tmp],1 \t\n" 257096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "sll %[tmp],%[tmp],%[norbits] \t\n" 258096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "or %[tmp],%[tmp],%[tmp2] \t\n" 259096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "movz %[res],%[tmp],%[bit5] \t\n" 260096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : [res]"=&r"(result),[tmp]"=&r"(tmp),[tmp1]"=&r"(tmp1),[tmp2]"=&r"(tmp2) 261096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : [a]"r"(a),[b]"r"(b),[norbits]"I"(~(shift)),[rshift]"I"(shift),[shiftm1] "I"(shift-1),[bit5]"I"(shift & 0x20) 262096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : "%hi","%lo" 263096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand ); 264096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand } 265096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand } else { 266096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand asm ("mult %[a], %[b] \t\n" 267096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "li %[tmp],1 \t\n" 268096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "sll %[tmp],%[tmp],%[shiftm1] \t\n" 269096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "mflo %[res] \t\n" 270096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "addu %[tmp1],%[tmp],%[res] \t\n" 271096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "sltu %[tmp1],%[tmp1],%[tmp] \t\n" /*obit?*/ 272096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "sra %[tmp2],%[tmp],0x1f \t\n" 273096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "addu %[res],%[res],%[tmp] \t\n" 274096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "mfhi %[tmp] \t\n" 275096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "addu %[tmp],%[tmp],%[tmp2] \t\n" 276096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "addu %[tmp],%[tmp],%[tmp1] \t\n" /*tmp=hi*/ 277096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "srl %[tmp2],%[res],%[rshift] \t\n" 278096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "srav %[res], %[tmp],%[rshift]\t\n" 279096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "sll %[tmp],%[tmp],1 \t\n" 280096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "sll %[tmp],%[tmp],%[norbits] \t\n" 281096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "or %[tmp],%[tmp],%[tmp2] \t\n" 282096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "movz %[res],%[tmp],%[bit5] \t\n" 283096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : [res]"=&r"(result),[tmp]"=&r"(tmp),[tmp1]"=&r"(tmp1),[tmp2]"=&r"(tmp2) 284096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : [a]"r"(a),[b]"r"(b),[norbits]"r"(~(shift)),[rshift] "r"(shift),[shiftm1]"r"(shift-1),[bit5] "r"(shift & 0x20) 285096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : "%hi","%lo" 286096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand ); 287096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand } 288096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand 289096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand return result; 290096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand} 291096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand 292096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sandinline GGLfixed gglMulAddx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) CONST; 293096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sandinline GGLfixed gglMulAddx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) { 294096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand GGLfixed result,t,tmp1,tmp2; 295096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand 296096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand if (__builtin_constant_p(shift)) { 297096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand if (shift == 0) { 298096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand asm ("mult %[a], %[b] \t\n" 299096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "mflo %[lo] \t\n" 300096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "addu %[lo],%[lo],%[c] \t\n" 301096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : [lo]"=&r"(result) 302096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : [a]"r"(a),[b]"r"(b),[c]"r"(c) 303096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : "%hi","%lo" 304096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand ); 305096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand } else if (shift == 32) { 306096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand asm ("mult %[a], %[b] \t\n" 307096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "mfhi %[lo] \t\n" 308096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "addu %[lo],%[lo],%[c] \t\n" 309096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : [lo]"=&r"(result) 310096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : [a]"r"(a),[b]"r"(b),[c]"r"(c) 311096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : "%hi","%lo" 312096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand ); 313096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand } else if ((shift>0) && (shift<32)) { 314096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand asm ("mult %[a], %[b] \t\n" 315096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "mflo %[res] \t\n" 316096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "mfhi %[t] \t\n" 317096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "srl %[res],%[res],%[rshift] \t\n" 318096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "sll %[t],%[t],%[lshift] \t\n" 319096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "or %[res],%[res],%[t] \t\n" 320096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "addu %[res],%[res],%[c] \t\n" 321096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : [res]"=&r"(result),[t]"=&r"(t) 322096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : [a]"r"(a),[b]"r"(b),[c]"r"(c),[lshift]"I"(32-shift),[rshift]"I"(shift) 323096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : "%hi","%lo" 324096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand ); 325096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand } else { 326096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand asm ("mult %[a], %[b] \t\n" 327096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "nor %[tmp1],$zero,%[shift]\t\n" 328096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "mflo %[res] \t\n" 329096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "mfhi %[t] \t\n" 330096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "srl %[res],%[res],%[shift] \t\n" 331096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "sll %[tmp2],%[t],1 \t\n" 332096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "sllv %[tmp2],%[tmp2],%[tmp1] \t\n" 333096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "or %[tmp1],%[tmp2],%[res] \t\n" 334096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "srav %[res],%[t],%[shift] \t\n" 335096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "andi %[tmp2],%[shift],0x20\t\n" 336096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "movz %[res],%[tmp1],%[tmp2]\t\n" 337096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "addu %[res],%[res],%[c] \t\n" 338096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : [res]"=&r"(result),[t]"=&r"(t),[tmp1]"=&r"(tmp1),[tmp2]"=&r"(tmp2) 339096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : [a]"r"(a),[b]"r"(b),[c]"r"(c),[shift]"I"(shift) 340096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : "%hi","%lo" 341096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand ); 342096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand } 343096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand } else { 344096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand asm ("mult %[a], %[b] \t\n" 345096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "nor %[tmp1],$zero,%[shift]\t\n" 346096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "mflo %[res] \t\n" 347096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "mfhi %[t] \t\n" 348096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "srl %[res],%[res],%[shift] \t\n" 349096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "sll %[tmp2],%[t],1 \t\n" 350096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "sllv %[tmp2],%[tmp2],%[tmp1] \t\n" 351096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "or %[tmp1],%[tmp2],%[res] \t\n" 352096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "srav %[res],%[t],%[shift] \t\n" 353096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "andi %[tmp2],%[shift],0x20\t\n" 354096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "movz %[res],%[tmp1],%[tmp2]\t\n" 355096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "addu %[res],%[res],%[c] \t\n" 356096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : [res]"=&r"(result),[t]"=&r"(t),[tmp1]"=&r"(tmp1),[tmp2]"=&r"(tmp2) 357096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : [a]"r"(a),[b]"r"(b),[c]"r"(c),[shift]"r"(shift) 358096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : "%hi","%lo" 359096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand ); 360096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand } 361096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand return result; 362096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand} 363096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand 364096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sandinline GGLfixed gglMulSubx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) CONST; 365096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sandinline GGLfixed gglMulSubx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) { 366096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand GGLfixed result,t,tmp1,tmp2; 367096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand 368096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand if (__builtin_constant_p(shift)) { 369096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand if (shift == 0) { 370096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand asm ("mult %[a], %[b] \t\n" 371096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "mflo %[lo] \t\n" 372096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "subu %[lo],%[lo],%[c] \t\n" 373096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : [lo]"=&r"(result) 374096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : [a]"r"(a),[b]"r"(b),[c]"r"(c) 375096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : "%hi","%lo" 376096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand ); 377096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand } else if (shift == 32) { 378096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand asm ("mult %[a], %[b] \t\n" 379096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "mfhi %[lo] \t\n" 380096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "subu %[lo],%[lo],%[c] \t\n" 381096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : [lo]"=&r"(result) 382096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : [a]"r"(a),[b]"r"(b),[c]"r"(c) 383096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : "%hi","%lo" 384096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand ); 385096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand } else if ((shift>0) && (shift<32)) { 386096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand asm ("mult %[a], %[b] \t\n" 387096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "mflo %[res] \t\n" 388096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "mfhi %[t] \t\n" 389096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "srl %[res],%[res],%[rshift] \t\n" 390096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "sll %[t],%[t],%[lshift] \t\n" 391096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "or %[res],%[res],%[t] \t\n" 392096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "subu %[res],%[res],%[c] \t\n" 393096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : [res]"=&r"(result),[t]"=&r"(t) 394096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : [a]"r"(a),[b]"r"(b),[c]"r"(c),[lshift]"I"(32-shift),[rshift]"I"(shift) 395096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : "%hi","%lo" 396096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand ); 397096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand } else { 398096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand asm ("mult %[a], %[b] \t\n" 399096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "nor %[tmp1],$zero,%[shift]\t\n" 400096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "mflo %[res] \t\n" 401096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "mfhi %[t] \t\n" 402096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "srl %[res],%[res],%[shift] \t\n" 403096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "sll %[tmp2],%[t],1 \t\n" 404096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "sllv %[tmp2],%[tmp2],%[tmp1] \t\n" 405096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "or %[tmp1],%[tmp2],%[res] \t\n" 406096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "srav %[res],%[t],%[shift] \t\n" 407096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "andi %[tmp2],%[shift],0x20\t\n" 408096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "movz %[res],%[tmp1],%[tmp2]\t\n" 409096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "subu %[res],%[res],%[c] \t\n" 410096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : [res]"=&r"(result),[t]"=&r"(t),[tmp1]"=&r"(tmp1),[tmp2]"=&r"(tmp2) 411096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : [a]"r"(a),[b]"r"(b),[c]"r"(c),[shift]"I"(shift) 412096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : "%hi","%lo" 413096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand ); 414096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand } 415096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand } else { 416096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand asm ("mult %[a], %[b] \t\n" 417096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "nor %[tmp1],$zero,%[shift]\t\n" 418096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "mflo %[res] \t\n" 419096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "mfhi %[t] \t\n" 420096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "srl %[res],%[res],%[shift] \t\n" 421096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "sll %[tmp2],%[t],1 \t\n" 422096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "sllv %[tmp2],%[tmp2],%[tmp1] \t\n" 423096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "or %[tmp1],%[tmp2],%[res] \t\n" 424096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "srav %[res],%[t],%[shift] \t\n" 425096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "andi %[tmp2],%[shift],0x20\t\n" 426096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "movz %[res],%[tmp1],%[tmp2]\t\n" 427096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "subu %[res],%[res],%[c] \t\n" 428096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : [res]"=&r"(result),[t]"=&r"(t),[tmp1]"=&r"(tmp1),[tmp2]"=&r"(tmp2) 429096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : [a]"r"(a),[b]"r"(b),[c]"r"(c),[shift]"r"(shift) 430096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : "%hi","%lo" 431096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand ); 432096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand } 433096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand return result; 434096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand} 435096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand 436096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sandinline int64_t gglMulii(int32_t x, int32_t y) CONST; 437096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sandinline int64_t gglMulii(int32_t x, int32_t y) { 438096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand union { 439096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand struct { 440096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand#if defined(__MIPSEL__) 441096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand int32_t lo; 442096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand int32_t hi; 443096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand#elif defined(__MIPSEB__) 444096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand int32_t hi; 445096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand int32_t lo; 446096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand#endif 447096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand } s; 448096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand int64_t res; 449096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand }u; 450096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand asm("mult %2, %3 \t\n" 451096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "mfhi %1 \t\n" 452096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand "mflo %0 \t\n" 453096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : "=r"(u.s.lo), "=&r"(u.s.hi) 454096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : "%r"(x), "r"(y) 455096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand : "%hi","%lo" 456096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand ); 457096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand return u.res; 458096041174b1d8cc09b06c51053b2b7e8545bd93fDuane Sand} 459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 460658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat#elif defined(__aarch64__) 461658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat 462658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat// inline AArch64 implementations 463658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat 464658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhatinline GGLfixed gglMulx(GGLfixed x, GGLfixed y, int shift) CONST; 465658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhatinline GGLfixed gglMulx(GGLfixed x, GGLfixed y, int shift) 466658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat{ 467658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat GGLfixed result; 468658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat GGLfixed round; 469658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat 470658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat asm("mov %x[round], #1 \n" 471658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat "lsl %x[round], %x[round], %x[shift] \n" 472658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat "lsr %x[round], %x[round], #1 \n" 473658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat "smaddl %x[result], %w[x], %w[y],%x[round] \n" 474658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat "lsr %x[result], %x[result], %x[shift] \n" 475658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat : [round]"=&r"(round), [result]"=&r"(result) \ 476658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat : [x]"r"(x), [y]"r"(y), [shift] "r"(shift) \ 477658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat : 478658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat ); 479658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat return result; 480658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat} 481658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhatinline GGLfixed gglMulAddx(GGLfixed x, GGLfixed y, GGLfixed a, int shift) CONST; 482658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhatinline GGLfixed gglMulAddx(GGLfixed x, GGLfixed y, GGLfixed a, int shift) 483658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat{ 484658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat GGLfixed result; 485658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat asm("smull %x[result], %w[x], %w[y] \n" 486658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat "lsr %x[result], %x[result], %x[shift] \n" 487658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat "add %w[result], %w[result], %w[a] \n" 488658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat : [result]"=&r"(result) \ 489658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat : [x]"r"(x), [y]"r"(y), [a]"r"(a), [shift] "r"(shift) \ 490658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat : 491658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat ); 492658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat return result; 493658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat} 494658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat 495658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhatinline GGLfixed gglMulSubx(GGLfixed x, GGLfixed y, GGLfixed a, int shift) CONST; 496658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhatinline GGLfixed gglMulSubx(GGLfixed x, GGLfixed y, GGLfixed a, int shift) 497658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat{ 498658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat 499658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat GGLfixed result; 500658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat int rshift; 501658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat 502658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat asm("smull %x[result], %w[x], %w[y] \n" 503658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat "lsr %x[result], %x[result], %x[shift] \n" 504658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat "sub %w[result], %w[result], %w[a] \n" 505658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat : [result]"=&r"(result) \ 506658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat : [x]"r"(x), [y]"r"(y), [a]"r"(a), [shift] "r"(shift) \ 507658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat : 508658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat ); 509658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat return result; 510658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat} 511658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhatinline int64_t gglMulii(int32_t x, int32_t y) CONST; 512658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhatinline int64_t gglMulii(int32_t x, int32_t y) 513658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat{ 514658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat int64_t res; 515658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat asm("smull %x0, %w1, %w2 \n" 516658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat : "=r"(res) 517658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat : "%r"(x), "r"(y) 518658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat : 519658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat ); 520658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat return res; 521658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat} 522658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat 523606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#elif defined(__mips__) && __mips_isa_rev == 6 524606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 525606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes/*inline MIPS implementations*/ 526606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesinline GGLfixed gglMulx(GGLfixed a, GGLfixed b, int shift) CONST; 527606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesinline GGLfixed gglMulx(GGLfixed a, GGLfixed b, int shift) { 528606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes GGLfixed result,tmp,tmp1,tmp2; 529606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 530606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (__builtin_constant_p(shift)) { 531606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (shift == 0) { 532606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes asm ("mul %[res], %[a], %[b] \t\n" 533606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : [res]"=&r"(result) 534606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : [a]"r"(a),[b]"r"(b) 535606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes ); 536606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else if (shift == 32) 537606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes { 538606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes asm ("mul %[res], %[a], %[b] \t\n" 539606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "li %[tmp],1\t\n" 540606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "sll %[tmp],%[tmp],0x1f\t\n" 541606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "addu %[tmp1],%[tmp],%[res] \t\n" 542606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "muh %[res], %[a], %[b] \t\n" 543606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "sltu %[tmp1],%[tmp1],%[tmp]\t\n" /*obit*/ 544606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "sra %[tmp],%[tmp],0x1f \t\n" 545606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "addu %[res],%[res],%[tmp]\t\n" 546606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "addu %[res],%[res],%[tmp1]\t\n" 547606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : [res]"=&r"(result),[tmp]"=&r"(tmp),[tmp1]"=&r"(tmp1) 548606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : [a]"r"(a),[b]"r"(b),[shift]"I"(shift) 549606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes ); 550606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else if ((shift >0) && (shift < 32)) 551606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes { 552606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes asm ("mul %[res], %[a], %[b] \t\n" 553606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "li %[tmp],1 \t\n" 554606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "sll %[tmp],%[tmp],%[shiftm1] \t\n" 555606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "addu %[tmp1],%[tmp],%[res] \t\n" 556606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "sltu %[tmp1],%[tmp1],%[tmp] \t\n" /*obit?*/ 557606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "addu %[res],%[res],%[tmp] \t\n" 558606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "muh %[tmp], %[a], %[b] \t\n" 559606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "addu %[tmp],%[tmp],%[tmp1] \t\n" 560606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "sll %[tmp],%[tmp],%[lshift] \t\n" 561606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "srl %[res],%[res],%[rshift] \t\n" 562606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "or %[res],%[res],%[tmp] \t\n" 563606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : [res]"=&r"(result),[tmp]"=&r"(tmp),[tmp1]"=&r"(tmp1),[tmp2]"=&r"(tmp2) 564606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : [a]"r"(a),[b]"r"(b),[lshift]"I"(32-shift),[rshift]"I"(shift),[shiftm1]"I"(shift-1) 565606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes ); 566606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else { 567606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes asm ("mul %[res], %[a], %[b] \t\n" 568606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "li %[tmp],1 \t\n" 569606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "sll %[tmp],%[tmp],%[shiftm1] \t\n" 570606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "addu %[tmp1],%[tmp],%[res] \t\n" 571606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "sltu %[tmp1],%[tmp1],%[tmp] \t\n" /*obit?*/ 572606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "sra %[tmp2],%[tmp],0x1f \t\n" 573606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "addu %[res],%[res],%[tmp] \t\n" 574606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "muh %[tmp], %[a], %[b] \t\n" 575606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "addu %[tmp],%[tmp],%[tmp2] \t\n" 576606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "addu %[tmp],%[tmp],%[tmp1] \t\n" /*tmp=hi*/ 577606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "srl %[tmp2],%[res],%[rshift] \t\n" 578606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "srav %[res], %[tmp],%[rshift]\t\n" 579606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "sll %[tmp],%[tmp],1 \t\n" 580606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "sll %[tmp],%[tmp],%[norbits] \t\n" 581606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "or %[tmp],%[tmp],%[tmp2] \t\n" 582606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "seleqz %[tmp],%[tmp],%[bit5] \t\n" 583606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "selnez %[res],%[res],%[bit5] \t\n" 584606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "or %[res],%[res],%[tmp] \t\n" 585606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : [res]"=&r"(result),[tmp]"=&r"(tmp),[tmp1]"=&r"(tmp1),[tmp2]"=&r"(tmp2) 586606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : [a]"r"(a),[b]"r"(b),[norbits]"I"(~(shift)),[rshift]"I"(shift),[shiftm1] "I"(shift-1),[bit5]"I"(shift & 0x20) 587606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes ); 588606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 589606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else { 590606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes asm ("mul %[res], %[a], %[b] \t\n" 591606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "li %[tmp],1 \t\n" 592606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "sll %[tmp],%[tmp],%[shiftm1] \t\n" 593606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "addu %[tmp1],%[tmp],%[res] \t\n" 594606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "sltu %[tmp1],%[tmp1],%[tmp] \t\n" /*obit?*/ 595606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "sra %[tmp2],%[tmp],0x1f \t\n" 596606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "addu %[res],%[res],%[tmp] \t\n" 597606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "muh %[tmp], %[a], %[b] \t\n" 598606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "addu %[tmp],%[tmp],%[tmp2] \t\n" 599606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "addu %[tmp],%[tmp],%[tmp1] \t\n" /*tmp=hi*/ 600606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "srl %[tmp2],%[res],%[rshift] \t\n" 601606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "srav %[res], %[tmp],%[rshift]\t\n" 602606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "sll %[tmp],%[tmp],1 \t\n" 603606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "sll %[tmp],%[tmp],%[norbits] \t\n" 604606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "or %[tmp],%[tmp],%[tmp2] \t\n" 605606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "seleqz %[tmp],%[tmp],%[bit5] \t\n" 606606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "selnez %[res],%[res],%[bit5] \t\n" 607606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "or %[res],%[res],%[tmp] \t\n" 608606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : [res]"=&r"(result),[tmp]"=&r"(tmp),[tmp1]"=&r"(tmp1),[tmp2]"=&r"(tmp2) 609606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : [a]"r"(a),[b]"r"(b),[norbits]"r"(~(shift)),[rshift] "r"(shift),[shiftm1]"r"(shift-1),[bit5] "r"(shift & 0x20) 610606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes ); 611606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 612606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes return result; 613606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 614606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 615606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesinline GGLfixed gglMulAddx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) CONST; 616606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesinline GGLfixed gglMulAddx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) { 617606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes GGLfixed result,t,tmp1,tmp2; 618606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 619606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (__builtin_constant_p(shift)) { 620606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (shift == 0) { 621606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes asm ("mul %[lo], %[a], %[b] \t\n" 622606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "addu %[lo],%[lo],%[c] \t\n" 623606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : [lo]"=&r"(result) 624606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : [a]"r"(a),[b]"r"(b),[c]"r"(c) 625606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes ); 626606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else if (shift == 32) { 627606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes asm ("muh %[lo], %[a], %[b] \t\n" 628606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "addu %[lo],%[lo],%[c] \t\n" 629606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : [lo]"=&r"(result) 630606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : [a]"r"(a),[b]"r"(b),[c]"r"(c) 631606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes ); 632606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else if ((shift>0) && (shift<32)) { 633606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes asm ("mul %[res], %[a], %[b] \t\n" 634606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "muh %[t], %[a], %[b] \t\n" 635606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "srl %[res],%[res],%[rshift] \t\n" 636606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "sll %[t],%[t],%[lshift] \t\n" 637606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "or %[res],%[res],%[t] \t\n" 638606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "addu %[res],%[res],%[c] \t\n" 639606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : [res]"=&r"(result),[t]"=&r"(t) 640606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : [a]"r"(a),[b]"r"(b),[c]"r"(c),[lshift]"I"(32-shift),[rshift]"I"(shift) 641606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes ); 642606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else { 643606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes asm ("mul %[res], %[a], %[b] \t\n" 644606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "muh %[t], %[a], %[b] \t\n" 645606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "nor %[tmp1],$zero,%[shift]\t\n" 646606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "srl %[res],%[res],%[shift] \t\n" 647606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "sll %[tmp2],%[t],1 \t\n" 648606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "sllv %[tmp2],%[tmp2],%[tmp1] \t\n" 649606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "or %[tmp1],%[tmp2],%[res] \t\n" 650606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "srav %[res],%[t],%[shift] \t\n" 651606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "andi %[tmp2],%[shift],0x20\t\n" 652606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "seleqz %[tmp1],%[tmp1],%[tmp2]\t\n" 653606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "selnez %[res],%[res],%[tmp2]\t\n" 654606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "or %[res],%[res],%[tmp1]\t\n" 655606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "addu %[res],%[res],%[c] \t\n" 656606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : [res]"=&r"(result),[t]"=&r"(t),[tmp1]"=&r"(tmp1),[tmp2]"=&r"(tmp2) 657606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : [a]"r"(a),[b]"r"(b),[c]"r"(c),[shift]"I"(shift) 658606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes ); 659606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 660606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else { 661606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes asm ("mul %[res], %[a], %[b] \t\n" 662606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "muh %[t], %[a], %[b] \t\n" 663606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "nor %[tmp1],$zero,%[shift]\t\n" 664606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "srl %[res],%[res],%[shift] \t\n" 665606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "sll %[tmp2],%[t],1 \t\n" 666606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "sllv %[tmp2],%[tmp2],%[tmp1] \t\n" 667606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "or %[tmp1],%[tmp2],%[res] \t\n" 668606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "srav %[res],%[t],%[shift] \t\n" 669606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "andi %[tmp2],%[shift],0x20\t\n" 670606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "seleqz %[tmp1],%[tmp1],%[tmp2]\t\n" 671606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "selnez %[res],%[res],%[tmp2]\t\n" 672606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "or %[res],%[res],%[tmp1]\t\n" 673606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "addu %[res],%[res],%[c] \t\n" 674606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : [res]"=&r"(result),[t]"=&r"(t),[tmp1]"=&r"(tmp1),[tmp2]"=&r"(tmp2) 675606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : [a]"r"(a),[b]"r"(b),[c]"r"(c),[shift]"r"(shift) 676606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes ); 677606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 678606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes return result; 679606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 680606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 681606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesinline GGLfixed gglMulSubx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) CONST; 682606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesinline GGLfixed gglMulSubx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) { 683606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes GGLfixed result,t,tmp1,tmp2; 684606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 685606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (__builtin_constant_p(shift)) { 686606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes if (shift == 0) { 687606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes asm ("mul %[lo], %[a], %[b] \t\n" 688606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "subu %[lo],%[lo],%[c] \t\n" 689606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : [lo]"=&r"(result) 690606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : [a]"r"(a),[b]"r"(b),[c]"r"(c) 691606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes ); 692606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else if (shift == 32) { 693606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes asm ("muh %[lo], %[a], %[b] \t\n" 694606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "subu %[lo],%[lo],%[c] \t\n" 695606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : [lo]"=&r"(result) 696606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : [a]"r"(a),[b]"r"(b),[c]"r"(c) 697606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes ); 698606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else if ((shift>0) && (shift<32)) { 699606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes asm ("mul %[res], %[a], %[b] \t\n" 700606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "muh %[t], %[a], %[b] \t\n" 701606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "srl %[res],%[res],%[rshift] \t\n" 702606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "sll %[t],%[t],%[lshift] \t\n" 703606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "or %[res],%[res],%[t] \t\n" 704606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "subu %[res],%[res],%[c] \t\n" 705606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : [res]"=&r"(result),[t]"=&r"(t) 706606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : [a]"r"(a),[b]"r"(b),[c]"r"(c),[lshift]"I"(32-shift),[rshift]"I"(shift) 707606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes ); 708606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else { 709606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes asm ("mul %[res], %[a], %[b] \t\n" 710606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "muh %[t], %[a], %[b] \t\n" 711606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "nor %[tmp1],$zero,%[shift]\t\n" 712606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "srl %[res],%[res],%[shift] \t\n" 713606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "sll %[tmp2],%[t],1 \t\n" 714606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "sllv %[tmp2],%[tmp2],%[tmp1] \t\n" 715606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "or %[tmp1],%[tmp2],%[res] \t\n" 716606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "srav %[res],%[t],%[shift] \t\n" 717606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "andi %[tmp2],%[shift],0x20\t\n" 718606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "seleqz %[tmp1],%[tmp1],%[tmp2]\t\n" 719606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "selnez %[res],%[res],%[tmp2]\t\n" 720606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "or %[res],%[res],%[tmp1]\t\n" 721606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "subu %[res],%[res],%[c] \t\n" 722606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : [res]"=&r"(result),[t]"=&r"(t),[tmp1]"=&r"(tmp1),[tmp2]"=&r"(tmp2) 723606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : [a]"r"(a),[b]"r"(b),[c]"r"(c),[shift]"I"(shift) 724606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes ); 725606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 726606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } else { 727606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes asm ("mul %[res], %[a], %[b] \t\n" 728606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "muh %[t], %[a], %[b] \t\n" 729606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "nor %[tmp1],$zero,%[shift]\t\n" 730606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "srl %[res],%[res],%[shift] \t\n" 731606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "sll %[tmp2],%[t],1 \t\n" 732606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "sllv %[tmp2],%[tmp2],%[tmp1] \t\n" 733606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "or %[tmp1],%[tmp2],%[res] \t\n" 734606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "srav %[res],%[t],%[shift] \t\n" 735606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "andi %[tmp2],%[shift],0x20\t\n" 736606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "seleqz %[tmp1],%[tmp1],%[tmp2]\t\n" 737606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "selnez %[res],%[res],%[tmp2]\t\n" 738606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "or %[res],%[res],%[tmp1]\t\n" 739606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "subu %[res],%[res],%[c] \t\n" 740606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : [res]"=&r"(result),[t]"=&r"(t),[tmp1]"=&r"(tmp1),[tmp2]"=&r"(tmp2) 741606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : [a]"r"(a),[b]"r"(b),[c]"r"(c),[shift]"r"(shift) 742606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes ); 743606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } 744606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes return result; 745606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 746606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 747606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesinline int64_t gglMulii(int32_t x, int32_t y) CONST; 748606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesinline int64_t gglMulii(int32_t x, int32_t y) { 749606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes union { 750606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes struct { 751606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#if defined(__MIPSEL__) 752606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes int32_t lo; 753606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes int32_t hi; 754606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#elif defined(__MIPSEB__) 755606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes int32_t hi; 756606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes int32_t lo; 757606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#endif 758606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes } s; 759606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes int64_t res; 760606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes }u; 761606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes asm("mul %0, %2, %3 \t\n" 762606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes "muh %1, %2, %3 \t\n" 763606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : "=r"(u.s.lo), "=&r"(u.s.hi) 764606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes : "%r"(x), "r"(y) 765606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes ); 766606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes return u.res; 767606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes} 768606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes 769dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else // ---------------------------------------------------------------------- 770dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 771dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulx(GGLfixed a, GGLfixed b, int shift) CONST; 772dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulx(GGLfixed a, GGLfixed b, int shift) { 773dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return GGLfixed((int64_t(a)*b + (1<<(shift-1)))>>shift); 774dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 775dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulAddx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) CONST; 776dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulAddx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) { 777dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return GGLfixed((int64_t(a)*b)>>shift) + c; 778dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 779dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulSubx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) CONST; 780dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulSubx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) { 781dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return GGLfixed((int64_t(a)*b)>>shift) - c; 782dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 783dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int64_t gglMulii(int32_t a, int32_t b) CONST; 784dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int64_t gglMulii(int32_t a, int32_t b) { 785dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return int64_t(a)*b; 786dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 787dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 788dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 789dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 790dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ------------------------------------------------------------------------ 791dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 792dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulx(GGLfixed a, GGLfixed b) CONST; 793dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulx(GGLfixed a, GGLfixed b) { 794dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return gglMulx(a, b, 16); 795dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 796dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulAddx(GGLfixed a, GGLfixed b, GGLfixed c) CONST; 797dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulAddx(GGLfixed a, GGLfixed b, GGLfixed c) { 798dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return gglMulAddx(a, b, c, 16); 799dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 800dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulSubx(GGLfixed a, GGLfixed b, GGLfixed c) CONST; 801dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglMulSubx(GGLfixed a, GGLfixed b, GGLfixed c) { 802dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return gglMulSubx(a, b, c, 16); 803dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 804dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 805dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ------------------------------------------------------------------------ 806dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 807dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int32_t gglClz(int32_t x) CONST; 808dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int32_t gglClz(int32_t x) 809dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 810658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat#if (defined(__arm__) && !defined(__thumb__)) || defined(__mips__) || defined(__aarch64__) 811dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return __builtin_clz(x); 812dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 813dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!x) return 32; 814dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int32_t exp = 31; 815dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (x & 0xFFFF0000) { exp -=16; x >>= 16; } 816dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (x & 0x0000ff00) { exp -= 8; x >>= 8; } 817dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (x & 0x000000f0) { exp -= 4; x >>= 4; } 818dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (x & 0x0000000c) { exp -= 2; x >>= 2; } 819dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (x & 0x00000002) { exp -= 1; } 820dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return exp; 821dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 822dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 823dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 824dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ------------------------------------------------------------------------ 825dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 826dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint32_t gglDivQ(GGLfixed n, GGLfixed d, int32_t i) CONST; 827dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 828dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int32_t gglDivQ16(GGLfixed n, GGLfixed d) CONST; 829dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int32_t gglDivQ16(GGLfixed n, GGLfixed d) { 830dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return gglDivQ(n, d, 16); 831dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 832dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 833dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int32_t gglDivx(GGLfixed n, GGLfixed d) CONST; 834dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline int32_t gglDivx(GGLfixed n, GGLfixed d) { 835dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return gglDivQ(n, d, 16); 836dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 837dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 838dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ------------------------------------------------------------------------ 839dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 840dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglRecipFast(GGLfixed x) CONST; 841dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglRecipFast(GGLfixed x) 842dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 843dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // This is a really bad approximation of 1/x, but it's also 844dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // very fast. x must be strictly positive. 845dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // if x between [0.5, 1[ , then 1/x = 3-2*x 846dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // (we use 2.30 fixed-point) 847dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const int32_t lz = gglClz(x); 848dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return (0xC0000000 - (x << (lz - 1))) >> (30-lz); 849dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 850dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 851dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ------------------------------------------------------------------------ 852dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 853dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglClampx(GGLfixed c) CONST; 854dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectinline GGLfixed gglClampx(GGLfixed c) 855dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 856dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if defined(__thumb__) 857dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // clamp without branches 858dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project c &= ~(c>>31); c = FIXED_ONE - c; 859dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project c &= ~(c>>31); c = FIXED_ONE - c; 860dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 861dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if defined(__arm__) 862dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // I don't know why gcc thinks its smarter than me! The code below 863dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // clamps to zero in one instruction, but gcc won't generate it and 864dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // replace it by a cmp + movlt (it's quite amazing actually). 865dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asm("bic %0, %1, %1, asr #31\n" : "=r"(c) : "r"(c)); 866658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat#elif defined(__aarch64__) 867658f89dc5c418dbbc0c5d78f5861855b90ca8c9fAshok Bhat asm("bic %w0, %w1, %w1, asr #31\n" : "=r"(c) : "r"(c)); 868dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 869dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project c &= ~(c>>31); 870dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 871dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (c>FIXED_ONE) 872dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project c = FIXED_ONE; 873dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 874dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return c; 875dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 876dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 877dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ------------------------------------------------------------------------ 878dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 879dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif // ANDROID_GGL_FIXED_H 880