diff options
author | 2016-03-22 23:35:27 -0700 | |
---|---|---|
committer | 2016-03-28 19:13:17 +0200 | |
commit | 3e8fce48a6c768036c11290b93116665e8e8bdda (patch) | |
tree | 2fd1b823ca44198da04bc42e30f71f78ee1ed70f | |
parent | 88521f6219b5a8c81e08c347bbdf1413b852fa17 (diff) |
Switch GLES wrappers over to using Clang (and fix inline assembly).
Bug: http://b/18003438
The GLES wrapper implementations make direct calls to their underlying
function without specifying that they are retaining the original
argument register(s). This change makes the retention of these argument
registers more explicit, and then removes the LOCAL_CLANG override,
since Clang no longer optimizes the code into a bad state.
We also switch to "naked" functions, so that we control all stack layout
information. This prevents us from accidentally still corrupting
arguments on x86 (and for other functions with many parameters).
Change-Id: I37f2ef4a697373388950b41f0a292393c9fcbac7
-rw-r--r-- | opengl/libs/Android.mk | 3 | ||||
-rw-r--r-- | opengl/libs/GLES2/gl2.cpp | 263 | ||||
-rw-r--r-- | opengl/libs/GLES_CM/gl.cpp | 262 |
3 files changed, 344 insertions, 184 deletions
diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk index f389c9493b..4cbca63ca6 100644 --- a/opengl/libs/Android.mk +++ b/opengl/libs/Android.mk @@ -79,7 +79,6 @@ LOCAL_SRC_FILES:= \ GLES_CM/gl.cpp.arm \ # -LOCAL_CLANG := false LOCAL_SHARED_LIBRARIES += libcutils liblog libEGL LOCAL_MODULE:= libGLESv1_CM @@ -107,7 +106,6 @@ LOCAL_SRC_FILES:= \ GLES2/gl2.cpp \ # -LOCAL_CLANG := false LOCAL_ARM_MODE := arm LOCAL_SHARED_LIBRARIES += libcutils libutils liblog libEGL LOCAL_MODULE:= libGLESv2 @@ -135,7 +133,6 @@ LOCAL_SRC_FILES:= \ GLES2/gl2.cpp \ # -LOCAL_CLANG := false LOCAL_ARM_MODE := arm LOCAL_SHARED_LIBRARIES += libcutils libutils liblog libEGL LOCAL_MODULE:= libGLESv3 diff --git a/opengl/libs/GLES2/gl2.cpp b/opengl/libs/GLES2/gl2.cpp index 6034a8edc0..6dd87c28e4 100644 --- a/opengl/libs/GLES2/gl2.cpp +++ b/opengl/libs/GLES2/gl2.cpp @@ -34,39 +34,65 @@ using namespace android; #undef API_ENTRY #undef CALL_GL_API +#undef CALL_GL_API_INTERNAL_CALL +#undef CALL_GL_API_INTERNAL_SET_RETURN_VALUE +#undef CALL_GL_API_INTERNAL_DO_RETURN #undef CALL_GL_API_RETURN #if USE_SLOW_BINDING #define API_ENTRY(_api) _api - #define CALL_GL_API(_api, ...) \ + #define CALL_GL_API_INTERNAL_CALL(_api, ...) \ gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \ if (_c) return _c->_api(__VA_ARGS__); + #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE return 0; + + // This stays blank, since void functions will implicitly return, and + // all of the other functions will return 0 based on the previous macro. + #define CALL_GL_API_INTERNAL_DO_RETURN + #elif defined(__arm__) #define GET_TLS(reg) "mrc p15, 0, " #reg ", c13, c0, 3 \n" - #define API_ENTRY(_api) __attribute__((noinline)) _api - - #define CALL_GL_API(_api, ...) \ - asm volatile( \ - GET_TLS(r12) \ - "ldr r12, [r12, %[tls]] \n" \ - "cmp r12, #0 \n" \ - "ldrne pc, [r12, %[api]] \n" \ - : \ - : [tls] "J"(TLS_SLOT_OPENGL_API*4), \ - [api] "J"(__builtin_offsetof(gl_hooks_t, gl._api)) \ - : "r12" \ - ); + #define API_ENTRY(_api) __attribute__((naked,noinline)) _api + + #define CALL_GL_API_INTERNAL_CALL(_api, ...) \ + asm volatile( \ + GET_TLS(r12) \ + "ldr r12, [r12, %[tls]] \n" \ + "cmp r12, #0 \n" \ + "ldrne pc, [r12, %[api]] \n" \ + : \ + : [tls] "J"(TLS_SLOT_OPENGL_API*4), \ + [api] "J"(__builtin_offsetof(gl_hooks_t, gl._api)) \ + : "r0", "r1", "r2", "r3", "r12" \ + ); + + #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE \ + asm volatile( \ + "mov r0, #0 \n" \ + : \ + : \ + : "r0" \ + ); + + + #define CALL_GL_API_INTERNAL_DO_RETURN \ + asm volatile( \ + "bx lr \n" \ + : \ + : \ + : "r0" \ + ); #elif defined(__aarch64__) - #define API_ENTRY(_api) __attribute__((noinline)) _api + #define API_ENTRY(_api) __attribute__((naked,noinline)) _api - #define CALL_GL_API(_api, ...) \ + #define CALL_GL_API_INTERNAL_CALL(_api, ...) \ asm volatile( \ "mrs x16, tpidr_el0\n" \ "ldr x16, [x16, %[tls]]\n" \ @@ -77,121 +103,173 @@ using namespace android; : \ : [tls] "i" (TLS_SLOT_OPENGL_API * sizeof(void*)), \ [api] "i" (__builtin_offsetof(gl_hooks_t, gl._api)) \ - : "x16" \ + : "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x16" \ + ); + + #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE \ + asm volatile( \ + "mov w0, wzr \n" \ + : \ + : \ + : "w0" \ + ); + + #define CALL_GL_API_INTERNAL_DO_RETURN \ + asm volatile( \ + "ret \n" \ + : \ + : \ + : \ ); #elif defined(__i386__) - #define API_ENTRY(_api) __attribute__((noinline,optimize("omit-frame-pointer"))) _api + #define API_ENTRY(_api) __attribute__((naked,noinline)) _api - #define CALL_GL_API(_api, ...) \ - register void** fn; \ + #define CALL_GL_API_INTERNAL_CALL(_api, ...) \ __asm__ volatile( \ - "mov %%gs:0, %[fn]\n" \ - "mov %P[tls](%[fn]), %[fn]\n" \ - "test %[fn], %[fn]\n" \ + "mov %%gs:0, %%eax\n" \ + "mov %P[tls](%%eax), %%eax\n" \ + "test %%eax, %%eax\n" \ "je 1f\n" \ - "jmp *%P[api](%[fn])\n" \ + "jmp *%P[api](%%eax)\n" \ "1:\n" \ - : [fn] "=r" (fn) \ + : \ : [tls] "i" (TLS_SLOT_OPENGL_API*sizeof(void*)), \ [api] "i" (__builtin_offsetof(gl_hooks_t, gl._api)) \ - : "cc" \ + : "cc", "%eax" \ ); + #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE \ + __asm__ volatile( \ + "xor %%eax, %%eax\n" \ + : \ + : \ + : "%eax" \ + ); + + #define CALL_GL_API_INTERNAL_DO_RETURN \ + __asm__ volatile( \ + "ret\n" \ + : \ + : \ + : \ + ); + #elif defined(__x86_64__) - #define API_ENTRY(_api) __attribute__((noinline,optimize("omit-frame-pointer"))) _api + #define API_ENTRY(_api) __attribute__((naked,noinline)) _api - #define CALL_GL_API(_api, ...) \ - register void** fn; \ - __asm__ volatile( \ - "mov %%fs:0, %[fn]\n" \ - "mov %P[tls](%[fn]), %[fn]\n" \ - "test %[fn], %[fn]\n" \ + #define CALL_GL_API_INTERNAL_CALL(_api, ...) \ + __asm__ volatile( \ + "mov %%fs:0, %%rax\n" \ + "mov %P[tls](%%rax), %%rax\n" \ + "test %%rax, %%rax\n" \ "je 1f\n" \ - "jmp *%P[api](%[fn])\n" \ + "jmp *%P[api](%%rax)\n" \ "1:\n" \ - : [fn] "=r" (fn) \ + : \ : [tls] "i" (TLS_SLOT_OPENGL_API*sizeof(void*)), \ [api] "i" (__builtin_offsetof(gl_hooks_t, gl._api)) \ - : "cc" \ - ); + : "cc", "%rdi", "%rsi", "%rdx", "%rcx", "%r8", "%r9", \ + "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", \ + "%xmm6", "%xmm7" \ + ); + + #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE \ + __asm__ volatile( \ + "xor %%eax, %%eax\n" \ + : \ + : \ + : "%eax" \ + ); + + #define CALL_GL_API_INTERNAL_DO_RETURN \ + __asm__ volatile( \ + "retq\n" \ + : \ + : \ + : \ + ); #elif defined(__mips64) - #define API_ENTRY(_api) __attribute__((noinline)) _api - - #define CALL_GL_API(_api, ...) \ - register unsigned long _t0 asm("$12"); \ - register unsigned long _fn asm("$25"); \ - register unsigned long _tls asm("$3"); \ - register unsigned long _v0 asm("$2"); \ - asm volatile( \ - ".set push\n\t" \ - ".set noreorder\n\t" \ - "rdhwr %[tls], $29\n\t" \ - "ld %[t0], %[OPENGL_API](%[tls])\n\t" \ - "beqz %[t0], 1f\n\t" \ - " move %[fn], $ra\n\t" \ - "ld %[t0], %[API](%[t0])\n\t" \ - "beqz %[t0], 1f\n\t" \ - " nop\n\t" \ - "move %[fn], %[t0]\n\t" \ - "1:\n\t" \ - "jalr $0, %[fn]\n\t" \ - " move %[v0], $0\n\t" \ - ".set pop\n\t" \ - : [fn] "=c"(_fn), \ - [tls] "=&r"(_tls), \ - [t0] "=&r"(_t0), \ - [v0] "=&r"(_v0) \ - : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*sizeof(void*)),\ - [API] "I"(__builtin_offsetof(gl_hooks_t, gl._api)) \ - : \ + #define API_ENTRY(_api) __attribute__((naked,noinline)) _api + + // t0: $12 + // fn: $25 + // tls: $3 + // v0: $2 + #define CALL_GL_API_INTERNAL_CALL(_api, ...) \ + asm volatile( \ + ".set push\n\t" \ + ".set noreorder\n\t" \ + "rdhwr $3, $29\n\t" \ + "ld $12, %[OPENGL_API]($3)\n\t" \ + "beqz $12, 1f\n\t" \ + " move $25, $ra\n\t" \ + "ld $12, %[API]($12)\n\t" \ + "beqz $12, 1f\n\t" \ + " nop\n\t" \ + "move $25, $12\n\t" \ + "1:\n\t" \ + "jalr $0, $25\n\t" \ + " move $2, $0\n\t" \ + ".set pop\n\t" \ + : \ + : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*sizeof(void*)),\ + [API] "I"(__builtin_offsetof(gl_hooks_t, gl._api)) \ + : "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9", \ + "$10", "$11", "$12", "$25" \ ); + #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE + #define CALL_GL_API_INTERNAL_DO_RETURN + #elif defined(__mips__) - #define API_ENTRY(_api) __attribute__((noinline)) _api + #define API_ENTRY(_api) __attribute__((naked,noinline)) _api - #define CALL_GL_API(_api, ...) \ - register unsigned int _t0 asm("$8"); \ - register unsigned int _fn asm("$25"); \ - register unsigned int _tls asm("$3"); \ - register unsigned int _v0 asm("$2"); \ + // t0: $8 + // fn: $25 + // tls: $3 + // v0: $2 + #define CALL_GL_API_INTERNAL_CALL(_api, ...) \ asm volatile( \ ".set push\n\t" \ ".set noreorder\n\t" \ ".set mips32r2\n\t" \ - "rdhwr %[tls], $29\n\t" \ - "lw %[t0], %[OPENGL_API](%[tls])\n\t" \ - "beqz %[t0], 1f\n\t" \ - " move %[fn],$ra\n\t" \ - "lw %[t0], %[API](%[t0])\n\t" \ - "beqz %[t0], 1f\n\t" \ + "rdhwr $3, $29\n\t" \ + "lw $3, %[OPENGL_API]($3)\n\t" \ + "beqz $3, 1f\n\t" \ + " move $25,$ra\n\t" \ + "lw $3, %[API]($3)\n\t" \ + "beqz $3, 1f\n\t" \ " nop\n\t" \ - "move %[fn], %[t0]\n\t" \ + "move $25, $3\n\t" \ "1:\n\t" \ - "jalr $0, %[fn]\n\t" \ - " move %[v0], $0\n\t" \ + "jalr $0, $25\n\t" \ + " move $2, $0\n\t" \ ".set pop\n\t" \ - : [fn] "=c"(_fn), \ - [tls] "=&r"(_tls), \ - [t0] "=&r"(_t0), \ - [v0] "=&r"(_v0) \ + : \ : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*4), \ [API] "I"(__builtin_offsetof(gl_hooks_t, gl._api)) \ - : \ - ); + : "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$25" \ + ); -#endif + #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE + #define CALL_GL_API_INTERNAL_DO_RETURN -#define CALL_GL_API_RETURN(_api, ...) \ - CALL_GL_API(_api, __VA_ARGS__) \ - return 0; +#endif +#define CALL_GL_API(_api, ...) \ + CALL_GL_API_INTERNAL_CALL(_api, __VA_ARGS__) \ + CALL_GL_API_INTERNAL_DO_RETURN +#define CALL_GL_API_RETURN(_api, ...) \ + CALL_GL_API_INTERNAL_CALL(_api, __VA_ARGS__) \ + CALL_GL_API_INTERNAL_SET_RETURN_VALUE \ + CALL_GL_API_INTERNAL_DO_RETURN extern "C" { #pragma GCC diagnostic ignored "-Wunused-parameter" @@ -202,6 +280,9 @@ extern "C" { #undef API_ENTRY #undef CALL_GL_API +#undef CALL_GL_API_INTERNAL_CALL +#undef CALL_GL_API_INTERNAL_SET_RETURN_VALUE +#undef CALL_GL_API_INTERNAL_DO_RETURN #undef CALL_GL_API_RETURN /* diff --git a/opengl/libs/GLES_CM/gl.cpp b/opengl/libs/GLES_CM/gl.cpp index b1b31f8294..8bde4e5f04 100644 --- a/opengl/libs/GLES_CM/gl.cpp +++ b/opengl/libs/GLES_CM/gl.cpp @@ -90,39 +90,65 @@ GL_API void GL_APIENTRY glWeightPointerOESBounds(GLint size, GLenum type, #undef API_ENTRY #undef CALL_GL_API +#undef CALL_GL_API_INTERNAL_CALL +#undef CALL_GL_API_INTERNAL_SET_RETURN_VALUE +#undef CALL_GL_API_INTERNAL_DO_RETURN #undef CALL_GL_API_RETURN #if USE_SLOW_BINDING #define API_ENTRY(_api) _api - #define CALL_GL_API(_api, ...) \ + #define CALL_GL_API_INTERNAL_CALL(_api, ...) \ gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \ if (_c) return _c->_api(__VA_ARGS__); + #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE return 0; + + // This stays blank, since void functions will implicitly return, and + // all of the other functions will return 0 based on the previous macro. + #define CALL_GL_API_INTERNAL_DO_RETURN + #elif defined(__arm__) #define GET_TLS(reg) "mrc p15, 0, " #reg ", c13, c0, 3 \n" - #define API_ENTRY(_api) __attribute__((noinline)) _api + #define API_ENTRY(_api) __attribute__((naked,noinline)) _api - #define CALL_GL_API(_api, ...) \ - asm volatile( \ - GET_TLS(r12) \ - "ldr r12, [r12, %[tls]] \n" \ - "cmp r12, #0 \n" \ - "ldrne pc, [r12, %[api]] \n" \ - : \ - : [tls] "J"(TLS_SLOT_OPENGL_API*4), \ - [api] "J"(__builtin_offsetof(gl_hooks_t, gl._api)) \ - : "r12" \ - ); + #define CALL_GL_API_INTERNAL_CALL(_api, ...) \ + asm volatile( \ + GET_TLS(r12) \ + "ldr r12, [r12, %[tls]] \n" \ + "cmp r12, #0 \n" \ + "ldrne pc, [r12, %[api]] \n" \ + : \ + : [tls] "J"(TLS_SLOT_OPENGL_API*4), \ + [api] "J"(__builtin_offsetof(gl_hooks_t, gl._api)) \ + : "r0", "r1", "r2", "r3", "r12" \ + ); + + #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE \ + asm volatile( \ + "mov r0, #0 \n" \ + : \ + : \ + : "r0" \ + ); + + + #define CALL_GL_API_INTERNAL_DO_RETURN \ + asm volatile( \ + "bx lr \n" \ + : \ + : \ + : "r0" \ + ); #elif defined(__aarch64__) - #define API_ENTRY(_api) __attribute__((noinline)) _api + #define API_ENTRY(_api) __attribute__((naked,noinline)) _api - #define CALL_GL_API(_api, ...) \ + #define CALL_GL_API_INTERNAL_CALL(_api, ...) \ asm volatile( \ "mrs x16, tpidr_el0\n" \ "ldr x16, [x16, %[tls]]\n" \ @@ -133,120 +159,173 @@ GL_API void GL_APIENTRY glWeightPointerOESBounds(GLint size, GLenum type, : \ : [tls] "i" (TLS_SLOT_OPENGL_API * sizeof(void*)), \ [api] "i" (__builtin_offsetof(gl_hooks_t, gl._api)) \ - : "x16" \ + : "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x16" \ + ); + + #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE \ + asm volatile( \ + "mov w0, wzr \n" \ + : \ + : \ + : "w0" \ + ); + + #define CALL_GL_API_INTERNAL_DO_RETURN \ + asm volatile( \ + "ret \n" \ + : \ + : \ + : \ ); #elif defined(__i386__) - #define API_ENTRY(_api) __attribute__((noinline,optimize("omit-frame-pointer"))) _api + #define API_ENTRY(_api) __attribute__((naked,noinline)) _api - #define CALL_GL_API(_api, ...) \ - register void* fn; \ + #define CALL_GL_API_INTERNAL_CALL(_api, ...) \ __asm__ volatile( \ - "mov %%gs:0, %[fn]\n" \ - "mov %P[tls](%[fn]), %[fn]\n" \ - "test %[fn], %[fn]\n" \ + "mov %%gs:0, %%eax\n" \ + "mov %P[tls](%%eax), %%eax\n" \ + "test %%eax, %%eax\n" \ "je 1f\n" \ - "jmp *%P[api](%[fn])\n" \ + "jmp *%P[api](%%eax)\n" \ "1:\n" \ - : [fn] "=r" (fn) \ + : \ : [tls] "i" (TLS_SLOT_OPENGL_API*sizeof(void*)), \ [api] "i" (__builtin_offsetof(gl_hooks_t, gl._api)) \ - : "cc" \ - ); + : "cc", "%eax" \ + ); + + #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE \ + __asm__ volatile( \ + "xor %%eax, %%eax\n" \ + : \ + : \ + : "%eax" \ + ); + + #define CALL_GL_API_INTERNAL_DO_RETURN \ + __asm__ volatile( \ + "ret\n" \ + : \ + : \ + : \ + ); #elif defined(__x86_64__) - #define API_ENTRY(_api) __attribute__((noinline,optimize("omit-frame-pointer"))) _api + #define API_ENTRY(_api) __attribute__((naked,noinline)) _api - #define CALL_GL_API(_api, ...) \ - register void** fn; \ - __asm__ volatile( \ - "mov %%fs:0, %[fn]\n" \ - "mov %P[tls](%[fn]), %[fn]\n" \ - "test %[fn], %[fn]\n" \ + #define CALL_GL_API_INTERNAL_CALL(_api, ...) \ + __asm__ volatile( \ + "mov %%fs:0, %%rax\n" \ + "mov %P[tls](%%rax), %%rax\n" \ + "test %%rax, %%rax\n" \ "je 1f\n" \ - "jmp *%P[api](%[fn])\n" \ + "jmp *%P[api](%%rax)\n" \ "1:\n" \ - : [fn] "=r" (fn) \ + : \ : [tls] "i" (TLS_SLOT_OPENGL_API*sizeof(void*)), \ [api] "i" (__builtin_offsetof(gl_hooks_t, gl._api)) \ - : "cc" \ - ); + : "cc", "%rdi", "%rsi", "%rdx", "%rcx", "%r8", "%r9", \ + "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", \ + "%xmm6", "%xmm7" \ + ); + + #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE \ + __asm__ volatile( \ + "xor %%eax, %%eax\n" \ + : \ + : \ + : "%eax" \ + ); + + #define CALL_GL_API_INTERNAL_DO_RETURN \ + __asm__ volatile( \ + "retq\n" \ + : \ + : \ + : \ + ); #elif defined(__mips64) - #define API_ENTRY(_api) __attribute__((noinline)) _api - - #define CALL_GL_API(_api, ...) \ - register unsigned long _t0 asm("$12"); \ - register unsigned long _fn asm("$25"); \ - register unsigned long _tls asm("$3"); \ - register unsigned long _v0 asm("$2"); \ - asm volatile( \ - ".set push\n\t" \ - ".set noreorder\n\t" \ - "rdhwr %[tls], $29\n\t" \ - "ld %[t0], %[OPENGL_API](%[tls])\n\t" \ - "beqz %[t0], 1f\n\t" \ - " move %[fn], $ra\n\t" \ - "ld %[t0], %[API](%[t0])\n\t" \ - "beqz %[t0], 1f\n\t" \ - " nop\n\t" \ - "move %[fn], %[t0]\n\t" \ - "1:\n\t" \ - "jalr $0, %[fn]\n\t" \ - " move %[v0], $0\n\t" \ - ".set pop\n\t" \ - : [fn] "=c"(_fn), \ - [tls] "=&r"(_tls), \ - [t0] "=&r"(_t0), \ - [v0] "=&r"(_v0) \ - : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*sizeof(void*)),\ - [API] "I"(__builtin_offsetof(gl_hooks_t, gl._api)) \ - : \ + #define API_ENTRY(_api) __attribute__((naked,noinline)) _api + + // t0: $12 + // fn: $25 + // tls: $3 + // v0: $2 + #define CALL_GL_API_INTERNAL_CALL(_api, ...) \ + asm volatile( \ + ".set push\n\t" \ + ".set noreorder\n\t" \ + "rdhwr $3, $29\n\t" \ + "ld $12, %[OPENGL_API]($3)\n\t" \ + "beqz $12, 1f\n\t" \ + " move $25, $ra\n\t" \ + "ld $12, %[API]($12)\n\t" \ + "beqz $12, 1f\n\t" \ + " nop\n\t" \ + "move $25, $12\n\t" \ + "1:\n\t" \ + "jalr $0, $25\n\t" \ + " move $2, $0\n\t" \ + ".set pop\n\t" \ + : \ + : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*sizeof(void*)),\ + [API] "I"(__builtin_offsetof(gl_hooks_t, gl._api)) \ + : "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9", \ + "$10", "$11", "$12", "$25" \ ); + #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE + #define CALL_GL_API_INTERNAL_DO_RETURN + #elif defined(__mips__) - #define API_ENTRY(_api) __attribute__((noinline)) _api + #define API_ENTRY(_api) __attribute__((naked,noinline)) _api - #define CALL_GL_API(_api, ...) \ - register unsigned int _t0 asm("$8"); \ - register unsigned int _fn asm("$25"); \ - register unsigned int _tls asm("$3"); \ - register unsigned int _v0 asm("$2"); \ + // t0: $8 + // fn: $25 + // tls: $3 + // v0: $2 + #define CALL_GL_API_INTERNAL_CALL(_api, ...) \ asm volatile( \ ".set push\n\t" \ ".set noreorder\n\t" \ ".set mips32r2\n\t" \ - "rdhwr %[tls], $29\n\t" \ - "lw %[t0], %[OPENGL_API](%[tls])\n\t" \ - "beqz %[t0], 1f\n\t" \ - " move %[fn], $ra\n\t" \ - "lw %[t0], %[API](%[t0])\n\t" \ - "beqz %[t0], 1f\n\t" \ + "rdhwr $3, $29\n\t" \ + "lw $3, %[OPENGL_API]($3)\n\t" \ + "beqz $3, 1f\n\t" \ + " move $25,$ra\n\t" \ + "lw $3, %[API]($3)\n\t" \ + "beqz $3, 1f\n\t" \ " nop\n\t" \ - "move %[fn], %[t0]\n\t" \ + "move $25, $3\n\t" \ "1:\n\t" \ - "jalr $0, %[fn]\n\t" \ - " move %[v0], $0\n\t" \ + "jalr $0, $25\n\t" \ + " move $2, $0\n\t" \ ".set pop\n\t" \ - : [fn] "=c"(_fn), \ - [tls] "=&r"(_tls), \ - [t0] "=&r"(_t0), \ - [v0] "=&r"(_v0) \ + : \ : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*4), \ [API] "I"(__builtin_offsetof(gl_hooks_t, gl._api)) \ - : \ - ); + : "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$25" \ + ); + + #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE + #define CALL_GL_API_INTERNAL_DO_RETURN #endif -#define CALL_GL_API_RETURN(_api, ...) \ - CALL_GL_API(_api, __VA_ARGS__) \ - return 0; +#define CALL_GL_API(_api, ...) \ + CALL_GL_API_INTERNAL_CALL(_api, __VA_ARGS__) \ + CALL_GL_API_INTERNAL_DO_RETURN +#define CALL_GL_API_RETURN(_api, ...) \ + CALL_GL_API_INTERNAL_CALL(_api, __VA_ARGS__) \ + CALL_GL_API_INTERNAL_SET_RETURN_VALUE \ + CALL_GL_API_INTERNAL_DO_RETURN extern "C" { #pragma GCC diagnostic ignored "-Wunused-parameter" @@ -257,6 +336,9 @@ extern "C" { #undef API_ENTRY #undef CALL_GL_API +#undef CALL_GL_API_INTERNAL_CALL +#undef CALL_GL_API_INTERNAL_SET_RETURN_VALUE +#undef CALL_GL_API_INTERNAL_DO_RETURN #undef CALL_GL_API_RETURN /* |