Implement various missing parts of the X86 compiler
Change-Id: I76f08580600befe268328f8cf7102c6146460c5e
diff --git a/src/oat/runtime/x86/runtime_support_x86.S b/src/oat/runtime/x86/runtime_support_x86.S
index 3333469..943b55c 100644
--- a/src/oat/runtime/x86/runtime_support_x86.S
+++ b/src/oat/runtime/x86/runtime_support_x86.S
@@ -51,7 +51,7 @@
/*
* Macro that sets up the callee save frame to conform with
- * Runtime::CreateCalleeSaveMethod(...)
+ * Runtime::CreateCalleeSaveMethod(kSaveAll)
*/
MACRO0(SETUP_SAVE_ALL_CALLEE_SAVE_FRAME)
pushl %edi // Save callee saves (ebx is saved/restored by the upcall)
@@ -60,16 +60,24 @@
subl LITERAL(16), %esp // Grow stack by 4 words, bottom word will hold Method*
END_MACRO
-MACRO0(RESTORE_CALLEE_SAVE_FRAME)
- addl LITERAL(16), %esp // Remove padding
- popl %ebp // Restore callee saves
- popl %esi
- popl %edi
+ /*
+ * Macro that sets up the callee save frame to conform with
+ * Runtime::CreateCalleeSaveMethod(kRefsOnly)
+ */
+MACRO0(SETUP_REF_ONLY_CALLEE_SAVE_FRAME)
+ pushl %edi // Save callee saves (ebx is saved/restored by the upcall)
+ pushl %esi
+ pushl %ebp
+ subl LITERAL(16), %esp // Grow stack by 4 words, bottom word will hold Method*
+END_MACRO
+
+MACRO0(RESTORE_REF_ONLY_CALLEE_SAVE_FRAME)
+ addl LITERAL(28), %esp // Unwind stack up to return address
END_MACRO
/*
* Macro that sets up the callee save frame to conform with
- * Runtime::CreateCalleeSaveMethod(...)
+ * Runtime::CreateCalleeSaveMethod(kRefsAndArgs)
*/
MACRO0(SETUP_REF_AND_ARG_CALLEE_SAVE_FRAME)
pushl %edi // Save callee saves
@@ -82,7 +90,10 @@
END_MACRO
MACRO0(RESTORE_REF_AND_ARG_CALLEE_SAVE_FRAME)
- addl LITERAL(16), %esp // Remove padding
+ addl LITERAL(4), %esp // Remove padding
+ popl %ecx // Restore args except eax
+ popl %edx
+ popl %ebx
popl %ebp // Restore callee saves
popl %esi
popl %edi
@@ -141,9 +152,9 @@
// Outgoing argument set up
pushl %edx // pass SP
pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
- pushl %eax // pass arg1
pushl %ecx // pass arg2
- call VAR(cxx_name, 1) // cxx_name(arg2, arg1, Thread*, SP)
+ pushl %eax // pass arg1
+ call VAR(cxx_name, 1) // cxx_name(arg1, arg2, Thread*, SP)
int3 // unreached
END_MACRO
@@ -204,7 +215,39 @@
.globl VAR(c_name, 0)
ALIGN_FUNCTION_ENTRY
VAR(c_name, 0):
- int3
+ // Set up the callee save frame to conform with Runtime::CreateCalleeSaveMethod(kRefsAndArgs)
+ // return address
+ pushl %edi
+ pushl %esi
+ pushl %ebp
+ pushl %ebx
+ pushl %edx
+ pushl %ecx
+ pushl %eax // <-- callee save Method* to go here
+ movl %esp, %edx // remember SP
+ // Outgoing argument set up
+ subl LITERAL(12), %esp // alignment padding
+ pushl %edx // pass SP
+ pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
+ pushl 32(%edx) // pass caller Method*
+ pushl %ecx // pass arg2
+ pushl %eax // pass arg1
+ call VAR(cxx_name, 1) // cxx_name(arg1, arg2, arg3, Thread*, SP)
+ movl %edx, %edi // save code pointer in EDI
+ addl LITERAL(36), %esp // Pop arguments skip eax
+ popl %ecx // Restore args
+ popl %edx
+ popl %ebx
+ popl %ebp // Restore callee saves.
+ popl %esi
+ // Swap EDI callee save with code pointer.
+ xchgl %edi, (%esp)
+ testl %eax, %eax // Branch forward if exception pending.
+ jz 1f
+ // Tail call to intended method.
+ ret
+1:
+ DELIVER_PENDING_EXCEPTION
END_MACRO
INVOKE_TRAMPOLINE art_invoke_interface_trampoline, artInvokeInterfaceTrampoline
@@ -215,6 +258,189 @@
INVOKE_TRAMPOLINE art_invoke_super_trampoline_with_access_check, artInvokeSuperTrampolineWithAccessCheck
INVOKE_TRAMPOLINE art_invoke_virtual_trampoline_with_access_check, artInvokeVirtualTrampolineWithAccessCheck
+MACRO2(TWO_ARG_ALLOC, c_name, cxx_name)
+ .globl VAR(c_name, 0)
+ ALIGN_FUNCTION_ENTRY
+VAR(c_name, 0):
+ SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
+ mov %esp, %edx // remember SP
+ // Outgoing argument set up
+ pushl %edx // pass SP
+ pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
+ pushl %ecx // pass arg2
+ pushl %eax // pass arg1
+ call VAR(cxx_name, 1) // cxx_name(arg1, arg2, arg3, Thread*, SP)
+ addl LITERAL(16), %esp // pop arguments
+ RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
+ testl %eax, %eax // eax == 0 ?
+ jz 1f
+ ret
+1:
+ DELIVER_PENDING_EXCEPTION
+END_MACRO
+
+MACRO2(THREE_ARG_ALLOC, c_name, cxx_name)
+ .globl VAR(c_name, 0)
+ ALIGN_FUNCTION_ENTRY
+VAR(c_name, 0):
+ SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
+ mov %esp, %ebx // remember SP
+ // Outgoing argument set up
+ subl LITERAL(12), %esp // alignment padding
+ pushl %ebx // pass SP
+ pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
+ pushl %edx // pass arg3
+ pushl %ecx // pass arg2
+ pushl %eax // pass arg1
+ call VAR(cxx_name, 1) // cxx_name(arg1, arg2, Thread*, SP)
+ addl LITERAL(32), %esp // pop arguments
+ RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
+ testl %eax, %eax // eax == 0 ?
+ jz 1f
+ ret
+1:
+ DELIVER_PENDING_EXCEPTION
+END_MACRO
+
+TWO_ARG_ALLOC art_alloc_object_from_code, artAllocObjectFromCode
+TWO_ARG_ALLOC art_alloc_object_from_code_with_access_check, artAllocObjectFromCodeWithAccessCheck
+THREE_ARG_ALLOC art_alloc_array_from_code, artAllocArrayFromCode
+THREE_ARG_ALLOC art_alloc_array_from_code_with_access_check, artAllocArrayFromCodeWithAccessCheck
+THREE_ARG_ALLOC art_check_and_alloc_array_from_code, artCheckAndAllocArrayFromCode
+THREE_ARG_ALLOC art_check_and_alloc_array_from_code_with_access_check, artCheckAndAllocArrayFromCodeWithAccessCheck
+
+TWO_ARG_ALLOC art_resolve_string_from_code, artResolveStringFromCode
+TWO_ARG_ALLOC art_initialize_static_storage_from_code, artInitializeStaticStorageFromCode
+
+ .globl art_lock_object_from_code
+ ALIGN_FUNCTION_ENTRY
+art_lock_object_from_code:
+ SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
+ mov %esp, %edx // remember SP
+ // Outgoing argument set up
+ pushl %eax // alignment padding
+ pushl %edx // pass SP
+ pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
+ pushl %eax // pass arg1
+ call artLockObjectFromCode // (Object*, Thread*, SP)
+ addl LITERAL(16), %esp // pop arguments
+ RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
+ ret
+
+ .globl art_unlock_object_from_code
+ ALIGN_FUNCTION_ENTRY
+art_unlock_object_from_code:
+ SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
+ mov %esp, %edx // remember SP
+ // Outgoing argument set up
+ pushl %eax // alignment padding
+ pushl %edx // pass SP
+ pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
+ pushl %eax // pass arg1
+ call artUnlockObjectFromCode // (Object*, Thread*, SP)
+ addl LITERAL(16), %esp // pop arguments
+ RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
+ testl %eax, %eax // eax == 0 ?
+ jnz 1f
+ ret
+1:
+ DELIVER_PENDING_EXCEPTION
+
+ .globl art_handle_fill_data_from_code
+ ALIGN_FUNCTION_ENTRY
+art_handle_fill_data_from_code:
+ SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
+ mov %esp, %edx // remember SP
+ // Outgoing argument set up
+ pushl %edx // pass SP
+ pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
+ pushl %ecx // pass arg2
+ pushl %eax // pass arg1
+ call artHandleFillArrayDataFromCode // (Array* array, const uint16_t* table, Thread*, SP)
+ addl LITERAL(16), %esp // pop arguments
+ RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
+ testl %eax, %eax // eax == 0 ?
+ jnz 1f
+ ret
+1:
+ DELIVER_PENDING_EXCEPTION
+
+ .globl art_is_assignable_from_code
+ ALIGN_FUNCTION_ENTRY
+art_is_assignable_from_code:
+ pushl %eax // alignment padding
+ pushl %ecx // pass arg2
+ pushl %eax // pass arg1
+ call artIsAssignableFromCode // (Class* a, Class* b, Thread*, SP)
+ addl LITERAL(12), %esp // pop arguments
+ ret
+
+ .globl art_memcpy
+ ALIGN_FUNCTION_ENTRY
+art_memcpy:
+ pushl %edx // pass arg3
+ pushl %ecx // pass arg2
+ pushl %eax // pass arg1
+ call memcpy // (void*, const void*, size_t)
+ addl LITERAL(12), %esp // pop arguments
+ ret
+
+ .globl art_check_cast_from_code
+ ALIGN_FUNCTION_ENTRY
+art_check_cast_from_code:
+ SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
+ mov %esp, %edx // remember SP
+ // Outgoing argument set up
+ pushl %edx // pass SP
+ pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
+ pushl %ecx // pass arg2
+ pushl %eax // pass arg1
+ call artCheckCastFromCode // (Class* a, Class* b, Thread*, SP)
+ addl LITERAL(16), %esp // pop arguments
+ RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
+ testl %eax, %eax // eax == 0 ?
+ jnz 1f
+ ret
+1:
+ DELIVER_PENDING_EXCEPTION
+
+ .globl art_idiv_from_code
+ ALIGN_FUNCTION_ENTRY
+art_idiv_from_code:
+ cdq // edx:eax = sign extend eax
+ idiv %ecx // (edx,eax) = (edx:eax % ecx, edx:eax / ecx)
+ ret
+
+ .globl art_idivmod_from_code
+ ALIGN_FUNCTION_ENTRY
+art_idivmod_from_code:
+ cdq // edx:eax = sign extend eax
+ idiv %ecx // (edx,eax) = (edx:eax % ecx, edx:eax / ecx)
+ movl %eax, %edx
+ ret
+
+ .globl art_can_put_array_element_from_code
+ ALIGN_FUNCTION_ENTRY
+art_can_put_array_element_from_code:
+ test %eax, %eax // Null is trivially storable
+ jz 1f
+ SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
+ mov %esp, %edx // remember SP
+ // Outgoing argument set up
+ pushl %edx // pass SP
+ pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
+ pushl %ecx // pass arg2
+ pushl %eax // pass arg1
+ call artCanPutArrayElementFromCode // (Object* element, Class* array_class, Thread*, SP)
+ addl LITERAL(16), %esp // pop arguments
+ RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
+ testl %eax, %eax // eax == 0 ?
+ jnz 2f
+1:
+ ret
+2:
+ DELIVER_PENDING_EXCEPTION
+
MACRO1(UNIMPLEMENTED,name)
.globl VAR(name, 0)
ALIGN_FUNCTION_ENTRY
@@ -226,18 +452,8 @@
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
@@ -250,9 +466,6 @@
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_memcmp16
UNIMPLEMENTED art_string_compareto