1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "rsContext.h"
18#include "rsScriptC.h"
19#include "rsMatrix4x4.h"
20#include "rsMatrix3x3.h"
21#include "rsMatrix2x2.h"
22#include "rsRuntime.h"
23
24#include "utils/Timers.h"
25#include "rsdCore.h"
26#include "rsdBcc.h"
27
28#include "rsdRuntime.h"
29//#include "rsdPath.h"
30#include "rsdAllocation.h"
31
32#include <time.h>
33
34using namespace android;
35using namespace android::renderscript;
36
37#define GET_TLS()  ScriptTLSStruct * tls = \
38    (ScriptTLSStruct *)pthread_getspecific(rsdgThreadTLSKey); \
39    Context * rsc = tls->mContext; \
40    ScriptC * sc = (ScriptC *) tls->mScript
41
42typedef float float2 __attribute__((ext_vector_type(2)));
43typedef float float3 __attribute__((ext_vector_type(3)));
44typedef float float4 __attribute__((ext_vector_type(4)));
45typedef char char2 __attribute__((ext_vector_type(2)));
46typedef char char3 __attribute__((ext_vector_type(3)));
47typedef char char4 __attribute__((ext_vector_type(4)));
48typedef unsigned char uchar2 __attribute__((ext_vector_type(2)));
49typedef unsigned char uchar3 __attribute__((ext_vector_type(3)));
50typedef unsigned char uchar4 __attribute__((ext_vector_type(4)));
51typedef short short2 __attribute__((ext_vector_type(2)));
52typedef short short3 __attribute__((ext_vector_type(3)));
53typedef short short4 __attribute__((ext_vector_type(4)));
54typedef unsigned short ushort2 __attribute__((ext_vector_type(2)));
55typedef unsigned short ushort3 __attribute__((ext_vector_type(3)));
56typedef unsigned short ushort4 __attribute__((ext_vector_type(4)));
57typedef int32_t int2 __attribute__((ext_vector_type(2)));
58typedef int32_t int3 __attribute__((ext_vector_type(3)));
59typedef int32_t int4 __attribute__((ext_vector_type(4)));
60typedef uint32_t uint2 __attribute__((ext_vector_type(2)));
61typedef uint32_t uint3 __attribute__((ext_vector_type(3)));
62typedef uint32_t uint4 __attribute__((ext_vector_type(4)));
63typedef long long long2 __attribute__((ext_vector_type(2)));
64typedef long long long3 __attribute__((ext_vector_type(3)));
65typedef long long long4 __attribute__((ext_vector_type(4)));
66typedef unsigned long long ulong2 __attribute__((ext_vector_type(2)));
67typedef unsigned long long ulong3 __attribute__((ext_vector_type(3)));
68typedef unsigned long long ulong4 __attribute__((ext_vector_type(4)));
69
70
71//////////////////////////////////////////////////////////////////////////////
72// Allocation
73//////////////////////////////////////////////////////////////////////////////
74
75
76static void SC_AllocationSyncAll2(Allocation *a, RsAllocationUsageType source) {
77    GET_TLS();
78    rsrAllocationSyncAll(rsc, sc, a, source);
79}
80
81static void SC_AllocationSyncAll(Allocation *a) {
82    GET_TLS();
83    rsrAllocationSyncAll(rsc, sc, a, RS_ALLOCATION_USAGE_SCRIPT);
84}
85
86static void SC_AllocationCopy1DRange(Allocation *dstAlloc,
87                                     uint32_t dstOff,
88                                     uint32_t dstMip,
89                                     uint32_t count,
90                                     Allocation *srcAlloc,
91                                     uint32_t srcOff, uint32_t srcMip) {
92    GET_TLS();
93    rsrAllocationCopy1DRange(rsc, dstAlloc, dstOff, dstMip, count,
94                             srcAlloc, srcOff, srcMip);
95}
96
97static void SC_AllocationCopy2DRange(Allocation *dstAlloc,
98                                     uint32_t dstXoff, uint32_t dstYoff,
99                                     uint32_t dstMip, uint32_t dstFace,
100                                     uint32_t width, uint32_t height,
101                                     Allocation *srcAlloc,
102                                     uint32_t srcXoff, uint32_t srcYoff,
103                                     uint32_t srcMip, uint32_t srcFace) {
104    GET_TLS();
105    rsrAllocationCopy2DRange(rsc, dstAlloc,
106                             dstXoff, dstYoff, dstMip, dstFace,
107                             width, height,
108                             srcAlloc,
109                             srcXoff, srcYoff, srcMip, srcFace);
110}
111
112
113//////////////////////////////////////////////////////////////////////////////
114//
115//////////////////////////////////////////////////////////////////////////////
116
117static void SC_SetObject(ObjectBase **dst, ObjectBase * src) {
118    GET_TLS();
119    rsrSetObject(rsc, sc, dst, src);
120}
121
122static void SC_ClearObject(ObjectBase **dst) {
123    GET_TLS();
124    rsrClearObject(rsc, sc, dst);
125}
126
127static bool SC_IsObject(const ObjectBase *src) {
128    GET_TLS();
129    return rsrIsObject(rsc, sc, src);
130}
131
132
133
134
135static const Allocation * SC_GetAllocation(const void *ptr) {
136    GET_TLS();
137    return rsdScriptGetAllocationForPointer(rsc, sc, ptr);
138}
139
140static void SC_ForEach_SAA(Script *target,
141                            Allocation *in,
142                            Allocation *out) {
143    GET_TLS();
144    rsrForEach(rsc, sc, target, in, out, NULL, 0, NULL);
145}
146
147static void SC_ForEach_SAAU(Script *target,
148                            Allocation *in,
149                            Allocation *out,
150                            const void *usr) {
151    GET_TLS();
152    rsrForEach(rsc, sc, target, in, out, usr, 0, NULL);
153}
154
155static void SC_ForEach_SAAUS(Script *target,
156                             Allocation *in,
157                             Allocation *out,
158                             const void *usr,
159                             const RsScriptCall *call) {
160    GET_TLS();
161    rsrForEach(rsc, sc, target, in, out, usr, 0, call);
162}
163
164static void SC_ForEach_SAAUL(Script *target,
165                             Allocation *in,
166                             Allocation *out,
167                             const void *usr,
168                             uint32_t usrLen) {
169    GET_TLS();
170    rsrForEach(rsc, sc, target, in, out, usr, usrLen, NULL);
171}
172
173static void SC_ForEach_SAAULS(Script *target,
174                              Allocation *in,
175                              Allocation *out,
176                              const void *usr,
177                              uint32_t usrLen,
178                              const RsScriptCall *call) {
179    GET_TLS();
180    rsrForEach(rsc, sc, target, in, out, usr, usrLen, call);
181}
182
183
184
185//////////////////////////////////////////////////////////////////////////////
186// Time routines
187//////////////////////////////////////////////////////////////////////////////
188
189static float SC_GetDt() {
190    GET_TLS();
191    return rsrGetDt(rsc, sc);
192}
193
194time_t SC_Time(time_t *timer) {
195    GET_TLS();
196    return rsrTime(rsc, sc, timer);
197}
198
199tm* SC_LocalTime(tm *local, time_t *timer) {
200    GET_TLS();
201    return rsrLocalTime(rsc, sc, local, timer);
202}
203
204int64_t SC_UptimeMillis() {
205    GET_TLS();
206    return rsrUptimeMillis(rsc, sc);
207}
208
209int64_t SC_UptimeNanos() {
210    GET_TLS();
211    return rsrUptimeNanos(rsc, sc);
212}
213
214//////////////////////////////////////////////////////////////////////////////
215// Message routines
216//////////////////////////////////////////////////////////////////////////////
217
218static uint32_t SC_ToClient2(int cmdID, void *data, int len) {
219    GET_TLS();
220    return rsrToClient(rsc, sc, cmdID, data, len);
221}
222
223static uint32_t SC_ToClient(int cmdID) {
224    GET_TLS();
225    return rsrToClient(rsc, sc, cmdID, NULL, 0);
226}
227
228static uint32_t SC_ToClientBlocking2(int cmdID, void *data, int len) {
229    GET_TLS();
230    return rsrToClientBlocking(rsc, sc, cmdID, data, len);
231}
232
233static uint32_t SC_ToClientBlocking(int cmdID) {
234    GET_TLS();
235    return rsrToClientBlocking(rsc, sc, cmdID, NULL, 0);
236}
237
238int SC_divsi3(int a, int b) {
239    return a / b;
240}
241
242int SC_modsi3(int a, int b) {
243    return a % b;
244}
245
246unsigned int SC_udivsi3(unsigned int a, unsigned int b) {
247    return a / b;
248}
249
250unsigned int SC_umodsi3(unsigned int a, unsigned int b) {
251    return a % b;
252}
253
254static void SC_debugF(const char *s, float f) {
255    ALOGD("%s %f, 0x%08x", s, f, *((int *) (&f)));
256}
257static void SC_debugFv2(const char *s, float f1, float f2) {
258    ALOGD("%s {%f, %f}", s, f1, f2);
259}
260static void SC_debugFv3(const char *s, float f1, float f2, float f3) {
261    ALOGD("%s {%f, %f, %f}", s, f1, f2, f3);
262}
263static void SC_debugFv4(const char *s, float f1, float f2, float f3, float f4) {
264    ALOGD("%s {%f, %f, %f, %f}", s, f1, f2, f3, f4);
265}
266static void SC_debugF2(const char *s, float2 f) {
267    ALOGD("%s {%f, %f}", s, f.x, f.y);
268}
269static void SC_debugF3(const char *s, float3 f) {
270    ALOGD("%s {%f, %f, %f}", s, f.x, f.y, f.z);
271}
272static void SC_debugF4(const char *s, float4 f) {
273    ALOGD("%s {%f, %f, %f, %f}", s, f.x, f.y, f.z, f.w);
274}
275static void SC_debugD(const char *s, double d) {
276    ALOGD("%s %f, 0x%08llx", s, d, *((long long *) (&d)));
277}
278static void SC_debugFM4v4(const char *s, const float *f) {
279    ALOGD("%s {%f, %f, %f, %f", s, f[0], f[4], f[8], f[12]);
280    ALOGD("%s  %f, %f, %f, %f", s, f[1], f[5], f[9], f[13]);
281    ALOGD("%s  %f, %f, %f, %f", s, f[2], f[6], f[10], f[14]);
282    ALOGD("%s  %f, %f, %f, %f}", s, f[3], f[7], f[11], f[15]);
283}
284static void SC_debugFM3v3(const char *s, const float *f) {
285    ALOGD("%s {%f, %f, %f", s, f[0], f[3], f[6]);
286    ALOGD("%s  %f, %f, %f", s, f[1], f[4], f[7]);
287    ALOGD("%s  %f, %f, %f}",s, f[2], f[5], f[8]);
288}
289static void SC_debugFM2v2(const char *s, const float *f) {
290    ALOGD("%s {%f, %f", s, f[0], f[2]);
291    ALOGD("%s  %f, %f}",s, f[1], f[3]);
292}
293static void SC_debugI8(const char *s, char c) {
294    ALOGD("%s %hhd  0x%hhx", s, c, (unsigned char)c);
295}
296static void SC_debugC2(const char *s, char2 c) {
297    ALOGD("%s {%hhd, %hhd}  0x%hhx 0x%hhx", s, c.x, c.y, (unsigned char)c.x, (unsigned char)c.y);
298}
299static void SC_debugC3(const char *s, char3 c) {
300    ALOGD("%s {%hhd, %hhd, %hhd}  0x%hhx 0x%hhx 0x%hhx", s, c.x, c.y, c.z, (unsigned char)c.x, (unsigned char)c.y, (unsigned char)c.z);
301}
302static void SC_debugC4(const char *s, char4 c) {
303    ALOGD("%s {%hhd, %hhd, %hhd, %hhd}  0x%hhx 0x%hhx 0x%hhx 0x%hhx", s, c.x, c.y, c.z, c.w, (unsigned char)c.x, (unsigned char)c.y, (unsigned char)c.z, (unsigned char)c.w);
304}
305static void SC_debugU8(const char *s, unsigned char c) {
306    ALOGD("%s %hhu  0x%hhx", s, c, c);
307}
308static void SC_debugUC2(const char *s, uchar2 c) {
309    ALOGD("%s {%hhu, %hhu}  0x%hhx 0x%hhx", s, c.x, c.y, c.x, c.y);
310}
311static void SC_debugUC3(const char *s, uchar3 c) {
312    ALOGD("%s {%hhu, %hhu, %hhu}  0x%hhx 0x%hhx 0x%hhx", s, c.x, c.y, c.z, c.x, c.y, c.z);
313}
314static void SC_debugUC4(const char *s, uchar4 c) {
315    ALOGD("%s {%hhu, %hhu, %hhu, %hhu}  0x%hhx 0x%hhx 0x%hhx 0x%hhx", s, c.x, c.y, c.z, c.w, c.x, c.y, c.z, c.w);
316}
317static void SC_debugI16(const char *s, short c) {
318    ALOGD("%s %hd  0x%hx", s, c, c);
319}
320static void SC_debugS2(const char *s, short2 c) {
321    ALOGD("%s {%hd, %hd}  0x%hx 0x%hx", s, c.x, c.y, c.x, c.y);
322}
323static void SC_debugS3(const char *s, short3 c) {
324    ALOGD("%s {%hd, %hd, %hd}  0x%hx 0x%hx 0x%hx", s, c.x, c.y, c.z, c.x, c.y, c.z);
325}
326static void SC_debugS4(const char *s, short4 c) {
327    ALOGD("%s {%hd, %hd, %hd, %hd}  0x%hx 0x%hx 0x%hx 0x%hx", s, c.x, c.y, c.z, c.w, c.x, c.y, c.z, c.w);
328}
329static void SC_debugU16(const char *s, unsigned short c) {
330    ALOGD("%s %hu  0x%hx", s, c, c);
331}
332static void SC_debugUS2(const char *s, ushort2 c) {
333    ALOGD("%s {%hu, %hu}  0x%hx 0x%hx", s, c.x, c.y, c.x, c.y);
334}
335static void SC_debugUS3(const char *s, ushort3 c) {
336    ALOGD("%s {%hu, %hu, %hu}  0x%hx 0x%hx 0x%hx", s, c.x, c.y, c.z, c.x, c.y, c.z);
337}
338static void SC_debugUS4(const char *s, ushort4 c) {
339    ALOGD("%s {%hu, %hu, %hu, %hu}  0x%hx 0x%hx 0x%hx 0x%hx", s, c.x, c.y, c.z, c.w, c.x, c.y, c.z, c.w);
340}
341static void SC_debugI32(const char *s, int32_t i) {
342    ALOGD("%s %d  0x%x", s, i, i);
343}
344static void SC_debugI2(const char *s, int2 i) {
345    ALOGD("%s {%d, %d}  0x%x 0x%x", s, i.x, i.y, i.x, i.y);
346}
347static void SC_debugI3(const char *s, int3 i) {
348    ALOGD("%s {%d, %d, %d}  0x%x 0x%x 0x%x", s, i.x, i.y, i.z, i.x, i.y, i.z);
349}
350static void SC_debugI4(const char *s, int4 i) {
351    ALOGD("%s {%d, %d, %d, %d}  0x%x 0x%x 0x%x 0x%x", s, i.x, i.y, i.z, i.w, i.x, i.y, i.z, i.w);
352}
353static void SC_debugU32(const char *s, uint32_t i) {
354    ALOGD("%s %u  0x%x", s, i, i);
355}
356static void SC_debugUI2(const char *s, uint2 i) {
357    ALOGD("%s {%u, %u}  0x%x 0x%x", s, i.x, i.y, i.x, i.y);
358}
359static void SC_debugUI3(const char *s, uint3 i) {
360    ALOGD("%s {%u, %u, %u}  0x%x 0x%x 0x%x", s, i.x, i.y, i.z, i.x, i.y, i.z);
361}
362static void SC_debugUI4(const char *s, uint4 i) {
363    ALOGD("%s {%u, %u, %u, %u}  0x%x 0x%x 0x%x 0x%x", s, i.x, i.y, i.z, i.w, i.x, i.y, i.z, i.w);
364}
365static void SC_debugLL64(const char *s, long long ll) {
366    ALOGD("%s %lld  0x%llx", s, ll, ll);
367}
368static void SC_debugL2(const char *s, long2 ll) {
369    ALOGD("%s {%lld, %lld}  0x%llx 0x%llx", s, ll.x, ll.y, ll.x, ll.y);
370}
371static void SC_debugL3(const char *s, long3 ll) {
372    ALOGD("%s {%lld, %lld, %lld}  0x%llx 0x%llx 0x%llx", s, ll.x, ll.y, ll.z, ll.x, ll.y, ll.z);
373}
374static void SC_debugL4(const char *s, long4 ll) {
375    ALOGD("%s {%lld, %lld, %lld, %lld}  0x%llx 0x%llx 0x%llx 0x%llx", s, ll.x, ll.y, ll.z, ll.w, ll.x, ll.y, ll.z, ll.w);
376}
377static void SC_debugULL64(const char *s, unsigned long long ll) {
378    ALOGD("%s %llu  0x%llx", s, ll, ll);
379}
380static void SC_debugUL2(const char *s, ulong2 ll) {
381    ALOGD("%s {%llu, %llu}  0x%llx 0x%llx", s, ll.x, ll.y, ll.x, ll.y);
382}
383static void SC_debugUL3(const char *s, ulong3 ll) {
384    ALOGD("%s {%llu, %llu, %llu}  0x%llx 0x%llx 0x%llx", s, ll.x, ll.y, ll.z, ll.x, ll.y, ll.z);
385}
386static void SC_debugUL4(const char *s, ulong4 ll) {
387    ALOGD("%s {%llu, %llu, %llu, %llu}  0x%llx 0x%llx 0x%llx 0x%llx", s, ll.x, ll.y, ll.z, ll.w, ll.x, ll.y, ll.z, ll.w);
388}
389static void SC_debugP(const char *s, const void *p) {
390    ALOGD("%s %p", s, p);
391}
392
393
394//////////////////////////////////////////////////////////////////////////////
395// Stub implementation
396//////////////////////////////////////////////////////////////////////////////
397
398// llvm name mangling ref
399//  <builtin-type> ::= v  # void
400//                 ::= b  # bool
401//                 ::= c  # char
402//                 ::= a  # signed char
403//                 ::= h  # unsigned char
404//                 ::= s  # short
405//                 ::= t  # unsigned short
406//                 ::= i  # int
407//                 ::= j  # unsigned int
408//                 ::= l  # long
409//                 ::= m  # unsigned long
410//                 ::= x  # long long, __int64
411//                 ::= y  # unsigned long long, __int64
412//                 ::= f  # float
413//                 ::= d  # double
414
415static RsdSymbolTable gSyms[] = {
416    { "memset", (void *)&memset, true },
417    { "memcpy", (void *)&memcpy, true },
418
419    // Refcounting
420    { "_Z11rsSetObjectP10rs_elementS_", (void *)&SC_SetObject, true },
421    { "_Z13rsClearObjectP10rs_element", (void *)&SC_ClearObject, true },
422    { "_Z10rsIsObject10rs_element", (void *)&SC_IsObject, true },
423
424    { "_Z11rsSetObjectP7rs_typeS_", (void *)&SC_SetObject, true },
425    { "_Z13rsClearObjectP7rs_type", (void *)&SC_ClearObject, true },
426    { "_Z10rsIsObject7rs_type", (void *)&SC_IsObject, true },
427
428    { "_Z11rsSetObjectP13rs_allocationS_", (void *)&SC_SetObject, true },
429    { "_Z13rsClearObjectP13rs_allocation", (void *)&SC_ClearObject, true },
430    { "_Z10rsIsObject13rs_allocation", (void *)&SC_IsObject, true },
431
432    { "_Z11rsSetObjectP10rs_samplerS_", (void *)&SC_SetObject, true },
433    { "_Z13rsClearObjectP10rs_sampler", (void *)&SC_ClearObject, true },
434    { "_Z10rsIsObject10rs_sampler", (void *)&SC_IsObject, true },
435
436    { "_Z11rsSetObjectP9rs_scriptS_", (void *)&SC_SetObject, true },
437    { "_Z13rsClearObjectP9rs_script", (void *)&SC_ClearObject, true },
438    { "_Z10rsIsObject9rs_script", (void *)&SC_IsObject, true },
439
440    { "_Z11rsSetObjectP7rs_pathS_", (void *)&SC_SetObject, true },
441    { "_Z13rsClearObjectP7rs_path", (void *)&SC_ClearObject, true },
442    { "_Z10rsIsObject7rs_path", (void *)&SC_IsObject, true },
443
444    { "_Z11rsSetObjectP7rs_meshS_", (void *)&SC_SetObject, true },
445    { "_Z13rsClearObjectP7rs_mesh", (void *)&SC_ClearObject, true },
446    { "_Z10rsIsObject7rs_mesh", (void *)&SC_IsObject, true },
447
448    { "_Z11rsSetObjectP19rs_program_fragmentS_", (void *)&SC_SetObject, true },
449    { "_Z13rsClearObjectP19rs_program_fragment", (void *)&SC_ClearObject, true },
450    { "_Z10rsIsObject19rs_program_fragment", (void *)&SC_IsObject, true },
451
452    { "_Z11rsSetObjectP17rs_program_vertexS_", (void *)&SC_SetObject, true },
453    { "_Z13rsClearObjectP17rs_program_vertex", (void *)&SC_ClearObject, true },
454    { "_Z10rsIsObject17rs_program_vertex", (void *)&SC_IsObject, true },
455
456    { "_Z11rsSetObjectP17rs_program_rasterS_", (void *)&SC_SetObject, true },
457    { "_Z13rsClearObjectP17rs_program_raster", (void *)&SC_ClearObject, true },
458    { "_Z10rsIsObject17rs_program_raster", (void *)&SC_IsObject, true },
459
460    { "_Z11rsSetObjectP16rs_program_storeS_", (void *)&SC_SetObject, true },
461    { "_Z13rsClearObjectP16rs_program_store", (void *)&SC_ClearObject, true },
462    { "_Z10rsIsObject16rs_program_store", (void *)&SC_IsObject, true },
463
464    { "_Z11rsSetObjectP7rs_fontS_", (void *)&SC_SetObject, true },
465    { "_Z13rsClearObjectP7rs_font", (void *)&SC_ClearObject, true },
466    { "_Z10rsIsObject7rs_font", (void *)&SC_IsObject, true },
467
468    // Allocation ops
469    { "_Z21rsAllocationMarkDirty13rs_allocation", (void *)&SC_AllocationSyncAll, true },
470    { "_Z20rsgAllocationSyncAll13rs_allocation", (void *)&SC_AllocationSyncAll, false },
471    { "_Z20rsgAllocationSyncAll13rs_allocationj", (void *)&SC_AllocationSyncAll2, false },
472    { "_Z20rsgAllocationSyncAll13rs_allocation24rs_allocation_usage_type", (void *)&SC_AllocationSyncAll2, false },
473    { "_Z15rsGetAllocationPKv", (void *)&SC_GetAllocation, true },
474    { "_Z23rsAllocationCopy1DRange13rs_allocationjjjS_jj", (void *)&SC_AllocationCopy1DRange, false },
475    { "_Z23rsAllocationCopy2DRange13rs_allocationjjj26rs_allocation_cubemap_facejjS_jjjS0_", (void *)&SC_AllocationCopy2DRange, false },
476
477    // Messaging
478
479    { "_Z14rsSendToClienti", (void *)&SC_ToClient, false },
480    { "_Z14rsSendToClientiPKvj", (void *)&SC_ToClient2, false },
481    { "_Z22rsSendToClientBlockingi", (void *)&SC_ToClientBlocking, false },
482    { "_Z22rsSendToClientBlockingiPKvj", (void *)&SC_ToClientBlocking2, false },
483
484    { "_Z9rsForEach9rs_script13rs_allocationS0_", (void *)&SC_ForEach_SAA, true },
485    { "_Z9rsForEach9rs_script13rs_allocationS0_PKv", (void *)&SC_ForEach_SAAU, true },
486    { "_Z9rsForEach9rs_script13rs_allocationS0_PKvPK16rs_script_call_t", (void *)&SC_ForEach_SAAUS, true },
487    { "_Z9rsForEach9rs_script13rs_allocationS0_PKvj", (void *)&SC_ForEach_SAAUL, true },
488    { "_Z9rsForEach9rs_script13rs_allocationS0_PKvjPK16rs_script_call_t", (void *)&SC_ForEach_SAAULS, true },
489
490    // time
491    { "_Z6rsTimePi", (void *)&SC_Time, true },
492    { "_Z11rsLocaltimeP5rs_tmPKi", (void *)&SC_LocalTime, true },
493    { "_Z14rsUptimeMillisv", (void*)&SC_UptimeMillis, true },
494    { "_Z13rsUptimeNanosv", (void*)&SC_UptimeNanos, true },
495    { "_Z7rsGetDtv", (void*)&SC_GetDt, false },
496
497    // Debug
498    { "_Z7rsDebugPKcf", (void *)&SC_debugF, true },
499    { "_Z7rsDebugPKcff", (void *)&SC_debugFv2, true },
500    { "_Z7rsDebugPKcfff", (void *)&SC_debugFv3, true },
501    { "_Z7rsDebugPKcffff", (void *)&SC_debugFv4, true },
502    { "_Z7rsDebugPKcDv2_f", (void *)&SC_debugF2, true },
503    { "_Z7rsDebugPKcDv3_f", (void *)&SC_debugF3, true },
504    { "_Z7rsDebugPKcDv4_f", (void *)&SC_debugF4, true },
505    { "_Z7rsDebugPKcd", (void *)&SC_debugD, true },
506    { "_Z7rsDebugPKcPK12rs_matrix4x4", (void *)&SC_debugFM4v4, true },
507    { "_Z7rsDebugPKcPK12rs_matrix3x3", (void *)&SC_debugFM3v3, true },
508    { "_Z7rsDebugPKcPK12rs_matrix2x2", (void *)&SC_debugFM2v2, true },
509    { "_Z7rsDebugPKcc", (void *)&SC_debugI8, true },
510    { "_Z7rsDebugPKcDv2_c", (void *)&SC_debugC2, true },
511    { "_Z7rsDebugPKcDv3_c", (void *)&SC_debugC3, true },
512    { "_Z7rsDebugPKcDv4_c", (void *)&SC_debugC4, true },
513    { "_Z7rsDebugPKch", (void *)&SC_debugU8, true },
514    { "_Z7rsDebugPKcDv2_h", (void *)&SC_debugUC2, true },
515    { "_Z7rsDebugPKcDv3_h", (void *)&SC_debugUC3, true },
516    { "_Z7rsDebugPKcDv4_h", (void *)&SC_debugUC4, true },
517    { "_Z7rsDebugPKcs", (void *)&SC_debugI16, true },
518    { "_Z7rsDebugPKcDv2_s", (void *)&SC_debugS2, true },
519    { "_Z7rsDebugPKcDv3_s", (void *)&SC_debugS3, true },
520    { "_Z7rsDebugPKcDv4_s", (void *)&SC_debugS4, true },
521    { "_Z7rsDebugPKct", (void *)&SC_debugU16, true },
522    { "_Z7rsDebugPKcDv2_t", (void *)&SC_debugUS2, true },
523    { "_Z7rsDebugPKcDv3_t", (void *)&SC_debugUS3, true },
524    { "_Z7rsDebugPKcDv4_t", (void *)&SC_debugUS4, true },
525    { "_Z7rsDebugPKci", (void *)&SC_debugI32, true },
526    { "_Z7rsDebugPKcDv2_i", (void *)&SC_debugI2, true },
527    { "_Z7rsDebugPKcDv3_i", (void *)&SC_debugI3, true },
528    { "_Z7rsDebugPKcDv4_i", (void *)&SC_debugI4, true },
529    { "_Z7rsDebugPKcj", (void *)&SC_debugU32, true },
530    { "_Z7rsDebugPKcDv2_j", (void *)&SC_debugUI2, true },
531    { "_Z7rsDebugPKcDv3_j", (void *)&SC_debugUI3, true },
532    { "_Z7rsDebugPKcDv4_j", (void *)&SC_debugUI4, true },
533    // Both "long" and "unsigned long" need to be redirected to their
534    // 64-bit counterparts, since we have hacked Slang to use 64-bit
535    // for "long" on Arm (to be similar to Java).
536    { "_Z7rsDebugPKcl", (void *)&SC_debugLL64, true },
537    { "_Z7rsDebugPKcDv2_l", (void *)&SC_debugL2, true },
538    { "_Z7rsDebugPKcDv3_l", (void *)&SC_debugL3, true },
539    { "_Z7rsDebugPKcDv4_l", (void *)&SC_debugL4, true },
540    { "_Z7rsDebugPKcm", (void *)&SC_debugULL64, true },
541    { "_Z7rsDebugPKcDv2_m", (void *)&SC_debugUL2, true },
542    { "_Z7rsDebugPKcDv3_m", (void *)&SC_debugUL3, true },
543    { "_Z7rsDebugPKcDv4_m", (void *)&SC_debugUL4, true },
544    { "_Z7rsDebugPKcx", (void *)&SC_debugLL64, true },
545    { "_Z7rsDebugPKcDv2_x", (void *)&SC_debugL2, true },
546    { "_Z7rsDebugPKcDv3_x", (void *)&SC_debugL3, true },
547    { "_Z7rsDebugPKcDv4_x", (void *)&SC_debugL4, true },
548    { "_Z7rsDebugPKcy", (void *)&SC_debugULL64, true },
549    { "_Z7rsDebugPKcDv2_y", (void *)&SC_debugUL2, true },
550    { "_Z7rsDebugPKcDv3_y", (void *)&SC_debugUL3, true },
551    { "_Z7rsDebugPKcDv4_y", (void *)&SC_debugUL4, true },
552    { "_Z7rsDebugPKcPKv", (void *)&SC_debugP, true },
553
554    { NULL, NULL, false }
555};
556
557
558void* rsdLookupRuntimeStub(void* pContext, char const* name) {
559    ScriptC *s = (ScriptC *)pContext;
560    RsdSymbolTable *syms = gSyms;
561    const RsdSymbolTable *sym = rsdLookupSymbolMath(name);
562
563    if (!sym) {
564        while (syms->mPtr) {
565            if (!strcmp(syms->mName, name)) {
566                sym = syms;
567            }
568            syms++;
569        }
570    }
571
572    if (sym) {
573        s->mHal.info.isThreadable &= sym->threadable;
574        return sym->mPtr;
575    }
576    ALOGE("ScriptC sym lookup failed for %s", name);
577    return NULL;
578}
579
580
581