Merge "Build rules for running bcc_strip_attr." into jb-mr2-dev
diff --git a/lib/Renderscript/runtime/rs_cl.c b/lib/Renderscript/runtime/rs_cl.c
index 07ff538..e9720c2 100755
--- a/lib/Renderscript/runtime/rs_cl.c
+++ b/lib/Renderscript/runtime/rs_cl.c
@@ -412,7 +412,7 @@
 extern float __attribute__((overloadable)) pow(float, float);
 
 extern float __attribute__((overloadable)) exp10(float v) {
-    return pow(10.f, v);
+    return exp2(v * 3.321928095f);
 }
 FN_FUNC_FN(exp10)
 
@@ -474,7 +474,7 @@
 
 
 extern float __attribute__((overloadable)) log2(float v) {
-    return log10(v) / log10(2.f);
+    return log10(v) * 3.321928095f;
 }
 FN_FUNC_FN(log2)
 
diff --git a/lib/Renderscript/runtime/rs_core.c b/lib/Renderscript/runtime/rs_core.c
index dc026a9..f0c9490 100644
--- a/lib/Renderscript/runtime/rs_core.c
+++ b/lib/Renderscript/runtime/rs_core.c
@@ -51,3 +51,115 @@
 }
 
 
+extern int32_t __attribute__((overloadable)) rsAtomicCas(volatile int32_t *ptr, int32_t expectedValue, int32_t newValue) {
+    return __sync_val_compare_and_swap(ptr, expectedValue, newValue);
+}
+
+extern uint32_t __attribute__((overloadable)) rsAtomicCas(volatile uint32_t *ptr, uint32_t expectedValue, uint32_t newValue) {
+    return __sync_val_compare_and_swap((volatile int32_t *)ptr, (int32_t)expectedValue, (int32_t)newValue);
+}
+
+extern int32_t __attribute__((overloadable)) rsAtomicInc(volatile int32_t *ptr) {
+    return __sync_fetch_and_add(ptr, 1);
+}
+
+extern int32_t __attribute__((overloadable)) rsAtomicDec(volatile int32_t *ptr) {
+    return __sync_fetch_and_sub(ptr, 1);
+}
+
+extern int32_t __attribute__((overloadable)) rsAtomicAdd(volatile int32_t *ptr, int32_t value) {
+    return __sync_fetch_and_add(ptr, value);
+}
+
+extern int32_t __attribute__((overloadable)) rsAtomicSub(volatile int32_t *ptr, int32_t value) {
+    return __sync_fetch_and_sub(ptr, value);
+}
+
+extern int32_t __attribute__((overloadable)) rsAtomicAnd(volatile int32_t *ptr, int32_t value) {
+    return __sync_fetch_and_and(ptr, value);
+}
+
+extern int32_t __attribute__((overloadable)) rsAtomicOr(volatile int32_t *ptr, int32_t value) {
+    return __sync_fetch_and_or(ptr, value);
+}
+
+extern int32_t __attribute__((overloadable)) rsAtomicXor(volatile int32_t *ptr, int32_t value) {
+    return __sync_fetch_and_xor(ptr, value);
+}
+
+extern uint32_t __attribute__((overloadable)) min(uint32_t, uint32_t);
+extern int32_t __attribute__((overloadable)) min(int32_t, int32_t);
+extern uint32_t __attribute__((overloadable)) max(uint32_t, uint32_t);
+extern int32_t __attribute__((overloadable)) max(int32_t, int32_t);
+
+extern uint32_t __attribute__((overloadable)) rsAtomicMin(volatile uint32_t *ptr, uint32_t value) {
+    uint32_t prev, status;
+    do {
+        prev = *ptr;
+        uint32_t n = min(value, prev);
+        status = rsAtomicCas((volatile int32_t*) ptr, (int32_t) prev, (int32_t)n);
+    } while (status != prev);
+    return prev;
+}
+
+extern int32_t __attribute__((overloadable)) rsAtomicMin(volatile int32_t *ptr, int32_t value) {
+    int32_t prev, status;
+    do {
+        prev = *ptr;
+        int32_t n = min(value, prev);
+        status = rsAtomicCas(ptr, prev, n);
+    } while (status != prev);
+    return prev;
+}
+
+extern uint32_t __attribute__((overloadable)) rsAtomicMax(volatile uint32_t *ptr, uint32_t value) {
+    uint32_t prev, status;
+    do {
+        prev = *ptr;
+        uint32_t n = max(value, prev);
+        status = rsAtomicCas((volatile int32_t*) ptr, (int32_t) prev, (int32_t) n);
+    } while (status != prev);
+    return prev;
+}
+
+extern int32_t __attribute__((overloadable)) rsAtomicMax(volatile int32_t *ptr, int32_t value) {
+    int32_t prev, status;
+    do {
+        prev = *ptr;
+        int32_t n = max(value, prev);
+        status = rsAtomicCas(ptr, prev, n);
+    } while (status != prev);
+    return prev;
+}
+
+
+
+extern int32_t rand();
+#define RAND_MAX 0x7fffffff
+
+
+
+extern float __attribute__((overloadable)) rsRand(float min, float max);/* {
+    float r = (float)rand();
+    r /= RAND_MAX;
+    r = r * (max - min) + min;
+    return r;
+}
+*/
+
+extern float __attribute__((overloadable)) rsRand(float max) {
+    return rsRand(0.f, max);
+    //float r = (float)rand();
+    //r *= max;
+    //r /= RAND_MAX;
+    //return r;
+}
+
+extern int __attribute__((overloadable)) rsRand(int max) {
+    return (int)rsRand((float)max);
+}
+
+extern int __attribute__((overloadable)) rsRand(int min, int max) {
+    return (int)rsRand((float)min, (float)max);
+}
+
diff --git a/lib/Renderscript/runtime/rs_matrix.c b/lib/Renderscript/runtime/rs_matrix.c
index 7e040f7..0b29d30 100644
--- a/lib/Renderscript/runtime/rs_matrix.c
+++ b/lib/Renderscript/runtime/rs_matrix.c
@@ -236,3 +236,79 @@
 rsMatrixMultiply(rs_matrix3x3 *m, float2 in) {
     return rsMatrixMultiply((const rs_matrix3x3 *)m, in);
 }
+
+extern void __attribute__((overloadable))
+rsMatrixLoadMultiply(rs_matrix4x4 *ret, const rs_matrix4x4 *lhs, const rs_matrix4x4 *rhs) {
+    for (int i=0 ; i<4 ; i++) {
+        float ri0 = 0;
+        float ri1 = 0;
+        float ri2 = 0;
+        float ri3 = 0;
+        for (int j=0 ; j<4 ; j++) {
+            const float rhs_ij = rsMatrixGet(rhs, i, j);
+            ri0 += rsMatrixGet(lhs, j, 0) * rhs_ij;
+            ri1 += rsMatrixGet(lhs, j, 1) * rhs_ij;
+            ri2 += rsMatrixGet(lhs, j, 2) * rhs_ij;
+            ri3 += rsMatrixGet(lhs, j, 3) * rhs_ij;
+        }
+        rsMatrixSet(ret, i, 0, ri0);
+        rsMatrixSet(ret, i, 1, ri1);
+        rsMatrixSet(ret, i, 2, ri2);
+        rsMatrixSet(ret, i, 3, ri3);
+    }
+}
+
+extern void __attribute__((overloadable))
+rsMatrixLoadMultiply(rs_matrix4x4 *lhs, const rs_matrix4x4 *rhs) {
+    rs_matrix4x4 r;
+    rsMatrixLoadMultiply(&r, lhs, rhs);
+    rsMatrixLoad(lhs, &r);
+}
+
+extern void __attribute__((overloadable))
+rsMatrixLoadMultiply(rs_matrix3x3 *ret, const rs_matrix3x3 *lhs, const rs_matrix3x3 *rhs) {
+    for (int i=0 ; i<3 ; i++) {
+        float ri0 = 0;
+        float ri1 = 0;
+        float ri2 = 0;
+        for (int j=0 ; j<3 ; j++) {
+            const float rhs_ij = rsMatrixGet(rhs, i, j);
+            ri0 += rsMatrixGet(lhs, j, 0) * rhs_ij;
+            ri1 += rsMatrixGet(lhs, j, 1) * rhs_ij;
+            ri2 += rsMatrixGet(lhs, j, 2) * rhs_ij;
+        }
+        rsMatrixSet(ret, i, 0, ri0);
+        rsMatrixSet(ret, i, 1, ri1);
+        rsMatrixSet(ret, i, 2, ri2);
+    }
+}
+
+extern void __attribute__((overloadable))
+rsMatrixLoadMultiply(rs_matrix3x3 *lhs, const rs_matrix3x3 *rhs) {
+    rs_matrix3x3 r;
+    rsMatrixLoadMultiply(&r, lhs, rhs);
+    rsMatrixLoad(lhs, &r);
+}
+
+extern void __attribute__((overloadable))
+rsMatrixLoadMultiply(rs_matrix2x2 *ret, const rs_matrix2x2 *lhs, const rs_matrix2x2 *rhs) {
+    for (int i=0 ; i<2 ; i++) {
+        float ri0 = 0;
+        float ri1 = 0;
+        for (int j=0 ; j<2 ; j++) {
+            const float rhs_ij = rsMatrixGet(rhs, i, j);
+            ri0 += rsMatrixGet(lhs, j, 0) * rhs_ij;
+            ri1 += rsMatrixGet(lhs, j, 1) * rhs_ij;
+        }
+        rsMatrixSet(ret, i, 0, ri0);
+        rsMatrixSet(ret, i, 1, ri1);
+    }
+}
+
+extern void __attribute__((overloadable))
+rsMatrixLoadMultiply(rs_matrix2x2 *lhs, const rs_matrix2x2 *rhs) {
+    rs_matrix2x2 r;
+    rsMatrixLoadMultiply(&r, lhs, rhs);
+    rsMatrixLoad(lhs, &r);
+}
+