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