Rewrite our x86 assembler macros to be portable across Mac OS and Linux.
Change-Id: Ia0fe688c4d80f95e149f179f9ed0852226d32a67
diff --git a/src/oat/runtime/x86/runtime_support_x86.S b/src/oat/runtime/x86/runtime_support_x86.S
index 443ed90..8f7177c 100644
--- a/src/oat/runtime/x86/runtime_support_x86.S
+++ b/src/oat/runtime/x86/runtime_support_x86.S
@@ -1,40 +1,61 @@
#include "asm_support.h"
#if defined(__APPLE__)
- // Mac OS X mangles the functions with an underscore prefix
- #define art_deliver_exception_from_code _art_deliver_exception_from_code
- #define art_proxy_invoke_handler _art_proxy_invoke_handler
- #define artDeliverExceptionFromCode _artDeliverExceptionFromCode
+ // Mac OS' as(1) doesn't let you name macro parameters.
+ #define MACRO0(macro_name) .macro macro_name
+ #define MACRO1(macro_name, macro_arg1) .macro macro_name
+ #define MACRO2(macro_name, macro_arg1, macro_args2) .macro macro_name
+ #define END_MACRO .endmacro
+
+ // Mac OS' as(1) uses $0, $1, and so on for macro arguments, and function names
+ // are mangled with an extra underscore prefix. The use of $x for arguments
+ // mean that literals need to be represented with $$x in macros.
+ #define VAR(name,index) _$index
+ #define LITERAL(value) $$value
+#else
+ // Regular gas(1) lets you name macro parameters.
+ #define MACRO0(macro_name) .macro macro_name
+ #define MACRO1(macro_name, macro_arg1) .macro macro_name macro_arg1
+ #define MACRO2(macro_name, macro_arg1, macro_arg2) .macro macro_name macro_arg1, macro_arg2
+ #define END_MACRO .endm
+
+ // Regular gas(1) uses \argument_name for macro arguments.
+ // We need to turn on alternate macro syntax so we can use & instead or the preprocessor
+ // will screw us by inserting a space between the \ and the name. Even in this mode there's
+ // no special meaning to $, so literals are still just $x.
+ .altmacro
+ #define VAR(name,index) name&
+ #define LITERAL(value) $value
#endif
/* Cache alignment for function entry */
-.macro ALIGN_FUNCTION_ENTRY
+MACRO0(ALIGN_FUNCTION_ENTRY)
.balign 16
-.endm
+END_MACRO
/*
* Macro that sets up the callee save frame to conform with
* Runtime::CreateCalleeSaveMethod(...)
*/
-.macro SETUP_SAVE_ALL_CALLEE_SAVE_FRAME
+MACRO0(SETUP_SAVE_ALL_CALLEE_SAVE_FRAME)
pushl %edi // Save callee saves (ebx is saved/restored by the upcall)
pushl %esi
pushl %ebp
- subl $16, %esp // Grow stack by 4 words, bottom word will hold Method*
-.endm
+ subl LITERAL(16), %esp // Grow stack by 4 words, bottom word will hold Method*
+END_MACRO
-.macro RESTORE_CALLEE_SAVE_FRAME
- addl $16, %esp // Remove padding
+MACRO0(RESTORE_CALLEE_SAVE_FRAME)
+ addl LITERAL(16), %esp // Remove padding
popl %ebp // Restore callee saves
popl %esi
popl %edi
-.endm
+END_MACRO
/*
* Macro that sets up the callee save frame to conform with
* Runtime::CreateCalleeSaveMethod(...)
*/
-.macro SETUP_REF_AND_ARG_CALLEE_SAVE_FRAME
+MACRO0(SETUP_REF_AND_ARG_CALLEE_SAVE_FRAME)
pushl %edi // Save callee saves
pushl %esi
pushl %ebp
@@ -42,63 +63,63 @@
pushl %edx
pushl %ecx
pushl %eax // Align stack, eax will be clobbered by Method*
-.endm
+END_MACRO
-.macro RESTORE_REF_AND_ARG_CALLEE_SAVE_FRAME
- addl $16, %esp // Remove padding
+MACRO0(RESTORE_REF_AND_ARG_CALLEE_SAVE_FRAME)
+ addl LITERAL(16), %esp // Remove padding
popl %ebp // Restore callee saves
popl %esi
popl %edi
-.endm
+END_MACRO
/*
* Macro that set calls through to artDeliverPendingExceptionFromCode, where the pending
* exception is Thread::Current()->exception_.
*/
-.macro DELIVER_PENDING_EXCEPTION
+MACRO0(DELIVER_PENDING_EXCEPTION)
SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save callee saves for throw
mov %esp, %ecx
// Outgoing argument set up
- subl $8, %esp // Alignment padding
+ subl LITERAL(8), %esp // Alignment padding
pushl %ecx // pass SP
pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
call artDeliverPendingExceptionFromCode // artDeliverExceptionFromCode(Thread*, SP)
int3
-.endm
+END_MACRO
-.macro NO_ARG_RUNTIME_EXCEPTION c_name, cxx_name
- .globl \c_name
+MACRO2(NO_ARG_RUNTIME_EXCEPTION, c_name, cxx_name)
+ .globl VAR(c_name, 0)
ALIGN_FUNCTION_ENTRY
-\c_name:
+VAR(c_name, 0):
SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
mov %esp, %ecx
// Outgoing argument set up
- subl $8, %esp // alignment padding
+ subl LITERAL(8), %esp // alignment padding
pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
pushl %ecx // pass SP
- call \cxx_name // \cxx_name(Thread*, SP)
+ call VAR(cxx_name, 1) // cxx_name(Thread*, SP)
int3 // unreached
-.endm
+END_MACRO
-.macro ONE_ARG_RUNTIME_EXCEPTION c_name, cxx_name
- .globl \c_name
+MACRO2(ONE_ARG_RUNTIME_EXCEPTION, c_name, cxx_name)
+ .globl VAR(c_name, 0)
ALIGN_FUNCTION_ENTRY
-\c_name:
+VAR(c_name, 0):
SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
mov %esp, %ecx
// Outgoing argument set up
- pushl $0 // alignment padding
+ pushl LITERAL(0) // alignment padding
pushl %ecx // pass SP
pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
pushl %eax // pass arg1
- call \cxx_name // \cxx_name(arg1, Thread*, SP)
+ call VAR(cxx_name, 1) // cxx_name(arg1, Thread*, SP)
int3 // unreached
-.endm
+END_MACRO
-.macro TWO_ARG_RUNTIME_EXCEPTION c_name, cxx_name
- .globl \c_name
+MACRO2(TWO_ARG_RUNTIME_EXCEPTION, c_name, cxx_name)
+ .globl VAR(c_name, 0)
ALIGN_FUNCTION_ENTRY
-\c_name:
+VAR(c_name, 0):
SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context
mov %esp, %edx
// Outgoing argument set up
@@ -106,15 +127,9 @@
pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
pushl %eax // pass arg1
pushl %ecx // pass arg2
- call \cxx_name // \cxx_name(arg1, Thread*, SP)
+ call VAR(cxx_name, 1) // cxx_name(arg2, arg1, Thread*, SP)
int3 // unreached
-.endm
-
- /*
- * Called by managed code, saves callee saves and then calls artThrowException
- * that will place a mock Method* at the bottom of the stack. Arg1 holds the exception.
- */
-ONE_ARG_RUNTIME_EXCEPTION art_deliver_exception_from_code, artDeliverExceptionFromCode
+END_MACRO
/*
* Called by managed code to create and deliver a NullPointerException.
@@ -127,22 +142,28 @@
NO_ARG_RUNTIME_EXCEPTION art_throw_div_zero_from_code, artThrowDivZeroFromCode
/*
- * Called by managed code to create and deliver an ArrayIndexOutOfBoundsException. Arg1 holds
- * index, arg2 holds limit.
- */
-TWO_ARG_RUNTIME_EXCEPTION art_throw_array_bounds_from_code, artThrowArrayBoundsFromCode
-
- /*
* Called by managed code to create and deliver a StackOverflowError.
*/
NO_ARG_RUNTIME_EXCEPTION art_throw_stack_overflow_from_code, artThrowStackOverflowFromCode
/*
+ * Called by managed code, saves callee saves and then calls artThrowException
+ * that will place a mock Method* at the bottom of the stack. Arg1 holds the exception.
+ */
+ONE_ARG_RUNTIME_EXCEPTION art_deliver_exception_from_code, artDeliverExceptionFromCode
+
+ /*
* Called by managed code to create and deliver a NoSuchMethodError.
*/
ONE_ARG_RUNTIME_EXCEPTION art_throw_no_such_method_from_code, artThrowNoSuchMethodFromCode
/*
+ * Called by managed code to create and deliver an ArrayIndexOutOfBoundsException. Arg1 holds
+ * index, arg2 holds limit.
+ */
+TWO_ARG_RUNTIME_EXCEPTION art_throw_array_bounds_from_code, artThrowArrayBoundsFromCode
+
+ /*
* Called by managed code to create and deliver verification errors. Arg1 is kind, arg2 is ref.
*/
TWO_ARG_RUNTIME_EXCEPTION art_throw_verification_error_from_code, artThrowVerificationErrorFromCode
@@ -163,12 +184,12 @@
* On success this wrapper will restore arguments and *jump* to the target, leaving the lr
* pointing back to the original caller.
*/
-.macro INVOKE_TRAMPOLINE c_name, cxx_name
- .globl \c_name
+MACRO2(INVOKE_TRAMPOLINE, c_name, cxx_name)
+ .globl VAR(c_name, 0)
ALIGN_FUNCTION_ENTRY
-\c_name:
+VAR(c_name, 0):
int3
-.endm
+END_MACRO
INVOKE_TRAMPOLINE art_invoke_interface_trampoline, artInvokeInterfaceTrampoline
INVOKE_TRAMPOLINE art_invoke_interface_trampoline_with_access_check, artInvokeInterfaceTrampolineWithAccessCheck
@@ -178,135 +199,44 @@
INVOKE_TRAMPOLINE art_invoke_super_trampoline_with_access_check, artInvokeSuperTrampolineWithAccessCheck
INVOKE_TRAMPOLINE art_invoke_virtual_trampoline_with_access_check, artInvokeVirtualTrampolineWithAccessCheck
- // TODO
- .globl art_proxy_invoke_handler
-art_proxy_invoke_handler:
+MACRO1(UNIMPLEMENTED,name)
+ .globl VAR(name, 0)
+ ALIGN_FUNCTION_ENTRY
+VAR(name, 0):
int3
+END_MACRO
- .globl art_update_debugger
-art_update_debugger:
- int3
-
- .globl art_test_suspend
-art_test_suspend:
- int3
-
- .globl art_alloc_object_from_code
-art_alloc_object_from_code:
- int3
-
- .globl art_alloc_object_from_code_with_access_check
-art_alloc_object_from_code_with_access_check:
- int3
-
- .globl art_alloc_array_from_code
-art_alloc_array_from_code:
- int3
-
- .globl art_alloc_array_from_code_with_access_check
-art_alloc_array_from_code_with_access_check:
- int3
-
- .globl art_check_and_alloc_array_from_code
-art_check_and_alloc_array_from_code:
- int3
-
- .globl art_check_and_alloc_array_from_code_with_access_check
-art_check_and_alloc_array_from_code_with_access_check:
- int3
-
- .globl art_can_put_array_element_from_code
-art_can_put_array_element_from_code:
- int3
-
- .globl art_check_cast_from_code
-art_check_cast_from_code:
- int3
-
- .globl art_initialize_static_storage_from_code
-art_initialize_static_storage_from_code:
- int3
-
- .globl art_initialize_type_and_verify_access_from_code
-art_initialize_type_and_verify_access_from_code:
- int3
-
- .globl art_initialize_type_from_code
-art_initialize_type_from_code:
- int3
-
- .globl art_resolve_string_from_code
-art_resolve_string_from_code:
- int3
-
- .globl art_set32_instance_from_code
-art_set32_instance_from_code:
- int3
-
- .globl art_set64_instance_from_code
-art_set64_instance_from_code:
- int3
-
- .globl art_set_obj_instance_from_code
-art_set_obj_instance_from_code:
- int3
-
- .globl art_get32_instance_from_code
-art_get32_instance_from_code:
- int3
-
- .globl art_get64_instance_from_code
-art_get64_instance_from_code:
- int3
-
- .globl art_get_obj_instance_from_code
-art_get_obj_instance_from_code:
- int3
-
- .globl art_set32_static_from_code
-art_set32_static_from_code:
- int3
-
- .globl art_set64_static_from_code
-art_set64_static_from_code:
- int3
-
- .globl art_set_obj_static_from_code
-art_set_obj_static_from_code:
- int3
-
- .globl art_get32_static_from_code
-art_get32_static_from_code:
- int3
-
- .globl art_get64_static_from_code
-art_get64_static_from_code:
- int3
-
- .globl art_get_obj_static_from_code
-art_get_obj_static_from_code:
- int3
-
- .globl art_handle_fill_data_from_code
-art_handle_fill_data_from_code:
- int3
-
- .globl art_lock_object_from_code
-art_lock_object_from_code:
- int3
-
- .globl art_unlock_object_from_code
-art_unlock_object_from_code:
- int3
-
- .globl art_indexof
-art_indexof:
- int3
-
- .globl __memcmp16
-__memcmp16:
- int3
-
- .globl art_string_compareto
-art_string_compareto:
- int3
+ // TODO: implement these!
+UNIMPLEMENTED art_proxy_invoke_handler
+UNIMPLEMENTED art_update_debugger
+UNIMPLEMENTED art_test_suspend
+UNIMPLEMENTED art_alloc_object_from_code
+UNIMPLEMENTED art_alloc_object_from_code_with_access_check
+UNIMPLEMENTED art_alloc_array_from_code
+UNIMPLEMENTED art_alloc_array_from_code_with_access_check
+UNIMPLEMENTED art_check_and_alloc_array_from_code
+UNIMPLEMENTED art_check_and_alloc_array_from_code_with_access_check
+UNIMPLEMENTED art_can_put_array_element_from_code
+UNIMPLEMENTED art_check_cast_from_code
+UNIMPLEMENTED art_initialize_static_storage_from_code
+UNIMPLEMENTED art_initialize_type_and_verify_access_from_code
+UNIMPLEMENTED art_initialize_type_from_code
+UNIMPLEMENTED art_resolve_string_from_code
+UNIMPLEMENTED art_set32_instance_from_code
+UNIMPLEMENTED art_set64_instance_from_code
+UNIMPLEMENTED art_set_obj_instance_from_code
+UNIMPLEMENTED art_get32_instance_from_code
+UNIMPLEMENTED art_get64_instance_from_code
+UNIMPLEMENTED art_get_obj_instance_from_code
+UNIMPLEMENTED art_set32_static_from_code
+UNIMPLEMENTED art_set64_static_from_code
+UNIMPLEMENTED art_set_obj_static_from_code
+UNIMPLEMENTED art_get32_static_from_code
+UNIMPLEMENTED art_get64_static_from_code
+UNIMPLEMENTED art_get_obj_static_from_code
+UNIMPLEMENTED art_handle_fill_data_from_code
+UNIMPLEMENTED art_lock_object_from_code
+UNIMPLEMENTED art_unlock_object_from_code
+UNIMPLEMENTED art_indexof
+UNIMPLEMENTED __memcmp16
+UNIMPLEMENTED art_string_compareto