10f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes/* 20f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * Copyright (C) 2012 The Android Open Source Project 30f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * 40f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 50f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * you may not use this file except in compliance with the License. 60f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * You may obtain a copy of the License at 70f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * 80f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 90f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * 100f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * Unless required by applicable law or agreed to in writing, software 110f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 120f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * See the License for the specific language governing permissions and 140f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes * limitations under the License. 150f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes */ 160f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes 177655f29fabc0a12765de828914a18314382e5a35Ian Rogers#include "asm_support_x86.S" 185e284224e5525ee0a8494a73d84c8ef86e022a0aElliott Hughes 194adeab196d160f70b4865fb8be048ddd2ac7ab82Hiroshi Yamauchi#include "arch/quick_alloc_entrypoints.S" 204adeab196d160f70b4865fb8be048ddd2ac7ab82Hiroshi Yamauchi 21bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison// For x86, the CFA is esp+4, the address above the pushed return address on the stack. 22bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison 2357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers /* 2457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers * Macro that sets up the callee save frame to conform with 257caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers * Runtime::CreateCalleeSaveMethod(kSaveAll) 2657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers */ 271d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersMACRO2(SETUP_SAVE_ALL_CALLEE_SAVE_FRAME, got_reg, temp_reg) 28aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers PUSH edi // Save callee saves (ebx is saved/restored by the upcall) 29aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers PUSH esi 30aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers PUSH ebp 314360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe subl MACRO_LITERAL(12), %esp // Grow stack by 3 words. 321d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers CFI_ADJUST_CFA_OFFSET(12) 334360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe SETUP_GOT_NOSAVE RAW_VAR(got_reg) 341d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers // Load Runtime::instance_ from GOT. 354360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe movl SYMBOL(_ZN3art7Runtime9instance_E)@GOT(REG_VAR(got_reg)), REG_VAR(temp_reg) 364360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe movl (REG_VAR(temp_reg)), REG_VAR(temp_reg) 371d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers // Push save all callee-save method. 384360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe pushl RUNTIME_SAVE_ALL_CALLEE_SAVE_FRAME_OFFSET(REG_VAR(temp_reg)) 391d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers CFI_ADJUST_CFA_OFFSET(4) 401d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers // Store esp as the top quick frame. 411d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers movl %esp, %fs:THREAD_TOP_QUICK_FRAME_OFFSET 425c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe // Ugly compile-time check, but we only have the preprocessor. 435c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe // Last +4: implicit return address pushed on stack when caller made call. 445c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe#if (FRAME_SIZE_SAVE_ALL_CALLEE_SAVE != 3*4 + 16 + 4) 455c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe#error "SAVE_ALL_CALLEE_SAVE_FRAME(X86) size not as expected." 465c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe#endif 47787ec205ee545b9c08f4fc6d3823cb43d10083afElliott HughesEND_MACRO 4857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers 497caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers /* 507caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers * Macro that sets up the callee save frame to conform with 517caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers * Runtime::CreateCalleeSaveMethod(kRefsOnly) 527caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers */ 531d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersMACRO2(SETUP_REFS_ONLY_CALLEE_SAVE_FRAME, got_reg, temp_reg) 54aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers PUSH edi // Save callee saves (ebx is saved/restored by the upcall) 55aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers PUSH esi 56aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers PUSH ebp 574360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe subl MACRO_LITERAL(12), %esp // Grow stack by 3 words. 581d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers CFI_ADJUST_CFA_OFFSET(12) 594360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe SETUP_GOT_NOSAVE RAW_VAR(got_reg) 601d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers // Load Runtime::instance_ from GOT. 614360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe movl SYMBOL(_ZN3art7Runtime9instance_E)@GOT(REG_VAR(got_reg)), REG_VAR(temp_reg) 624360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe movl (REG_VAR(temp_reg)), REG_VAR(temp_reg) 631d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers // Push save all callee-save method. 644360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe pushl RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET(REG_VAR(temp_reg)) 651d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers CFI_ADJUST_CFA_OFFSET(4) 661d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers // Store esp as the top quick frame. 671d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers movl %esp, %fs:THREAD_TOP_QUICK_FRAME_OFFSET 685c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe 695c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe // Ugly compile-time check, but we only have the preprocessor. 705c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe // Last +4: implicit return address pushed on stack when caller made call. 715c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe#if (FRAME_SIZE_REFS_ONLY_CALLEE_SAVE != 3*4 + 16 + 4) 725c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe#error "REFS_ONLY_CALLEE_SAVE_FRAME(X86) size not as expected." 735c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe#endif 747caad77632ae121c9f64c488e3f8f710e2c4813dIan RogersEND_MACRO 757caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers 76a048ca8e0ff6d0e79d070decf9fa2331e2d13824Nicolas Geoffray /* 77a048ca8e0ff6d0e79d070decf9fa2331e2d13824Nicolas Geoffray * Macro that sets up the callee save frame to conform with 78a048ca8e0ff6d0e79d070decf9fa2331e2d13824Nicolas Geoffray * Runtime::CreateCalleeSaveMethod(kRefsOnly) 79a048ca8e0ff6d0e79d070decf9fa2331e2d13824Nicolas Geoffray * and preserves the value of got_reg at entry. 80a048ca8e0ff6d0e79d070decf9fa2331e2d13824Nicolas Geoffray */ 81a048ca8e0ff6d0e79d070decf9fa2331e2d13824Nicolas GeoffrayMACRO2(SETUP_REFS_ONLY_CALLEE_SAVE_FRAME_PRESERVE_GOT_REG, got_reg, temp_reg) 82a048ca8e0ff6d0e79d070decf9fa2331e2d13824Nicolas Geoffray PUSH edi // Save callee saves (ebx is saved/restored by the upcall) 83a048ca8e0ff6d0e79d070decf9fa2331e2d13824Nicolas Geoffray PUSH esi 84a048ca8e0ff6d0e79d070decf9fa2331e2d13824Nicolas Geoffray PUSH ebp 85a048ca8e0ff6d0e79d070decf9fa2331e2d13824Nicolas Geoffray pushl REG_VAR(got_reg) // Save got_reg 86a048ca8e0ff6d0e79d070decf9fa2331e2d13824Nicolas Geoffray subl MACRO_LITERAL(8), %esp // Grow stack by 2 words. 87a048ca8e0ff6d0e79d070decf9fa2331e2d13824Nicolas Geoffray CFI_ADJUST_CFA_OFFSET(8) 88a048ca8e0ff6d0e79d070decf9fa2331e2d13824Nicolas Geoffray 89a048ca8e0ff6d0e79d070decf9fa2331e2d13824Nicolas Geoffray SETUP_GOT_NOSAVE RAW_VAR(got_reg) 90a048ca8e0ff6d0e79d070decf9fa2331e2d13824Nicolas Geoffray // Load Runtime::instance_ from GOT. 91a048ca8e0ff6d0e79d070decf9fa2331e2d13824Nicolas Geoffray movl SYMBOL(_ZN3art7Runtime9instance_E)@GOT(REG_VAR(got_reg)), REG_VAR(temp_reg) 92a048ca8e0ff6d0e79d070decf9fa2331e2d13824Nicolas Geoffray movl (REG_VAR(temp_reg)), REG_VAR(temp_reg) 93a048ca8e0ff6d0e79d070decf9fa2331e2d13824Nicolas Geoffray // Push save all callee-save method. 94a048ca8e0ff6d0e79d070decf9fa2331e2d13824Nicolas Geoffray pushl RUNTIME_REFS_ONLY_CALLEE_SAVE_FRAME_OFFSET(REG_VAR(temp_reg)) 95a048ca8e0ff6d0e79d070decf9fa2331e2d13824Nicolas Geoffray CFI_ADJUST_CFA_OFFSET(4) 96a048ca8e0ff6d0e79d070decf9fa2331e2d13824Nicolas Geoffray // Store esp as the top quick frame. 97a048ca8e0ff6d0e79d070decf9fa2331e2d13824Nicolas Geoffray movl %esp, %fs:THREAD_TOP_QUICK_FRAME_OFFSET 98a048ca8e0ff6d0e79d070decf9fa2331e2d13824Nicolas Geoffray // Restore got_reg. 99a048ca8e0ff6d0e79d070decf9fa2331e2d13824Nicolas Geoffray movl 12(%esp), REG_VAR(got_reg) 100a048ca8e0ff6d0e79d070decf9fa2331e2d13824Nicolas Geoffray 101a048ca8e0ff6d0e79d070decf9fa2331e2d13824Nicolas Geoffray // Ugly compile-time check, but we only have the preprocessor. 102a048ca8e0ff6d0e79d070decf9fa2331e2d13824Nicolas Geoffray // Last +4: implicit return address pushed on stack when caller made call. 103a048ca8e0ff6d0e79d070decf9fa2331e2d13824Nicolas Geoffray#if (FRAME_SIZE_REFS_ONLY_CALLEE_SAVE != 3*4 + 16 + 4) 104a048ca8e0ff6d0e79d070decf9fa2331e2d13824Nicolas Geoffray#error "REFS_ONLY_CALLEE_SAVE_FRAME(X86) size not as expected." 105a048ca8e0ff6d0e79d070decf9fa2331e2d13824Nicolas Geoffray#endif 106a048ca8e0ff6d0e79d070decf9fa2331e2d13824Nicolas GeoffrayEND_MACRO 107a048ca8e0ff6d0e79d070decf9fa2331e2d13824Nicolas Geoffray 1081d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersMACRO0(RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME) 10947d00c0a893b13b69e4bac1836e10cc3e1812d41Ian Rogers addl MACRO_LITERAL(16), %esp // Unwind stack up to saved values 110bf6b92a158053c98b15f4393abb3b86344ec9a20Andreas Gampe CFI_ADJUST_CFA_OFFSET(-16) 1112a6c7b7c21adcd4493542604305585b852ccf554Mathieu Chartier POP ebp // Restore callee saves (ebx is saved/restored by the upcall) 1122a6c7b7c21adcd4493542604305585b852ccf554Mathieu Chartier POP esi 1132a6c7b7c21adcd4493542604305585b852ccf554Mathieu Chartier POP edi 114787ec205ee545b9c08f4fc6d3823cb43d10083afElliott HughesEND_MACRO 11557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers 11657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers /* 11757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers * Macro that sets up the callee save frame to conform with 1187caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers * Runtime::CreateCalleeSaveMethod(kRefsAndArgs) 11957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers */ 1201d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersMACRO2(SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME, got_reg, temp_reg) 121aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers PUSH edi // Save callee saves 122aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers PUSH esi 123aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers PUSH ebp 124aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers PUSH ebx // Save args 125aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers PUSH edx 126aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers PUSH ecx 127966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Create space for FPR args. 128966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell subl MACRO_LITERAL(4 * 8), %esp 129966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell CFI_ADJUST_CFA_OFFSET(4 * 8) 130966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Save FPRs. 131966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movsd %xmm0, 0(%esp) 132966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movsd %xmm1, 8(%esp) 133966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movsd %xmm2, 16(%esp) 134966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movsd %xmm3, 24(%esp) 135966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 1364360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe SETUP_GOT_NOSAVE RAW_VAR(got_reg) 1371d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers // Load Runtime::instance_ from GOT. 1384360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe movl SYMBOL(_ZN3art7Runtime9instance_E)@GOT(REG_VAR(got_reg)), REG_VAR(temp_reg) 1394360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe movl (REG_VAR(temp_reg)), REG_VAR(temp_reg) 1401d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers // Push save all callee-save method. 1414360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe pushl RUNTIME_REFS_AND_ARGS_CALLEE_SAVE_FRAME_OFFSET(REG_VAR(temp_reg)) 1421d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers CFI_ADJUST_CFA_OFFSET(4) 1431d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers // Store esp as the stop quick frame. 1441d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers movl %esp, %fs:THREAD_TOP_QUICK_FRAME_OFFSET 1455c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe 1465c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe // Ugly compile-time check, but we only have the preprocessor. 1475c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe // Last +4: implicit return address pushed on stack when caller made call. 148966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell#if (FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE != 7*4 + 4*8 + 4) 1495c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe#error "REFS_AND_ARGS_CALLEE_SAVE_FRAME(X86) size not as expected." 1505c1e4352614d61fed6868567e58b96682828cb4dAndreas Gampe#endif 151787ec205ee545b9c08f4fc6d3823cb43d10083afElliott HughesEND_MACRO 15257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers 1531d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers /* 1541d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers * Macro that sets up the callee save frame to conform with 1551d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers * Runtime::CreateCalleeSaveMethod(kRefsAndArgs) where the method is passed in EAX. 1561d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers */ 1571d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersMACRO0(SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME_WITH_METHOD_IN_EAX) 158966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Save callee and GPR args, mixed together to agree with core spills bitmap. 1591d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers PUSH edi // Save callee saves 1601d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers PUSH esi 1611d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers PUSH ebp 1621d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers PUSH ebx // Save args 1631d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers PUSH edx 1641d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers PUSH ecx 165966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 166966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Create space for FPR args. 167966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell subl MACRO_LITERAL(32), %esp 168966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell CFI_ADJUST_CFA_OFFSET(32) 169966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 170966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Save FPRs. 171966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movsd %xmm0, 0(%esp) 172966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movsd %xmm1, 8(%esp) 173966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movsd %xmm2, 16(%esp) 174966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movsd %xmm3, 24(%esp) 175966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 1761d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers PUSH eax // Store the ArtMethod reference at the bottom of the stack. 1771d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers // Store esp as the stop quick frame. 1781d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers movl %esp, %fs:THREAD_TOP_QUICK_FRAME_OFFSET 1791d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersEND_MACRO 1801d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers 1811d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersMACRO0(RESTORE_REFS_AND_ARGS_CALLEE_SAVE_FRAME) 182966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Restore FPRs. EAX is still on the stack. 183966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movsd 4(%esp), %xmm0 184966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movsd 12(%esp), %xmm1 185966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movsd 20(%esp), %xmm2 186966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movsd 28(%esp), %xmm3 187966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 188966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell addl MACRO_LITERAL(36), %esp // Remove FPRs and EAX. 189966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell CFI_ADJUST_CFA_OFFSET(-36) 190966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 1914360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe POP ecx // Restore args except eax 192aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers POP edx 193aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers POP ebx 1944360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe POP ebp // Restore callee saves 195aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers POP esi 196aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers POP edi 197787ec205ee545b9c08f4fc6d3823cb43d10083afElliott HughesEND_MACRO 19857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers 199966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell// Restore register and jump to routine 200966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell// Inputs: EDI contains pointer to code. 201966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell// Notes: Need to pop EAX too (restores Method*) 202966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P MendellMACRO0(RESTORE_REFS_AND_ARGS_CALLEE_SAVE_FRAME_AND_JUMP) 203966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell POP eax // Restore Method* 204966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 205966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Restore FPRs. 206966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movsd 0(%esp), %xmm0 207966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movsd 8(%esp), %xmm1 208966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movsd 16(%esp), %xmm2 209966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movsd 24(%esp), %xmm3 210966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 211966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell addl MACRO_LITERAL(32), %esp // Remove FPRs. 212966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell CFI_ADJUST_CFA_OFFSET(-32) 213966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 214966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell POP ecx // Restore args except eax 215966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell POP edx 216966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell POP ebx 217966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell POP ebp // Restore callee saves 218966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell POP esi 219966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell xchgl 0(%esp),%edi // restore EDI and place code pointer as only value on stack 220966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell ret 221966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P MendellEND_MACRO 222966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 22357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers /* 22457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers * Macro that set calls through to artDeliverPendingExceptionFromCode, where the pending 22557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers * exception is Thread::Current()->exception_. 22657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers */ 227787ec205ee545b9c08f4fc6d3823cb43d10083afElliott HughesMACRO0(DELIVER_PENDING_EXCEPTION) 2281d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers SETUP_SAVE_ALL_CALLEE_SAVE_FRAME ebx, ebx // save callee saves for throw 22957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers // Outgoing argument set up 2304360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe subl MACRO_LITERAL(12), %esp // Alignment padding 2311d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers CFI_ADJUST_CFA_OFFSET(12) 2321d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() 2333f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(4) 2341d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers call SYMBOL(artDeliverPendingExceptionFromCode) // artDeliverPendingExceptionFromCode(Thread*) 2354360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe UNREACHABLE 236787ec205ee545b9c08f4fc6d3823cb43d10083afElliott HughesEND_MACRO 23757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers 238787ec205ee545b9c08f4fc6d3823cb43d10083afElliott HughesMACRO2(NO_ARG_RUNTIME_EXCEPTION, c_name, cxx_name) 2394360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe DEFINE_FUNCTION VAR(c_name) 2401d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers SETUP_SAVE_ALL_CALLEE_SAVE_FRAME ebx, ebx // save all registers as basis for long jump context 24157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers // Outgoing argument set up 2424360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe subl MACRO_LITERAL(12), %esp // alignment padding 2431d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers CFI_ADJUST_CFA_OFFSET(12) 2444360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() 2453f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(4) 2464360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe call CALLVAR(cxx_name) // cxx_name(Thread*) 2474360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe UNREACHABLE 2484360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe END_FUNCTION VAR(c_name) 249787ec205ee545b9c08f4fc6d3823cb43d10083afElliott HughesEND_MACRO 25057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers 251787ec205ee545b9c08f4fc6d3823cb43d10083afElliott HughesMACRO2(ONE_ARG_RUNTIME_EXCEPTION, c_name, cxx_name) 2524360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe DEFINE_FUNCTION VAR(c_name) 2531d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers SETUP_SAVE_ALL_CALLEE_SAVE_FRAME ebx, ebx // save all registers as basis for long jump context 25457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers mov %esp, %ecx 25557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers // Outgoing argument set up 2564360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe subl MACRO_LITERAL(8), %esp // alignment padding 2571d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers CFI_ADJUST_CFA_OFFSET(8) 2584360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() 2593f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(4) 2604360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH eax // pass arg1 2614360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe call CALLVAR(cxx_name) // cxx_name(arg1, Thread*) 2624360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe UNREACHABLE 2634360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe END_FUNCTION VAR(c_name) 264787ec205ee545b9c08f4fc6d3823cb43d10083afElliott HughesEND_MACRO 26557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers 266787ec205ee545b9c08f4fc6d3823cb43d10083afElliott HughesMACRO2(TWO_ARG_RUNTIME_EXCEPTION, c_name, cxx_name) 2674360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe DEFINE_FUNCTION VAR(c_name) 2681d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers SETUP_SAVE_ALL_CALLEE_SAVE_FRAME ebx, ebx // save all registers as basis for long jump context 26957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers // Outgoing argument set up 2704360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH eax // alignment padding 2714360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() 2723f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(4) 2734360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH ecx // pass arg2 2744360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH eax // pass arg1 2754360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe call CALLVAR(cxx_name) // cxx_name(arg1, arg2, Thread*) 2764360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe UNREACHABLE 2774360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe END_FUNCTION VAR(c_name) 278787ec205ee545b9c08f4fc6d3823cb43d10083afElliott HughesEND_MACRO 27957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers 28057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers /* 28157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers * Called by managed code to create and deliver a NullPointerException. 28257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers */ 283468532ea115657709bc32ee498e701a4c71762d4Ian RogersNO_ARG_RUNTIME_EXCEPTION art_quick_throw_null_pointer_exception, artThrowNullPointerExceptionFromCode 28457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers 28557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers /* 28657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers * Called by managed code to create and deliver an ArithmeticException. 28757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers */ 288468532ea115657709bc32ee498e701a4c71762d4Ian RogersNO_ARG_RUNTIME_EXCEPTION art_quick_throw_div_zero, artThrowDivZeroFromCode 28957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers 29057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers /* 291787ec205ee545b9c08f4fc6d3823cb43d10083afElliott Hughes * Called by managed code to create and deliver a StackOverflowError. 29257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers */ 293468532ea115657709bc32ee498e701a4c71762d4Ian RogersNO_ARG_RUNTIME_EXCEPTION art_quick_throw_stack_overflow, artThrowStackOverflowFromCode 29457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers 29557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers /* 296787ec205ee545b9c08f4fc6d3823cb43d10083afElliott Hughes * Called by managed code, saves callee saves and then calls artThrowException 297787ec205ee545b9c08f4fc6d3823cb43d10083afElliott Hughes * that will place a mock Method* at the bottom of the stack. Arg1 holds the exception. 29857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers */ 299468532ea115657709bc32ee498e701a4c71762d4Ian RogersONE_ARG_RUNTIME_EXCEPTION art_quick_deliver_exception, artDeliverExceptionFromCode 30057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers 30157b86d47b66322693a070185fadfb43cb9c12eabIan Rogers /* 30257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers * Called by managed code to create and deliver a NoSuchMethodError. 30357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers */ 304468532ea115657709bc32ee498e701a4c71762d4Ian RogersONE_ARG_RUNTIME_EXCEPTION art_quick_throw_no_such_method, artThrowNoSuchMethodFromCode 30557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers 30657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers /* 307787ec205ee545b9c08f4fc6d3823cb43d10083afElliott Hughes * Called by managed code to create and deliver an ArrayIndexOutOfBoundsException. Arg1 holds 308787ec205ee545b9c08f4fc6d3823cb43d10083afElliott Hughes * index, arg2 holds limit. 309787ec205ee545b9c08f4fc6d3823cb43d10083afElliott Hughes */ 310468532ea115657709bc32ee498e701a4c71762d4Ian RogersTWO_ARG_RUNTIME_EXCEPTION art_quick_throw_array_bounds, artThrowArrayBoundsFromCode 311787ec205ee545b9c08f4fc6d3823cb43d10083afElliott Hughes 312787ec205ee545b9c08f4fc6d3823cb43d10083afElliott Hughes /* 31357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers * All generated callsites for interface invokes and invocation slow paths will load arguments 31457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers * as usual - except instead of loading arg0/r0 with the target Method*, arg0/r0 will contain 3157ea6a170486d81b127e69673cd1020c4db628c93Nicolas Geoffray * the method_idx. This wrapper will save arg1-arg3 and call the appropriate C helper. 31657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers * NOTE: "this" is first visible argument of the target, and so can be found in arg1/r1. 31757b86d47b66322693a070185fadfb43cb9c12eabIan Rogers * 31857b86d47b66322693a070185fadfb43cb9c12eabIan Rogers * The helper will attempt to locate the target and return a 64-bit result in r0/r1 consisting 31957b86d47b66322693a070185fadfb43cb9c12eabIan Rogers * of the target Method* in r0 and method->code_ in r1. 32057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers * 3212cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier * If unsuccessful, the helper will return null/null will bea pending exception in the 32257b86d47b66322693a070185fadfb43cb9c12eabIan Rogers * thread and we branch to another stub to deliver it. 32357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers * 32457b86d47b66322693a070185fadfb43cb9c12eabIan Rogers * On success this wrapper will restore arguments and *jump* to the target, leaving the lr 32557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers * pointing back to the original caller. 32657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers */ 3273031c8da0c5009183f770b005c245f9bf2a4d01bAndreas GampeMACRO1(INVOKE_TRAMPOLINE_BODY, cxx_name) 3281d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME ebx, ebx 3297caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers movl %esp, %edx // remember SP 330966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 3317caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers // Outgoing argument set up 332aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers PUSH edx // pass SP 3337caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() 3343f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(4) 335aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers PUSH ecx // pass arg2 336aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers PUSH eax // pass arg1 3374360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe call CALLVAR(cxx_name) // cxx_name(arg1, arg2, Thread*, SP) 3387caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers movl %edx, %edi // save code pointer in EDI 3397ea6a170486d81b127e69673cd1020c4db628c93Nicolas Geoffray addl MACRO_LITERAL(20), %esp // Pop arguments skip eax 3407ea6a170486d81b127e69673cd1020c4db628c93Nicolas Geoffray CFI_ADJUST_CFA_OFFSET(-20) 341966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 342966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Restore FPRs. 343966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movsd 0(%esp), %xmm0 344966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movsd 8(%esp), %xmm1 345966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movsd 16(%esp), %xmm2 346966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movsd 24(%esp), %xmm3 347966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 348966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Remove space for FPR args. 349966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell addl MACRO_LITERAL(4 * 8), %esp 350966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell CFI_ADJUST_CFA_OFFSET(-4 * 8) 351966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 352bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison POP ecx // Restore args except eax 353aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers POP edx 354aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers POP ebx 355bbb32c277b800a8ee378c16a3645ab6d4d19aef1Dave Allison POP ebp // Restore callee saves 356aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers POP esi 3577caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers // Swap EDI callee save with code pointer. 3587caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers xchgl %edi, (%esp) 3597caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers testl %eax, %eax // Branch forward if exception pending. 3607caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers jz 1f 3617caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers // Tail call to intended method. 3627caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers ret 3637caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers1: 36420b5c6c9d6fdd0b4192d467086a097a28d7b3a0ajeffhao addl MACRO_LITERAL(4), %esp // Pop code pointer off stack 3653f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(-4) 3667caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers DELIVER_PENDING_EXCEPTION 3673031c8da0c5009183f770b005c245f9bf2a4d01bAndreas GampeEND_MACRO 3683031c8da0c5009183f770b005c245f9bf2a4d01bAndreas GampeMACRO2(INVOKE_TRAMPOLINE, c_name, cxx_name) 3694360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe DEFINE_FUNCTION VAR(c_name) 3704360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe INVOKE_TRAMPOLINE_BODY RAW_VAR(cxx_name) 3714360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe END_FUNCTION VAR(c_name) 372787ec205ee545b9c08f4fc6d3823cb43d10083afElliott HughesEND_MACRO 37357b86d47b66322693a070185fadfb43cb9c12eabIan Rogers 3748dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienINVOKE_TRAMPOLINE art_quick_invoke_interface_trampoline_with_access_check, artInvokeInterfaceTrampolineWithAccessCheck 37557b86d47b66322693a070185fadfb43cb9c12eabIan Rogers 3768dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienINVOKE_TRAMPOLINE art_quick_invoke_static_trampoline_with_access_check, artInvokeStaticTrampolineWithAccessCheck 3778dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienINVOKE_TRAMPOLINE art_quick_invoke_direct_trampoline_with_access_check, artInvokeDirectTrampolineWithAccessCheck 3788dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienINVOKE_TRAMPOLINE art_quick_invoke_super_trampoline_with_access_check, artInvokeSuperTrampolineWithAccessCheck 3798dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienINVOKE_TRAMPOLINE art_quick_invoke_virtual_trampoline_with_access_check, artInvokeVirtualTrampolineWithAccessCheck 38057b86d47b66322693a070185fadfb43cb9c12eabIan Rogers 3815d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao /* 382966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell * Helper for quick invocation stub to set up XMM registers. 383966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell * Increments shorty and arg_array and clobbers temp_char. 384966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell * Branches to finished if it encounters the end of the shorty. 385966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell */ 386966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P MendellMACRO5(LOOP_OVER_SHORTY_LOADING_XMMS, xmm_reg, shorty, arg_array, temp_char, finished) 387966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell1: // LOOP 3884360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe movb (REG_VAR(shorty)), REG_VAR(temp_char) // temp_char := *shorty 3894360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe addl MACRO_LITERAL(1), REG_VAR(shorty) // shorty++ 3904360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe cmpb MACRO_LITERAL(0), REG_VAR(temp_char) // if (temp_char == '\0') 3914360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe je VAR(finished) // goto finished 3924360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe cmpb MACRO_LITERAL(68), REG_VAR(temp_char) // if (temp_char == 'D') 3934360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe je 2f // goto FOUND_DOUBLE 3944360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe cmpb MACRO_LITERAL(70), REG_VAR(temp_char) // if (temp_char == 'F') 3954360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe je 3f // goto FOUND_FLOAT 3964360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe addl MACRO_LITERAL(4), REG_VAR(arg_array) // arg_array++ 397966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Handle extra space in arg array taken by a long. 3984360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe cmpb MACRO_LITERAL(74), REG_VAR(temp_char) // if (temp_char != 'J') 3994360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe jne 1b // goto LOOP 4004360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe addl MACRO_LITERAL(4), REG_VAR(arg_array) // arg_array++ 4014360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe jmp 1b // goto LOOP 402966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell2: // FOUND_DOUBLE 4034360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe movsd (REG_VAR(arg_array)), REG_VAR(xmm_reg) 4044360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe addl MACRO_LITERAL(8), REG_VAR(arg_array) // arg_array+=2 405966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell jmp 4f 406966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell3: // FOUND_FLOAT 4074360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe movss (REG_VAR(arg_array)), REG_VAR(xmm_reg) 4084360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe addl MACRO_LITERAL(4), REG_VAR(arg_array) // arg_array++ 409966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell4: 410966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P MendellEND_MACRO 411966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 412966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell /* 413966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell * Helper for quick invocation stub to set up GPR registers. 414966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell * Increments shorty and arg_array, and returns the current short character in 415966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell * temp_char. Branches to finished if it encounters the end of the shorty. 416966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell */ 417966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P MendellMACRO4(SKIP_OVER_FLOATS, shorty, arg_array, temp_char, finished) 418966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell1: // LOOP: 4194360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe movb (REG_VAR(shorty)), REG_VAR(temp_char) // temp_char := *shorty 4204360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe addl MACRO_LITERAL(1), REG_VAR(shorty) // shorty++ 4214360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe cmpb MACRO_LITERAL(0), REG_VAR(temp_char) // if (temp_char == '\0') 4224360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe je VAR(finished) // goto finished 4234360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe cmpb MACRO_LITERAL(70), REG_VAR(temp_char) // if (temp_char == 'F') 4244360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe je 3f // goto SKIP_FLOAT 4254360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe cmpb MACRO_LITERAL(68), REG_VAR(temp_char) // if (temp_char == 'D') 4264360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe je 4f // goto SKIP_DOUBLE 4274360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe jmp 5f // goto end 428966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell3: // SKIP_FLOAT 4294360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe addl MACRO_LITERAL(4), REG_VAR(arg_array) // arg_array++ 4304360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe jmp 1b // goto LOOP 431966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell4: // SKIP_DOUBLE 4324360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe addl MACRO_LITERAL(8), REG_VAR(arg_array) // arg_array+=2 4334360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe jmp 1b // goto LOOP 434966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell5: 435966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P MendellEND_MACRO 436966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 437966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell /* 438966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell * Quick invocation stub (non-static). 4396474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao * On entry: 4406474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao * [sp] = return address 4416474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao * [sp + 4] = method pointer 4422cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier * [sp + 8] = argument array or null for no argument methods 4436474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao * [sp + 12] = size of argument array in bytes 4446474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao * [sp + 16] = (managed) thread pointer 4456474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao * [sp + 20] = JValue* result 4460177e53ea521ad58b70c305700dab32f1ac773b7Ian Rogers * [sp + 24] = shorty 4475d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao */ 4485d9173014c1ca09f7249a6b07629aa37778b5f8fJeff HaoDEFINE_FUNCTION art_quick_invoke_stub 449966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Save the non-volatiles. 4505d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao PUSH ebp // save ebp 4515d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao PUSH ebx // save ebx 4524808846b2a8647a448aaa05d561a4f60b190196bNicolas Geoffray PUSH esi // save esi 4534808846b2a8647a448aaa05d561a4f60b190196bNicolas Geoffray PUSH edi // save edi 454966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Set up argument XMM registers. 455966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell mov 24+16(%esp), %esi // ESI := shorty + 1 ; ie skip return arg character. 456966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell addl LITERAL(1), %esi 457966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell mov 8+16(%esp), %edi // EDI := arg_array + 4 ; ie skip this pointer. 458966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell addl LITERAL(4), %edi 459966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Clobbers ESI, EDI, EAX. 460966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell LOOP_OVER_SHORTY_LOADING_XMMS xmm0, esi, edi, al, .Lxmm_setup_finished 461966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell LOOP_OVER_SHORTY_LOADING_XMMS xmm1, esi, edi, al, .Lxmm_setup_finished 462966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell LOOP_OVER_SHORTY_LOADING_XMMS xmm2, esi, edi, al, .Lxmm_setup_finished 463966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell LOOP_OVER_SHORTY_LOADING_XMMS xmm3, esi, edi, al, .Lxmm_setup_finished 464966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell .balign 16 465966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell.Lxmm_setup_finished: 4665d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao mov %esp, %ebp // copy value of stack pointer into base pointer 4673f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_DEF_CFA_REGISTER(ebp) 4684808846b2a8647a448aaa05d561a4f60b190196bNicolas Geoffray mov 28(%ebp), %ebx // get arg array size 4694808846b2a8647a448aaa05d561a4f60b190196bNicolas Geoffray // reserve space for return addr, method*, ebx, ebp, esi, and edi in frame 4704808846b2a8647a448aaa05d561a4f60b190196bNicolas Geoffray addl LITERAL(36), %ebx 4714808846b2a8647a448aaa05d561a4f60b190196bNicolas Geoffray // align frame size to 16 bytes 4724808846b2a8647a448aaa05d561a4f60b190196bNicolas Geoffray andl LITERAL(0xFFFFFFF0), %ebx 4734808846b2a8647a448aaa05d561a4f60b190196bNicolas Geoffray subl LITERAL(20), %ebx // remove space for return address, ebx, ebp, esi and edi 4745d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao subl %ebx, %esp // reserve stack space for argument array 475966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 4762cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier movl LITERAL(0), (%esp) // store null for method* 477966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 478966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Copy arg array into stack. 479966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movl 28(%ebp), %ecx // ECX = size of args 480966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movl 24(%ebp), %esi // ESI = argument array 481966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell leal 4(%esp), %edi // EDI = just after Method* in stack arguments 482966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell rep movsb // while (ecx--) { *edi++ = *esi++ } 483966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 484966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell mov 40(%ebp), %esi // ESI := shorty + 1 ; ie skip return arg character. 485966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell addl LITERAL(1), %esi 486966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell mov 24(%ebp), %edi // EDI := arg_array 487966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell mov 0(%edi), %ecx // ECX := this pointer 488966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell addl LITERAL(4), %edi // EDI := arg_array + 4 ; ie skip this pointer. 489966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 490966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Enumerate the possible cases for loading GPRS. 491966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // edx (and maybe ebx): 492966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell SKIP_OVER_FLOATS esi, edi, al, .Lgpr_setup_finished 493966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell cmpb LITERAL(74), %al // if (al == 'J') goto FOUND_LONG 494966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell je .LfirstLong 495966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Must be an integer value. 496966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movl (%edi), %edx 497966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell addl LITERAL(4), %edi // arg_array++ 498966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 499966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Now check ebx 500966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell SKIP_OVER_FLOATS esi, edi, al, .Lgpr_setup_finished 5013e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell // Must be first word of a long, or an integer. First word of long doesn't 5023e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell // go into EBX, but can be loaded there anyways, as it is harmless. 503966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movl (%edi), %ebx 504966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell jmp .Lgpr_setup_finished 505966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell.LfirstLong: 506966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movl (%edi), %edx 507966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movl 4(%edi), %ebx 508966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Nothing left to load. 509966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell.Lgpr_setup_finished: 5104808846b2a8647a448aaa05d561a4f60b190196bNicolas Geoffray mov 20(%ebp), %eax // move method pointer into eax 511e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier call *ART_METHOD_QUICK_CODE_OFFSET_32(%eax) // call the method 5125d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao mov %ebp, %esp // restore stack pointer 5133f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_DEF_CFA_REGISTER(esp) 5144808846b2a8647a448aaa05d561a4f60b190196bNicolas Geoffray POP edi // pop edi 5154808846b2a8647a448aaa05d561a4f60b190196bNicolas Geoffray POP esi // pop esi 5165d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao POP ebx // pop ebx 5175d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao POP ebp // pop ebp 5185d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao mov 20(%esp), %ecx // get result pointer 5190177e53ea521ad58b70c305700dab32f1ac773b7Ian Rogers mov %eax, (%ecx) // store the result assuming its a long, int or Object* 5200177e53ea521ad58b70c305700dab32f1ac773b7Ian Rogers mov %edx, 4(%ecx) // store the other half of the result 5210177e53ea521ad58b70c305700dab32f1ac773b7Ian Rogers mov 24(%esp), %edx // get the shorty 5220177e53ea521ad58b70c305700dab32f1ac773b7Ian Rogers cmpb LITERAL(68), (%edx) // test if result type char == 'D' 5238016a12a5f9c2ea70b52e353a0169ba836ee9402Ian Rogers je .Lreturn_double_quick 5240177e53ea521ad58b70c305700dab32f1ac773b7Ian Rogers cmpb LITERAL(70), (%edx) // test if result type char == 'F' 5258016a12a5f9c2ea70b52e353a0169ba836ee9402Ian Rogers je .Lreturn_float_quick 5266474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao ret 5278016a12a5f9c2ea70b52e353a0169ba836ee9402Ian Rogers.Lreturn_double_quick: 5285d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao movsd %xmm0, (%ecx) // store the floating point result 5295d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao ret 5308016a12a5f9c2ea70b52e353a0169ba836ee9402Ian Rogers.Lreturn_float_quick: 5310177e53ea521ad58b70c305700dab32f1ac773b7Ian Rogers movss %xmm0, (%ecx) // store the floating point result 5320177e53ea521ad58b70c305700dab32f1ac773b7Ian Rogers ret 5335d9173014c1ca09f7249a6b07629aa37778b5f8fJeff HaoEND_FUNCTION art_quick_invoke_stub 5345d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao 535966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell /* 536966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell * Quick invocation stub (static). 537966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell * On entry: 538966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell * [sp] = return address 539966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell * [sp + 4] = method pointer 5402cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier * [sp + 8] = argument array or null for no argument methods 541966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell * [sp + 12] = size of argument array in bytes 542966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell * [sp + 16] = (managed) thread pointer 543966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell * [sp + 20] = JValue* result 544966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell * [sp + 24] = shorty 545966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell */ 546966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P MendellDEFINE_FUNCTION art_quick_invoke_static_stub 547966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Save the non-volatiles. 548966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell PUSH ebp // save ebp 549966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell PUSH ebx // save ebx 550966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell PUSH esi // save esi 551966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell PUSH edi // save edi 552966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Set up argument XMM registers. 553966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell mov 24+16(%esp), %esi // ESI := shorty + 1 ; ie skip return arg character. 554966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell addl LITERAL(1), %esi 555966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell mov 8+16(%esp), %edi // EDI := arg_array 556966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Clobbers ESI, EDI, EAX. 557966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell LOOP_OVER_SHORTY_LOADING_XMMS xmm0, esi, edi, al, .Lxmm_setup_finished2 558966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell LOOP_OVER_SHORTY_LOADING_XMMS xmm1, esi, edi, al, .Lxmm_setup_finished2 559966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell LOOP_OVER_SHORTY_LOADING_XMMS xmm2, esi, edi, al, .Lxmm_setup_finished2 560966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell LOOP_OVER_SHORTY_LOADING_XMMS xmm3, esi, edi, al, .Lxmm_setup_finished2 561966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell .balign 16 562966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell.Lxmm_setup_finished2: 563966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell mov %esp, %ebp // copy value of stack pointer into base pointer 564966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell CFI_DEF_CFA_REGISTER(ebp) 565966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell mov 28(%ebp), %ebx // get arg array size 566966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // reserve space for return addr, method*, ebx, ebp, esi, and edi in frame 567966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell addl LITERAL(36), %ebx 568966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // align frame size to 16 bytes 569966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell andl LITERAL(0xFFFFFFF0), %ebx 570966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell subl LITERAL(20), %ebx // remove space for return address, ebx, ebp, esi and edi 571966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell subl %ebx, %esp // reserve stack space for argument array 572966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 5732cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier movl LITERAL(0), (%esp) // store null for method* 574966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 575966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Copy arg array into stack. 576966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movl 28(%ebp), %ecx // ECX = size of args 577966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movl 24(%ebp), %esi // ESI = argument array 578966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell leal 4(%esp), %edi // EDI = just after Method* in stack arguments 579966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell rep movsb // while (ecx--) { *edi++ = *esi++ } 580966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 581966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell mov 40(%ebp), %esi // ESI := shorty + 1 ; ie skip return arg character. 582966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell addl LITERAL(1), %esi 583966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell mov 24(%ebp), %edi // EDI := arg_array 584966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 585966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Enumerate the possible cases for loading GPRS. 586966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // ecx (and maybe edx) 587966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell SKIP_OVER_FLOATS esi, edi, al, .Lgpr_setup_finished2 588966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell cmpb LITERAL(74), %al // if (al == 'J') goto FOUND_LONG 589966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell je .LfirstLong2 590966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Must be an integer value. Load into ECX. 591966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movl (%edi), %ecx 592966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell addl LITERAL(4), %edi // arg_array++ 593966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 594966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Now check edx (and maybe ebx). 595966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell SKIP_OVER_FLOATS esi, edi, al, .Lgpr_setup_finished2 596966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell cmpb LITERAL(74), %al // if (al == 'J') goto FOUND_LONG 597966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell je .LSecondLong2 598966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Must be an integer. Load into EDX. 599966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movl (%edi), %edx 600966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell addl LITERAL(4), %edi // arg_array++ 601966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 602966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Is there anything for ebx? 603966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell SKIP_OVER_FLOATS esi, edi, al, .Lgpr_setup_finished2 6043e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell // Must be first word of a long, or an integer. First word of long doesn't 6053e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell // go into EBX, but can be loaded there anyways, as it is harmless. 606966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movl (%edi), %ebx 607966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell jmp .Lgpr_setup_finished2 608966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell.LSecondLong2: 609966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // EDX:EBX is long. That is all. 610966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movl (%edi), %edx 611966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movl 4(%edi), %ebx 612966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell jmp .Lgpr_setup_finished2 613966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell.LfirstLong2: 614966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // ECX:EDX is a long 615966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movl (%edi), %ecx 616966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movl 4(%edi), %edx 617966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell addl LITERAL(8), %edi // arg_array += 2 618966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 619966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Anything for EBX? 620966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell SKIP_OVER_FLOATS esi, edi, al, .Lgpr_setup_finished2 6213e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell // Must be first word of a long, or an integer. First word of long doesn't 6223e6a3bf797e49b7f449256455c7e522e888687d8Mark Mendell // go into EBX, but can be loaded there anyways, as it is harmless. 623966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movl (%edi), %ebx 624966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell jmp .Lgpr_setup_finished2 625966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Nothing left to load. 626966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell.Lgpr_setup_finished2: 627966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell mov 20(%ebp), %eax // move method pointer into eax 628e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier call *ART_METHOD_QUICK_CODE_OFFSET_32(%eax) // call the method 629966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell mov %ebp, %esp // restore stack pointer 630966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell CFI_DEF_CFA_REGISTER(esp) 631966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell POP edi // pop edi 632966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell POP esi // pop esi 633966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell POP ebx // pop ebx 634966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell POP ebp // pop ebp 635966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell mov 20(%esp), %ecx // get result pointer 636966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell mov %eax, (%ecx) // store the result assuming its a long, int or Object* 637966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell mov %edx, 4(%ecx) // store the other half of the result 638966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell mov 24(%esp), %edx // get the shorty 639966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell cmpb LITERAL(68), (%edx) // test if result type char == 'D' 640966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell je .Lreturn_double_quick2 641966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell cmpb LITERAL(70), (%edx) // test if result type char == 'F' 642966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell je .Lreturn_float_quick2 643966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell ret 644966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell.Lreturn_double_quick2: 645966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movsd %xmm0, (%ecx) // store the floating point result 646966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell ret 647966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell.Lreturn_float_quick2: 648966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movss %xmm0, (%ecx) // store the floating point result 649966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell ret 650966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P MendellEND_FUNCTION art_quick_invoke_static_stub 651966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 652d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan RogersMACRO3(NO_ARG_DOWNCALL, c_name, cxx_name, return_macro) 6534360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe DEFINE_FUNCTION VAR(c_name) 6541d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers SETUP_REFS_ONLY_CALLEE_SAVE_FRAME ebx, ebx // save ref containing registers for GC 6557caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers // Outgoing argument set up 6564360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe subl MACRO_LITERAL(12), %esp // push padding 6571d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers CFI_ADJUST_CFA_OFFSET(12) 6584360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() 6593f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(4) 6604360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe call CALLVAR(cxx_name) // cxx_name(Thread*) 6614360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe addl MACRO_LITERAL(16), %esp // pop arguments 6623f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(-16) 6634360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address 6644360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe CALL_MACRO(return_macro) // return or deliver exception 6654360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe END_FUNCTION VAR(c_name) 6667caad77632ae121c9f64c488e3f8f710e2c4813dIan RogersEND_MACRO 6677caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers 668d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan RogersMACRO3(ONE_ARG_DOWNCALL, c_name, cxx_name, return_macro) 6694360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe DEFINE_FUNCTION VAR(c_name) 6701d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers SETUP_REFS_ONLY_CALLEE_SAVE_FRAME ebx, ebx // save ref containing registers for GC 6717caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers // Outgoing argument set up 6724360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe subl MACRO_LITERAL(8), %esp // push padding 6731d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers CFI_ADJUST_CFA_OFFSET(8) 6744360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() 6753f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(4) 6764360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH eax // pass arg1 6774360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe call CALLVAR(cxx_name) // cxx_name(arg1, Thread*) 6784360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe addl MACRO_LITERAL(16), %esp // pop arguments 6793f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(-16) 6804360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address 6814360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe CALL_MACRO(return_macro) // return or deliver exception 6824360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe END_FUNCTION VAR(c_name) 683d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan RogersEND_MACRO 6847caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers 685d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan RogersMACRO3(TWO_ARG_DOWNCALL, c_name, cxx_name, return_macro) 6864360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe DEFINE_FUNCTION VAR(c_name) 6871d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers SETUP_REFS_ONLY_CALLEE_SAVE_FRAME ebx, ebx // save ref containing registers for GC 6887caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers // Outgoing argument set up 6894360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH eax // push padding 6904360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() 6913f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(4) 6924360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH ecx // pass arg2 6934360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH eax // pass arg1 6944360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe call CALLVAR(cxx_name) // cxx_name(arg1, arg2, Thread*) 6954360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe addl MACRO_LITERAL(16), %esp // pop arguments 6963f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(-16) 6974360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address 6984360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe CALL_MACRO(return_macro) // return or deliver exception 6994360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe END_FUNCTION VAR(c_name) 700d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan RogersEND_MACRO 7017caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers 702d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan RogersMACRO3(THREE_ARG_DOWNCALL, c_name, cxx_name, return_macro) 7034360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe DEFINE_FUNCTION VAR(c_name) 7041d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers SETUP_REFS_ONLY_CALLEE_SAVE_FRAME ebx, ebx // save ref containing registers for GC 7057caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers // Outgoing argument set up 7064360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() 7073f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(4) 7084360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH edx // pass arg3 7094360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH ecx // pass arg2 7104360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH eax // pass arg1 7114360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe call CALLVAR(cxx_name) // cxx_name(arg1, arg2, arg3, Thread*) 7124360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe addl MACRO_LITERAL(16), %esp // pop arguments 7131d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers CFI_ADJUST_CFA_OFFSET(-16) 7144360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address 7154360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe CALL_MACRO(return_macro) // return or deliver exception 7164360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe END_FUNCTION VAR(c_name) 717d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan RogersEND_MACRO 718d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers 719848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff HaoMACRO3(FOUR_ARG_DOWNCALL, c_name, cxx_name, return_macro) 7204360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe DEFINE_FUNCTION VAR(c_name) 721a048ca8e0ff6d0e79d070decf9fa2331e2d13824Nicolas Geoffray SETUP_REFS_ONLY_CALLEE_SAVE_FRAME_PRESERVE_GOT_REG ebx, ebx // save ref containing registers for GC 722f969a209c30e3af636342d2fb7851d82a2529bf7Roland Levillain 723848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao // Outgoing argument set up 7244360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe subl MACRO_LITERAL(12), %esp // alignment padding 725848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao CFI_ADJUST_CFA_OFFSET(12) 7264360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() 727848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao CFI_ADJUST_CFA_OFFSET(4) 7284360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH ebx // pass arg4 7294360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH edx // pass arg3 7304360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH ecx // pass arg2 7314360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH eax // pass arg1 7324360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe call CALLVAR(cxx_name) // cxx_name(arg1, arg2, arg3, arg4, Thread*) 7334360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe addl MACRO_LITERAL(32), %esp // pop arguments 734848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao CFI_ADJUST_CFA_OFFSET(-32) 7354360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address 7364360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe CALL_MACRO(return_macro) // return or deliver exception 7374360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe END_FUNCTION VAR(c_name) 738848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff HaoEND_MACRO 739848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao 74037f05ef45e0393de812d51261dc293240c17294dFred ShihMACRO3(ONE_ARG_REF_DOWNCALL, c_name, cxx_name, return_macro) 7414360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe DEFINE_FUNCTION VAR(c_name) 7424360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe SETUP_REFS_ONLY_CALLEE_SAVE_FRAME ebx, ebx // save ref containing registers for GC 74337f05ef45e0393de812d51261dc293240c17294dFred Shih // Outgoing argument set up 7441d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers mov FRAME_SIZE_REFS_ONLY_CALLEE_SAVE(%esp), %ecx // get referrer 7454360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH eax // push padding 7464360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() 74737f05ef45e0393de812d51261dc293240c17294dFred Shih CFI_ADJUST_CFA_OFFSET(4) 7484360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH ecx // pass referrer 7494360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH eax // pass arg1 7504360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe call CALLVAR(cxx_name) // cxx_name(arg1, referrer, Thread*) 7514360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe addl MACRO_LITERAL(16), %esp // pop arguments 75237f05ef45e0393de812d51261dc293240c17294dFred Shih CFI_ADJUST_CFA_OFFSET(-16) 7534360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address 7544360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe CALL_MACRO(return_macro) // return or deliver exception 7554360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe END_FUNCTION VAR(c_name) 75637f05ef45e0393de812d51261dc293240c17294dFred ShihEND_MACRO 75737f05ef45e0393de812d51261dc293240c17294dFred Shih 75837f05ef45e0393de812d51261dc293240c17294dFred ShihMACRO3(TWO_ARG_REF_DOWNCALL, c_name, cxx_name, return_macro) 7594360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe DEFINE_FUNCTION VAR(c_name) 7604360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe SETUP_REFS_ONLY_CALLEE_SAVE_FRAME ebx, ebx // save ref containing registers for GC 7611d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers // Outgoing argument set up 7621d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers mov FRAME_SIZE_REFS_ONLY_CALLEE_SAVE(%esp), %edx // get referrer 7634360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() 76437f05ef45e0393de812d51261dc293240c17294dFred Shih CFI_ADJUST_CFA_OFFSET(4) 7654360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH edx // pass referrer 7664360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH ecx // pass arg2 7674360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH eax // pass arg1 7684360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe call CALLVAR(cxx_name) // cxx_name(arg1, arg2, referrer, Thread*) 7694360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe addl MACRO_LITERAL(16), %esp // pop arguments 7701d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers CFI_ADJUST_CFA_OFFSET(-16) 7714360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address 7724360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe CALL_MACRO(return_macro) // return or deliver exception 7734360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe END_FUNCTION VAR(c_name) 77437f05ef45e0393de812d51261dc293240c17294dFred ShihEND_MACRO 77537f05ef45e0393de812d51261dc293240c17294dFred Shih 7761d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersMACRO3(THREE_ARG_REF_DOWNCALL, c_name, cxx_name, return_macro) 7774360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe DEFINE_FUNCTION VAR(c_name) 7784360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe SETUP_REFS_ONLY_CALLEE_SAVE_FRAME ebx, ebx // save ref containing registers for GC 7791d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers // Outgoing argument set up 7801d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers mov FRAME_SIZE_REFS_ONLY_CALLEE_SAVE(%esp), %ebx // get referrer 7814360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe subl MACRO_LITERAL(12), %esp // alignment padding 7821d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers CFI_ADJUST_CFA_OFFSET(12) 7834360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() 7841d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers CFI_ADJUST_CFA_OFFSET(4) 7854360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH ebx // pass referrer 7864360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH edx // pass arg3 7874360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH ecx // pass arg2 7884360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH eax // pass arg1 7894360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe call CALLVAR(cxx_name) // cxx_name(arg1, arg2, arg3, referrer, 7904360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe // Thread*) 7914360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe addl LITERAL(32), %esp // pop arguments 7921d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers CFI_ADJUST_CFA_OFFSET(-32) 7934360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address 7944360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe CALL_MACRO(return_macro) // return or deliver exception 7954360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe END_FUNCTION VAR(c_name) 7961d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersEND_MACRO 79737f05ef45e0393de812d51261dc293240c17294dFred Shih 7984adeab196d160f70b4865fb8be048ddd2ac7ab82Hiroshi YamauchiMACRO0(RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER) 799d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers testl %eax, %eax // eax == 0 ? 800d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers jz 1f // if eax == 0 goto 1 801d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers ret // return 802d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers1: // deliver exception on current thread 803d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers DELIVER_PENDING_EXCEPTION 804d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan RogersEND_MACRO 805d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers 806d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan RogersMACRO0(RETURN_IF_EAX_ZERO) 807d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers testl %eax, %eax // eax == 0 ? 808d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers jnz 1f // if eax != 0 goto 1 809d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers ret // return 810d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers1: // deliver exception on current thread 8117caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers DELIVER_PENDING_EXCEPTION 812d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan RogersEND_MACRO 813d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers 814d66a87583bebcd5f89906aeaae9f8fb104ef2ac9jeffhaoMACRO0(RETURN_OR_DELIVER_PENDING_EXCEPTION) 8151d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers cmpl MACRO_LITERAL(0),%fs:THREAD_EXCEPTION_OFFSET // exception field == 0 ? 8164360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe jne 1f // if exception field != 0 goto 1 8174360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe ret // return 8184360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe1: // deliver exception on current thread 819d66a87583bebcd5f89906aeaae9f8fb104ef2ac9jeffhao DELIVER_PENDING_EXCEPTION 820d66a87583bebcd5f89906aeaae9f8fb104ef2ac9jeffhaoEND_MACRO 821d66a87583bebcd5f89906aeaae9f8fb104ef2ac9jeffhao 8227410f29b4dae223befac036ea567d7f33351dad1Mathieu Chartier// Generate the allocation entrypoints for each allocator. 8234adeab196d160f70b4865fb8be048ddd2ac7ab82Hiroshi YamauchiGENERATE_ALLOC_ENTRYPOINTS_FOR_EACH_ALLOCATOR 824de95c870993673b512009d94a931cd980df0e6b6lwang 825de95c870993673b512009d94a931cd980df0e6b6lwang// A hand-written override for GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT(_rosalloc, RosAlloc). 826de95c870993673b512009d94a931cd980df0e6b6lwangDEFINE_FUNCTION art_quick_alloc_object_rosalloc 827de95c870993673b512009d94a931cd980df0e6b6lwang // Fast path rosalloc allocation. 828de95c870993673b512009d94a931cd980df0e6b6lwang // eax: uint32_t type_idx/return value, ecx: ArtMethod* 829de95c870993673b512009d94a931cd980df0e6b6lwang // ebx, edx: free 830de95c870993673b512009d94a931cd980df0e6b6lwang PUSH edi 831de95c870993673b512009d94a931cd980df0e6b6lwang movl ART_METHOD_DEX_CACHE_TYPES_OFFSET_32(%ecx), %edx // Load dex cache resolved types array 832de95c870993673b512009d94a931cd980df0e6b6lwang // Load the class (edx) 833de95c870993673b512009d94a931cd980df0e6b6lwang movl 0(%edx, %eax, COMPRESSED_REFERENCE_SIZE), %edx 834de95c870993673b512009d94a931cd980df0e6b6lwang testl %edx, %edx // Check null class 835de95c870993673b512009d94a931cd980df0e6b6lwang jz .Lart_quick_alloc_object_rosalloc_slow_path 836de95c870993673b512009d94a931cd980df0e6b6lwang // Check class status 837de95c870993673b512009d94a931cd980df0e6b6lwang cmpl LITERAL(MIRROR_CLASS_STATUS_INITIALIZED), MIRROR_CLASS_STATUS_OFFSET(%edx) 838de95c870993673b512009d94a931cd980df0e6b6lwang jne .Lart_quick_alloc_object_rosalloc_slow_path 839de95c870993673b512009d94a931cd980df0e6b6lwang // No fake dependence needed on x86 840de95c870993673b512009d94a931cd980df0e6b6lwang // between status and flags load, 841de95c870993673b512009d94a931cd980df0e6b6lwang // since each load is a load-acquire, 842de95c870993673b512009d94a931cd980df0e6b6lwang // no loads reordering. 843de95c870993673b512009d94a931cd980df0e6b6lwang // Check access flags has 844de95c870993673b512009d94a931cd980df0e6b6lwang // kAccClassIsFinalizable 845de95c870993673b512009d94a931cd980df0e6b6lwang testl LITERAL(ACCESS_FLAGS_CLASS_IS_FINALIZABLE), MIRROR_CLASS_ACCESS_FLAGS_OFFSET(%edx) 846de95c870993673b512009d94a931cd980df0e6b6lwang jnz .Lart_quick_alloc_object_rosalloc_slow_path 847de95c870993673b512009d94a931cd980df0e6b6lwang 848de95c870993673b512009d94a931cd980df0e6b6lwang movl %fs:THREAD_SELF_OFFSET, %ebx // ebx = thread 849de95c870993673b512009d94a931cd980df0e6b6lwang // Check if the thread local allocation 850de95c870993673b512009d94a931cd980df0e6b6lwang // stack has room 851de95c870993673b512009d94a931cd980df0e6b6lwang movl THREAD_LOCAL_ALLOC_STACK_TOP_OFFSET(%ebx), %edi 852de95c870993673b512009d94a931cd980df0e6b6lwang cmpl THREAD_LOCAL_ALLOC_STACK_END_OFFSET(%ebx), %edi 853de95c870993673b512009d94a931cd980df0e6b6lwang jae .Lart_quick_alloc_object_rosalloc_slow_path 854de95c870993673b512009d94a931cd980df0e6b6lwang 855de95c870993673b512009d94a931cd980df0e6b6lwang movl MIRROR_CLASS_OBJECT_SIZE_OFFSET(%edx), %edi // Load the object size (edi) 856de95c870993673b512009d94a931cd980df0e6b6lwang // Check if the size is for a thread 857de95c870993673b512009d94a931cd980df0e6b6lwang // local allocation 858de95c870993673b512009d94a931cd980df0e6b6lwang cmpl LITERAL(ROSALLOC_MAX_THREAD_LOCAL_BRACKET_SIZE), %edi 859de95c870993673b512009d94a931cd980df0e6b6lwang ja .Lart_quick_alloc_object_rosalloc_slow_path 860de95c870993673b512009d94a931cd980df0e6b6lwang decl %edi 861de95c870993673b512009d94a931cd980df0e6b6lwang shrl LITERAL(ROSALLOC_BRACKET_QUANTUM_SIZE_SHIFT), %edi // Calculate the rosalloc bracket index 862de95c870993673b512009d94a931cd980df0e6b6lwang // from object size. 863de95c870993673b512009d94a931cd980df0e6b6lwang // Align up the size by the rosalloc 864de95c870993673b512009d94a931cd980df0e6b6lwang // bracket quantum size and divide 865de95c870993673b512009d94a931cd980df0e6b6lwang // by the quantum size and subtract 866de95c870993673b512009d94a931cd980df0e6b6lwang // by 1. This code is a shorter but 867de95c870993673b512009d94a931cd980df0e6b6lwang // equivalent version. 868de95c870993673b512009d94a931cd980df0e6b6lwang // Load thread local rosalloc run (ebx) 869de95c870993673b512009d94a931cd980df0e6b6lwang movl THREAD_ROSALLOC_RUNS_OFFSET(%ebx, %edi, __SIZEOF_POINTER__), %ebx 870de95c870993673b512009d94a931cd980df0e6b6lwang // Load free_list head (edi), 871de95c870993673b512009d94a931cd980df0e6b6lwang // this will be the return value. 872de95c870993673b512009d94a931cd980df0e6b6lwang movl (ROSALLOC_RUN_FREE_LIST_OFFSET + ROSALLOC_RUN_FREE_LIST_HEAD_OFFSET)(%ebx), %edi 873de95c870993673b512009d94a931cd980df0e6b6lwang test %edi, %edi 874de95c870993673b512009d94a931cd980df0e6b6lwang jz .Lart_quick_alloc_object_rosalloc_slow_path 875de95c870993673b512009d94a931cd980df0e6b6lwang // Point of no slow path. Won't go to 876de95c870993673b512009d94a931cd980df0e6b6lwang // the slow path from here on. Ok to 877de95c870993673b512009d94a931cd980df0e6b6lwang // clobber eax and ecx. 878de95c870993673b512009d94a931cd980df0e6b6lwang movl %edi, %eax 879de95c870993673b512009d94a931cd980df0e6b6lwang // Load the next pointer of the head 880de95c870993673b512009d94a931cd980df0e6b6lwang // and update head of free list with 881de95c870993673b512009d94a931cd980df0e6b6lwang // next pointer 882de95c870993673b512009d94a931cd980df0e6b6lwang movl ROSALLOC_SLOT_NEXT_OFFSET(%eax), %edi 883de95c870993673b512009d94a931cd980df0e6b6lwang movl %edi, (ROSALLOC_RUN_FREE_LIST_OFFSET + ROSALLOC_RUN_FREE_LIST_HEAD_OFFSET)(%ebx) 884de95c870993673b512009d94a931cd980df0e6b6lwang // Decrement size of free list by 1 885de95c870993673b512009d94a931cd980df0e6b6lwang decl (ROSALLOC_RUN_FREE_LIST_OFFSET + ROSALLOC_RUN_FREE_LIST_SIZE_OFFSET)(%ebx) 886de95c870993673b512009d94a931cd980df0e6b6lwang // Store the class pointer in the 887de95c870993673b512009d94a931cd980df0e6b6lwang // header. This also overwrites the 888de95c870993673b512009d94a931cd980df0e6b6lwang // next pointer. The offsets are 889de95c870993673b512009d94a931cd980df0e6b6lwang // asserted to match. 890de95c870993673b512009d94a931cd980df0e6b6lwang#if ROSALLOC_SLOT_NEXT_OFFSET != MIRROR_OBJECT_CLASS_OFFSET 891de95c870993673b512009d94a931cd980df0e6b6lwang#error "Class pointer needs to overwrite next pointer." 892de95c870993673b512009d94a931cd980df0e6b6lwang#endif 893de95c870993673b512009d94a931cd980df0e6b6lwang POISON_HEAP_REF edx 894de95c870993673b512009d94a931cd980df0e6b6lwang movl %edx, MIRROR_OBJECT_CLASS_OFFSET(%eax) 895de95c870993673b512009d94a931cd980df0e6b6lwang movl %fs:THREAD_SELF_OFFSET, %ebx // ebx = thread 896de95c870993673b512009d94a931cd980df0e6b6lwang // Push the new object onto the thread 897de95c870993673b512009d94a931cd980df0e6b6lwang // local allocation stack and 898de95c870993673b512009d94a931cd980df0e6b6lwang // increment the thread local 899de95c870993673b512009d94a931cd980df0e6b6lwang // allocation stack top. 900de95c870993673b512009d94a931cd980df0e6b6lwang movl THREAD_LOCAL_ALLOC_STACK_TOP_OFFSET(%ebx), %edi 901de95c870993673b512009d94a931cd980df0e6b6lwang movl %eax, (%edi) 902de95c870993673b512009d94a931cd980df0e6b6lwang addl LITERAL(COMPRESSED_REFERENCE_SIZE), %edi 903de95c870993673b512009d94a931cd980df0e6b6lwang movl %edi, THREAD_LOCAL_ALLOC_STACK_TOP_OFFSET(%ebx) 904de95c870993673b512009d94a931cd980df0e6b6lwang // No fence needed for x86. 905de95c870993673b512009d94a931cd980df0e6b6lwang POP edi 906de95c870993673b512009d94a931cd980df0e6b6lwang ret 907de95c870993673b512009d94a931cd980df0e6b6lwang.Lart_quick_alloc_object_rosalloc_slow_path: 908de95c870993673b512009d94a931cd980df0e6b6lwang POP edi 909de95c870993673b512009d94a931cd980df0e6b6lwang SETUP_REFS_ONLY_CALLEE_SAVE_FRAME ebx, ebx // save ref containing registers for GC 910de95c870993673b512009d94a931cd980df0e6b6lwang // Outgoing argument set up 911de95c870993673b512009d94a931cd980df0e6b6lwang PUSH eax // alignment padding 912de95c870993673b512009d94a931cd980df0e6b6lwang pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() 913de95c870993673b512009d94a931cd980df0e6b6lwang CFI_ADJUST_CFA_OFFSET(4) 914de95c870993673b512009d94a931cd980df0e6b6lwang PUSH ecx 915de95c870993673b512009d94a931cd980df0e6b6lwang PUSH eax 916de95c870993673b512009d94a931cd980df0e6b6lwang call SYMBOL(artAllocObjectFromCodeRosAlloc) // cxx_name(arg0, arg1, Thread*) 917de95c870993673b512009d94a931cd980df0e6b6lwang addl LITERAL(16), %esp // pop arguments 918de95c870993673b512009d94a931cd980df0e6b6lwang CFI_ADJUST_CFA_OFFSET(-16) 919de95c870993673b512009d94a931cd980df0e6b6lwang RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME // resotre frame up to return address 920de95c870993673b512009d94a931cd980df0e6b6lwang RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER // return or deliver exception 921de95c870993673b512009d94a931cd980df0e6b6lwangEND_FUNCTION art_quick_alloc_object_rosalloc 922de95c870993673b512009d94a931cd980df0e6b6lwang 9233f2d031f639b3b9dd4adbf9e70d23de931a9801dMark MendellGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT(_tlab, TLAB) 92410d4c08c0ea9df0a85a11e1c77974df24078c0ecHiroshi YamauchiGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT(_region_tlab, RegionTLAB) 9254adeab196d160f70b4865fb8be048ddd2ac7ab82Hiroshi Yamauchi 9264adeab196d160f70b4865fb8be048ddd2ac7ab82Hiroshi YamauchiONE_ARG_DOWNCALL art_quick_resolve_string, artResolveStringFromCode, RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER 9274adeab196d160f70b4865fb8be048ddd2ac7ab82Hiroshi YamauchiONE_ARG_DOWNCALL art_quick_initialize_static_storage, artInitializeStaticStorageFromCode, RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER 9284adeab196d160f70b4865fb8be048ddd2ac7ab82Hiroshi YamauchiONE_ARG_DOWNCALL art_quick_initialize_type, artInitializeTypeFromCode, RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER 9294adeab196d160f70b4865fb8be048ddd2ac7ab82Hiroshi YamauchiONE_ARG_DOWNCALL art_quick_initialize_type_and_verify_access, artInitializeTypeAndVerifyAccessFromCode, RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER 930d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers 931832336b3c9eb892045a8de1bb12c9361112ca3c5Ian RogersTWO_ARG_REF_DOWNCALL art_quick_handle_fill_data, artHandleFillArrayDataFromCode, RETURN_IF_EAX_ZERO 9327caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers 933d9c4fc94fa618617f94e1de9af5f034549100753Ian RogersDEFINE_FUNCTION art_quick_lock_object 934d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers testl %eax, %eax // null check object/eax 9358016a12a5f9c2ea70b52e353a0169ba836ee9402Ian Rogers jz .Lslow_lock 9368016a12a5f9c2ea70b52e353a0169ba836ee9402Ian Rogers.Lretry_lock: 9371d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers movl MIRROR_OBJECT_LOCK_WORD_OFFSET(%eax), %ecx // ecx := lock word 938e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi test LITERAL(LOCK_WORD_STATE_MASK), %ecx // test the 2 high bits. 9398016a12a5f9c2ea70b52e353a0169ba836ee9402Ian Rogers jne .Lslow_lock // slow path if either of the two high bits are set. 940e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi movl %ecx, %edx // save lock word (edx) to keep read barrier bits. 941e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi andl LITERAL(LOCK_WORD_READ_BARRIER_STATE_MASK_TOGGLED), %ecx // zero the read barrier bits. 942d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers test %ecx, %ecx 9438016a12a5f9c2ea70b52e353a0169ba836ee9402Ian Rogers jnz .Lalready_thin // lock word contains a thin lock 944e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi // unlocked case - edx: original lock word, eax: obj. 945d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers movl %eax, %ecx // remember object in case of retry 946e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi movl %edx, %eax // eax: lock word zero except for read barrier bits. 947e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi movl %fs:THREAD_ID_OFFSET, %edx // load thread id. 948e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi or %eax, %edx // edx: thread id with count of 0 + read barrier bits. 949e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi lock cmpxchg %edx, MIRROR_OBJECT_LOCK_WORD_OFFSET(%ecx) // eax: old val, edx: new val. 950e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi jnz .Llock_cmpxchg_fail // cmpxchg failed retry 951d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers ret 952e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi.Lalready_thin: // edx: lock word (with high 2 bits zero and original rb bits), eax: obj. 953e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi movl %fs:THREAD_ID_OFFSET, %ecx // ecx := thread id 9548ef84afbaeb433adaed98a11902502dd733e5222Serguei Katkov cmpw %cx, %dx // do we hold the lock already? 9558016a12a5f9c2ea70b52e353a0169ba836ee9402Ian Rogers jne .Lslow_lock 956e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi movl %edx, %ecx // copy the lock word to check count overflow. 957e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi andl LITERAL(LOCK_WORD_READ_BARRIER_STATE_MASK_TOGGLED), %ecx // zero the read barrier bits. 958e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi addl LITERAL(LOCK_WORD_THIN_LOCK_COUNT_ONE), %ecx // increment recursion count for overflow check. 959e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi test LITERAL(LOCK_WORD_READ_BARRIER_STATE_MASK), %ecx // overflowed if either of the upper two bits (28-29) are set. 9608016a12a5f9c2ea70b52e353a0169ba836ee9402Ian Rogers jne .Lslow_lock // count overflowed so go slow 961e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi movl %eax, %ecx // save obj to use eax for cmpxchg. 962e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi movl %edx, %eax // copy the lock word as the old val for cmpxchg. 963e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi addl LITERAL(LOCK_WORD_THIN_LOCK_COUNT_ONE), %edx // increment recursion count again for real. 964e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi // update lockword, cmpxchg necessary for read barrier bits. 965e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi lock cmpxchg %edx, MIRROR_OBJECT_LOCK_WORD_OFFSET(%ecx) // eax: old val, edx: new val. 966e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi jnz .Llock_cmpxchg_fail // cmpxchg failed retry 967d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers ret 968e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi.Llock_cmpxchg_fail: 969e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi movl %ecx, %eax // restore eax 970e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi jmp .Lretry_lock 9718016a12a5f9c2ea70b52e353a0169ba836ee9402Ian Rogers.Lslow_lock: 9721d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers SETUP_REFS_ONLY_CALLEE_SAVE_FRAME ebx, ebx // save ref containing registers for GC 973d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers // Outgoing argument set up 9744360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe subl LITERAL(8), %esp // alignment padding 9751d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers CFI_ADJUST_CFA_OFFSET(8) 9764360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() 9773f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(4) 9784360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH eax // pass object 9794360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe call SYMBOL(artLockObjectFromCode) // artLockObjectFromCode(object, Thread*) 9804360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe addl LITERAL(16), %esp // pop arguments 9813f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(-16) 9824360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address 983d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers RETURN_IF_EAX_ZERO 984d9c4fc94fa618617f94e1de9af5f034549100753Ian RogersEND_FUNCTION art_quick_lock_object 985d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 986fc6898769ae1ef91ec3e41c0a273401213cb82cdAndreas GampeDEFINE_FUNCTION art_quick_lock_object_no_inline 987fc6898769ae1ef91ec3e41c0a273401213cb82cdAndreas Gampe SETUP_REFS_ONLY_CALLEE_SAVE_FRAME ebx, ebx // save ref containing registers for GC 988fc6898769ae1ef91ec3e41c0a273401213cb82cdAndreas Gampe // Outgoing argument set up 989fc6898769ae1ef91ec3e41c0a273401213cb82cdAndreas Gampe subl LITERAL(8), %esp // alignment padding 990fc6898769ae1ef91ec3e41c0a273401213cb82cdAndreas Gampe CFI_ADJUST_CFA_OFFSET(8) 991fc6898769ae1ef91ec3e41c0a273401213cb82cdAndreas Gampe pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() 992fc6898769ae1ef91ec3e41c0a273401213cb82cdAndreas Gampe CFI_ADJUST_CFA_OFFSET(4) 993fc6898769ae1ef91ec3e41c0a273401213cb82cdAndreas Gampe PUSH eax // pass object 994fc6898769ae1ef91ec3e41c0a273401213cb82cdAndreas Gampe call SYMBOL(artLockObjectFromCode) // artLockObjectFromCode(object, Thread*) 995fc6898769ae1ef91ec3e41c0a273401213cb82cdAndreas Gampe addl LITERAL(16), %esp // pop arguments 996fc6898769ae1ef91ec3e41c0a273401213cb82cdAndreas Gampe CFI_ADJUST_CFA_OFFSET(-16) 997fc6898769ae1ef91ec3e41c0a273401213cb82cdAndreas Gampe RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address 998fc6898769ae1ef91ec3e41c0a273401213cb82cdAndreas Gampe RETURN_IF_EAX_ZERO 999fc6898769ae1ef91ec3e41c0a273401213cb82cdAndreas GampeEND_FUNCTION art_quick_lock_object_no_inline 1000fc6898769ae1ef91ec3e41c0a273401213cb82cdAndreas Gampe 1001fc6898769ae1ef91ec3e41c0a273401213cb82cdAndreas Gampe 1002d9c4fc94fa618617f94e1de9af5f034549100753Ian RogersDEFINE_FUNCTION art_quick_unlock_object 1003d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers testl %eax, %eax // null check object/eax 10048016a12a5f9c2ea70b52e353a0169ba836ee9402Ian Rogers jz .Lslow_unlock 1005e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi.Lretry_unlock: 10061d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers movl MIRROR_OBJECT_LOCK_WORD_OFFSET(%eax), %ecx // ecx := lock word 1007d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers movl %fs:THREAD_ID_OFFSET, %edx // edx := thread id 1008e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi test LITERAL(LOCK_WORD_STATE_MASK), %ecx 1009e78d4e1a7066d2bc60d265eb27e78b336df941ddSerguei Katkov jnz .Lslow_unlock // lock word contains a monitor 1010d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers cmpw %cx, %dx // does the thread id match? 10118016a12a5f9c2ea70b52e353a0169ba836ee9402Ian Rogers jne .Lslow_unlock 1012e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi movl %ecx, %edx // copy the lock word to detect new count of 0. 1013e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi andl LITERAL(LOCK_WORD_READ_BARRIER_STATE_MASK_TOGGLED), %edx // zero the read barrier bits. 1014e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi cmpl LITERAL(LOCK_WORD_THIN_LOCK_COUNT_ONE), %edx 10158016a12a5f9c2ea70b52e353a0169ba836ee9402Ian Rogers jae .Lrecursive_thin_unlock 1016e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi // update lockword, cmpxchg necessary for read barrier bits. 1017e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi movl %eax, %edx // edx: obj 1018e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi movl %ecx, %eax // eax: old lock word. 1019e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi andl LITERAL(LOCK_WORD_READ_BARRIER_STATE_MASK), %ecx // ecx: new lock word zero except original rb bits. 1020e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi#ifndef USE_READ_BARRIER 1021e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi movl %ecx, MIRROR_OBJECT_LOCK_WORD_OFFSET(%edx) 1022e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi#else 1023e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi lock cmpxchg %ecx, MIRROR_OBJECT_LOCK_WORD_OFFSET(%edx) // eax: old val, ecx: new val. 1024e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi jnz .Lunlock_cmpxchg_fail // cmpxchg failed retry 1025e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi#endif 1026d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers ret 1027e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi.Lrecursive_thin_unlock: // ecx: original lock word, eax: obj 1028e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi // update lockword, cmpxchg necessary for read barrier bits. 1029e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi movl %eax, %edx // edx: obj 1030e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi movl %ecx, %eax // eax: old lock word. 1031e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi subl LITERAL(LOCK_WORD_THIN_LOCK_COUNT_ONE), %ecx // ecx: new lock word with decremented count. 1032e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi#ifndef USE_READ_BARRIER 1033e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi mov %ecx, MIRROR_OBJECT_LOCK_WORD_OFFSET(%edx) 1034e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi#else 1035e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi lock cmpxchg %ecx, MIRROR_OBJECT_LOCK_WORD_OFFSET(%edx) // eax: old val, ecx: new val. 1036e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi jnz .Lunlock_cmpxchg_fail // cmpxchg failed retry 1037e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi#endif 1038d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers ret 1039e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi.Lunlock_cmpxchg_fail: // edx: obj 1040e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi movl %edx, %eax // restore eax 1041e15ea086439b41a805d164d2beb07b4ba96aaa97Hiroshi Yamauchi jmp .Lretry_unlock 10428016a12a5f9c2ea70b52e353a0169ba836ee9402Ian Rogers.Lslow_unlock: 10431d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers SETUP_REFS_ONLY_CALLEE_SAVE_FRAME ebx, ebx // save ref containing registers for GC 1044d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers // Outgoing argument set up 10454360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe subl LITERAL(8), %esp // alignment padding 10461d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers CFI_ADJUST_CFA_OFFSET(8) 10474360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() 10483f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(4) 10494360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH eax // pass object 10501d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers call SYMBOL(artUnlockObjectFromCode) // artUnlockObjectFromCode(object, Thread*) 10514360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe addl LITERAL(16), %esp // pop arguments 10523f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(-16) 10534360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address 1054d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers RETURN_IF_EAX_ZERO 1055d9c4fc94fa618617f94e1de9af5f034549100753Ian RogersEND_FUNCTION art_quick_unlock_object 1056d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers 1057fc6898769ae1ef91ec3e41c0a273401213cb82cdAndreas GampeDEFINE_FUNCTION art_quick_unlock_object_no_inline 1058fc6898769ae1ef91ec3e41c0a273401213cb82cdAndreas Gampe SETUP_REFS_ONLY_CALLEE_SAVE_FRAME ebx, ebx // save ref containing registers for GC 1059fc6898769ae1ef91ec3e41c0a273401213cb82cdAndreas Gampe // Outgoing argument set up 1060fc6898769ae1ef91ec3e41c0a273401213cb82cdAndreas Gampe subl LITERAL(8), %esp // alignment padding 1061fc6898769ae1ef91ec3e41c0a273401213cb82cdAndreas Gampe CFI_ADJUST_CFA_OFFSET(8) 1062fc6898769ae1ef91ec3e41c0a273401213cb82cdAndreas Gampe pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() 1063fc6898769ae1ef91ec3e41c0a273401213cb82cdAndreas Gampe CFI_ADJUST_CFA_OFFSET(4) 1064fc6898769ae1ef91ec3e41c0a273401213cb82cdAndreas Gampe PUSH eax // pass object 1065fc6898769ae1ef91ec3e41c0a273401213cb82cdAndreas Gampe call SYMBOL(artUnlockObjectFromCode) // artUnlockObjectFromCode(object, Thread*) 1066fc6898769ae1ef91ec3e41c0a273401213cb82cdAndreas Gampe addl LITERAL(16), %esp // pop arguments 1067fc6898769ae1ef91ec3e41c0a273401213cb82cdAndreas Gampe CFI_ADJUST_CFA_OFFSET(-16) 1068fc6898769ae1ef91ec3e41c0a273401213cb82cdAndreas Gampe RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address 1069fc6898769ae1ef91ec3e41c0a273401213cb82cdAndreas Gampe RETURN_IF_EAX_ZERO 1070fc6898769ae1ef91ec3e41c0a273401213cb82cdAndreas GampeEND_FUNCTION art_quick_unlock_object_no_inline 1071fc6898769ae1ef91ec3e41c0a273401213cb82cdAndreas Gampe 1072468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_is_assignable 10734360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH eax // alignment padding 10744360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH ecx // pass arg2 - obj->klass 10754360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH eax // pass arg1 - checked class 107629b3841ad8c1c18ee7ddd2d8cab85806b3d62eaaAndreas Gampe call SYMBOL(artIsAssignableFromCode) // (Class* klass, Class* ref_klass) 10774360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe addl LITERAL(12), %esp // pop arguments 10783f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(-12) 10797caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers ret 1080468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_is_assignable 10817caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers 1082a9a8254c920ce8e22210abfc16c9842ce0aea28fIan RogersDEFINE_FUNCTION art_quick_check_cast 10834360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH eax // alignment padding 10844360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH ecx // pass arg2 - obj->klass 10854360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH eax // pass arg1 - checked class 108629b3841ad8c1c18ee7ddd2d8cab85806b3d62eaaAndreas Gampe call SYMBOL(artIsAssignableFromCode) // (Class* klass, Class* ref_klass) 1087a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers testl %eax, %eax 10884360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe jz 1f // jump forward if not assignable 10894360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe addl LITERAL(12), %esp // pop arguments 10903f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(-12) 1091a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers ret 10926b90d42316e0370c789dddb5dda48d7403ea378fAndreas Gampe 10934360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe CFI_ADJUST_CFA_OFFSET(12) // Reset unwind info so following code unwinds. 1094a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers1: 10954360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe POP eax // pop arguments 1096a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers POP ecx 1097a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers addl LITERAL(4), %esp 10989f5e1d9b63ef44e05c2cc7b141ef788ecc0084c7Christopher Ferris CFI_ADJUST_CFA_OFFSET(-4) 10991d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers SETUP_SAVE_ALL_CALLEE_SAVE_FRAME ebx, ebx // save all registers as basis for long jump context 1100a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers // Outgoing argument set up 11014360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH eax // alignment padding 11024360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() 11033f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(4) 11044360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH ecx // pass arg2 11054360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH eax // pass arg1 11061d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers call SYMBOL(artThrowClassCastException) // (Class* a, Class* b, Thread*) 11074360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe UNREACHABLE 1108a9a8254c920ce8e22210abfc16c9842ce0aea28fIan RogersEND_FUNCTION art_quick_check_cast 1109a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers 11101aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao// Restore reg's value if reg is not the same as exclude_reg, otherwise just adjust stack. 11111aee900d5a0b3a8d78725a7551356bda0d8554e1Man CaoMACRO2(POP_REG_NE, reg, exclude_reg) 11121aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao .ifc RAW_VAR(reg), RAW_VAR(exclude_reg) 11131aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao addl MACRO_LITERAL(4), %esp 11141aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao CFI_ADJUST_CFA_OFFSET(-4) 11151aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao .else 11161aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao POP RAW_VAR(reg) 11171aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao .endif 11181aee900d5a0b3a8d78725a7551356bda0d8554e1Man CaoEND_MACRO 11191aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao 11201aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao /* 11211aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao * Macro to insert read barrier, only used in art_quick_aput_obj. 11221aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao * obj_reg and dest_reg are registers, offset is a defined literal such as 11231aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao * MIRROR_OBJECT_CLASS_OFFSET. 11241aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao * pop_eax is a boolean flag, indicating if eax is popped after the call. 11251aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao * TODO: When read barrier has a fast path, add heap unpoisoning support for the fast path. 11261aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao */ 11271aee900d5a0b3a8d78725a7551356bda0d8554e1Man CaoMACRO4(READ_BARRIER, obj_reg, offset, dest_reg, pop_eax) 11281aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao#ifdef USE_READ_BARRIER 11291aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao PUSH eax // save registers used in art_quick_aput_obj 11301aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao PUSH ebx 11311aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao PUSH edx 11321aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao PUSH ecx 11331aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao // Outgoing argument set up 11341aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao pushl MACRO_LITERAL((RAW_VAR(offset))) // pass offset, double parentheses are necessary 11351aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao CFI_ADJUST_CFA_OFFSET(4) 11361aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao PUSH RAW_VAR(obj_reg) // pass obj_reg 11371aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao PUSH eax // pass ref, just pass eax for now since parameter ref is unused 11381aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao call SYMBOL(artReadBarrierSlow) // artReadBarrierSlow(ref, obj_reg, offset) 11391aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao // No need to unpoison return value in eax, artReadBarrierSlow() would do the unpoisoning. 11401aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao .ifnc RAW_VAR(dest_reg), eax 11411aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao movl %eax, REG_VAR(dest_reg) // save loaded ref in dest_reg 11421aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao .endif 11431aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao addl MACRO_LITERAL(12), %esp // pop arguments 11441aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao CFI_ADJUST_CFA_OFFSET(-12) 11451aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao POP_REG_NE ecx, RAW_VAR(dest_reg) // Restore args except dest_reg 11461aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao POP_REG_NE edx, RAW_VAR(dest_reg) 11471aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao POP_REG_NE ebx, RAW_VAR(dest_reg) 11481aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao .ifc RAW_VAR(pop_eax), true 11491aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao POP_REG_NE eax, RAW_VAR(dest_reg) 11501aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao .endif 11511aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao#else 11521aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao movl RAW_VAR(offset)(REG_VAR(obj_reg)), REG_VAR(dest_reg) 11531aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao UNPOISON_HEAP_REF RAW_VAR(dest_reg) 11541aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao#endif // USE_READ_BARRIER 11551aee900d5a0b3a8d78725a7551356bda0d8554e1Man CaoEND_MACRO 11561aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao 1157a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers /* 1158a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers * Entry from managed code for array put operations of objects where the value being stored 1159a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers * needs to be checked for compatibility. 1160a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers * eax = array, ecx = index, edx = value 1161a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers */ 1162a9a8254c920ce8e22210abfc16c9842ce0aea28fIan RogersDEFINE_FUNCTION art_quick_aput_obj_with_null_and_bound_check 1163a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers testl %eax, %eax 11643bed41cf3ace3105686f626fed2ac802376852f3Dan Albert jnz SYMBOL(art_quick_aput_obj_with_bound_check) 11653bed41cf3ace3105686f626fed2ac802376852f3Dan Albert jmp SYMBOL(art_quick_throw_null_pointer_exception) 1166a9a8254c920ce8e22210abfc16c9842ce0aea28fIan RogersEND_FUNCTION art_quick_aput_obj_with_null_and_bound_check 1167a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers 1168a9a8254c920ce8e22210abfc16c9842ce0aea28fIan RogersDEFINE_FUNCTION art_quick_aput_obj_with_bound_check 11691d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers movl MIRROR_ARRAY_LENGTH_OFFSET(%eax), %ebx 1170a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers cmpl %ebx, %ecx 11713bed41cf3ace3105686f626fed2ac802376852f3Dan Albert jb SYMBOL(art_quick_aput_obj) 1172a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers mov %ecx, %eax 1173a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers mov %ebx, %ecx 11743bed41cf3ace3105686f626fed2ac802376852f3Dan Albert jmp SYMBOL(art_quick_throw_array_bounds) 1175a9a8254c920ce8e22210abfc16c9842ce0aea28fIan RogersEND_FUNCTION art_quick_aput_obj_with_bound_check 1176a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers 1177a9a8254c920ce8e22210abfc16c9842ce0aea28fIan RogersDEFINE_FUNCTION art_quick_aput_obj 1178a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers test %edx, %edx // store of null 11798016a12a5f9c2ea70b52e353a0169ba836ee9402Ian Rogers jz .Ldo_aput_null 11801aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao READ_BARRIER eax, MIRROR_OBJECT_CLASS_OFFSET, ebx, true 11811aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao READ_BARRIER ebx, MIRROR_CLASS_COMPONENT_TYPE_OFFSET, ebx, true 11821d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers // value's type == array's component type - trivial assignability 11831aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao#if defined(USE_READ_BARRIER) 11841aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao READ_BARRIER edx, MIRROR_OBJECT_CLASS_OFFSET, eax, false 11851aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao cmpl %eax, %ebx 11861aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao POP eax // restore eax from the push in the beginning of READ_BARRIER macro 11876306921722283d2b0f8aac01883ad83215d6e864Man Cao // This asymmetric push/pop saves a push of eax and maintains stack alignment. 11881aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao#elif defined(USE_HEAP_POISONING) 11891aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao PUSH eax // save eax 1190bfa5eb6e8d15ea73a36f8df449630f285a91e995Hiroshi Yamauchi movl MIRROR_OBJECT_CLASS_OFFSET(%edx), %eax 1191bfa5eb6e8d15ea73a36f8df449630f285a91e995Hiroshi Yamauchi UNPOISON_HEAP_REF eax 1192bfa5eb6e8d15ea73a36f8df449630f285a91e995Hiroshi Yamauchi cmpl %eax, %ebx 11931aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao POP eax // restore eax 1194bfa5eb6e8d15ea73a36f8df449630f285a91e995Hiroshi Yamauchi#else 11951d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers cmpl MIRROR_OBJECT_CLASS_OFFSET(%edx), %ebx 1196bfa5eb6e8d15ea73a36f8df449630f285a91e995Hiroshi Yamauchi#endif 11978016a12a5f9c2ea70b52e353a0169ba836ee9402Ian Rogers jne .Lcheck_assignability 11988016a12a5f9c2ea70b52e353a0169ba836ee9402Ian Rogers.Ldo_aput: 1199bfa5eb6e8d15ea73a36f8df449630f285a91e995Hiroshi Yamauchi POISON_HEAP_REF edx 12001d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers movl %edx, MIRROR_OBJECT_ARRAY_DATA_OFFSET(%eax, %ecx, 4) 1201a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers movl %fs:THREAD_CARD_TABLE_OFFSET, %edx 1202a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers shrl LITERAL(7), %eax 1203a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers movb %dl, (%edx, %eax) 1204a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers ret 12058016a12a5f9c2ea70b52e353a0169ba836ee9402Ian Rogers.Ldo_aput_null: 12061d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers movl %edx, MIRROR_OBJECT_ARRAY_DATA_OFFSET(%eax, %ecx, 4) 1207a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers ret 12088016a12a5f9c2ea70b52e353a0169ba836ee9402Ian Rogers.Lcheck_assignability: 12094360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH eax // save arguments 1210a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers PUSH ecx 1211a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers PUSH edx 12126306921722283d2b0f8aac01883ad83215d6e864Man Cao#if defined(USE_READ_BARRIER) 12136306921722283d2b0f8aac01883ad83215d6e864Man Cao subl LITERAL(4), %esp // alignment padding 12146306921722283d2b0f8aac01883ad83215d6e864Man Cao CFI_ADJUST_CFA_OFFSET(4) 12156306921722283d2b0f8aac01883ad83215d6e864Man Cao READ_BARRIER edx, MIRROR_OBJECT_CLASS_OFFSET, eax, true 12166306921722283d2b0f8aac01883ad83215d6e864Man Cao subl LITERAL(4), %esp // alignment padding 12176306921722283d2b0f8aac01883ad83215d6e864Man Cao CFI_ADJUST_CFA_OFFSET(4) 12186306921722283d2b0f8aac01883ad83215d6e864Man Cao PUSH eax // pass arg2 - type of the value to be stored 12196306921722283d2b0f8aac01883ad83215d6e864Man Cao#elif defined(USE_HEAP_POISONING) 12204360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe subl LITERAL(8), %esp // alignment padding 12213f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(8) 12226306921722283d2b0f8aac01883ad83215d6e864Man Cao movl MIRROR_OBJECT_CLASS_OFFSET(%edx), %eax 1223bfa5eb6e8d15ea73a36f8df449630f285a91e995Hiroshi Yamauchi UNPOISON_HEAP_REF eax 12246306921722283d2b0f8aac01883ad83215d6e864Man Cao PUSH eax // pass arg2 - type of the value to be stored 1225bfa5eb6e8d15ea73a36f8df449630f285a91e995Hiroshi Yamauchi#else 12266306921722283d2b0f8aac01883ad83215d6e864Man Cao subl LITERAL(8), %esp // alignment padding 12276306921722283d2b0f8aac01883ad83215d6e864Man Cao CFI_ADJUST_CFA_OFFSET(8) 12281d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers pushl MIRROR_OBJECT_CLASS_OFFSET(%edx) // pass arg2 - type of the value to be stored 12293f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(4) 12309f5e1d9b63ef44e05c2cc7b141ef788ecc0084c7Christopher Ferris#endif 12312738639bcd30b908d825725169b7497ed047debbMathieu Chartier PUSH ebx // pass arg1 - component type of the array 123229b3841ad8c1c18ee7ddd2d8cab85806b3d62eaaAndreas Gampe call SYMBOL(artIsAssignableFromCode) // (Class* a, Class* b) 12332738639bcd30b908d825725169b7497ed047debbMathieu Chartier addl LITERAL(16), %esp // pop arguments 12343f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(-16) 1235a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers testl %eax, %eax 12368016a12a5f9c2ea70b52e353a0169ba836ee9402Ian Rogers jz .Lthrow_array_store_exception 1237a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers POP edx 1238a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers POP ecx 1239a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers POP eax 1240bfa5eb6e8d15ea73a36f8df449630f285a91e995Hiroshi Yamauchi POISON_HEAP_REF edx 12411d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers movl %edx, MIRROR_OBJECT_ARRAY_DATA_OFFSET(%eax, %ecx, 4) // do the aput 1242a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers movl %fs:THREAD_CARD_TABLE_OFFSET, %edx 1243a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers shrl LITERAL(7), %eax 1244a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers movb %dl, (%edx, %eax) 1245a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers ret 12462738639bcd30b908d825725169b7497ed047debbMathieu Chartier CFI_ADJUST_CFA_OFFSET(12) // 3 POP after the jz for unwinding. 12478016a12a5f9c2ea70b52e353a0169ba836ee9402Ian Rogers.Lthrow_array_store_exception: 1248a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers POP edx 1249a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers POP ecx 1250a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers POP eax 12511d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers SETUP_SAVE_ALL_CALLEE_SAVE_FRAME ebx, ebx // save all registers as basis for long jump context 1252a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers // Outgoing argument set up 12531d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers PUSH eax // alignment padding 1254a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() 12553f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(4) 1256a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers PUSH edx // pass arg2 - value 1257a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers PUSH eax // pass arg1 - array 12581d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers call SYMBOL(artThrowArrayStoreException) // (array, value, Thread*) 12594360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe UNREACHABLE 1260a9a8254c920ce8e22210abfc16c9842ce0aea28fIan RogersEND_FUNCTION art_quick_aput_obj 1261a9a8254c920ce8e22210abfc16c9842ce0aea28fIan Rogers 12628dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienDEFINE_FUNCTION art_quick_memcpy 12631d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers SETUP_GOT_NOSAVE ebx // clobbers EBX 1264aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers PUSH edx // pass arg3 1265aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers PUSH ecx // pass arg2 1266aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers PUSH eax // pass arg1 12673f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell call PLT_SYMBOL(memcpy) // (void*, const void*, size_t) 126855bd45f4ea40b9a0af323f813d07f23d7a8ed397Ian Rogers addl LITERAL(12), %esp // pop arguments 12693f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(-12) 12707caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers ret 1271aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian RogersEND_FUNCTION art_quick_memcpy 12727caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers 12738dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienNO_ARG_DOWNCALL art_quick_test_suspend, artTestSuspendFromCode, ret 12747caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers 1275468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_d2l 1276966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell subl LITERAL(12), %esp // alignment padding, room for argument 1277966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell CFI_ADJUST_CFA_OFFSET(12) 1278966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movsd %xmm0, 0(%esp) // arg a 1279966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell call SYMBOL(art_d2l) // (jdouble a) 128041005ddb5576b8630a1084fbb3979ffa602c0599jeffhao addl LITERAL(12), %esp // pop arguments 12813f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(-12) 128241005ddb5576b8630a1084fbb3979ffa602c0599jeffhao ret 1283468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_d2l 128441005ddb5576b8630a1084fbb3979ffa602c0599jeffhao 1285468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_f2l 1286966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell subl LITERAL(12), %esp // alignment padding 1287966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell CFI_ADJUST_CFA_OFFSET(12) 1288966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movss %xmm0, 0(%esp) // arg a 1289966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell call SYMBOL(art_f2l) // (jfloat a) 129041005ddb5576b8630a1084fbb3979ffa602c0599jeffhao addl LITERAL(12), %esp // pop arguments 12913f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(-12) 129241005ddb5576b8630a1084fbb3979ffa602c0599jeffhao ret 1293468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_f2l 129441005ddb5576b8630a1084fbb3979ffa602c0599jeffhao 1295468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_ldiv 12964360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe subl LITERAL(12), %esp // alignment padding 12973f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(12) 12984360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH ebx // pass arg4 b.hi 12994360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH edx // pass arg3 b.lo 13004360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH ecx // pass arg2 a.hi 13014360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH eax // pass arg1 a.lo 13024360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe call SYMBOL(artLdiv) // (jlong a, jlong b) 13034360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe addl LITERAL(28), %esp // pop arguments 13043f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(-28) 130555bd45f4ea40b9a0af323f813d07f23d7a8ed397Ian Rogers ret 1306468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_ldiv 130755bd45f4ea40b9a0af323f813d07f23d7a8ed397Ian Rogers 1308a9a8254c920ce8e22210abfc16c9842ce0aea28fIan RogersDEFINE_FUNCTION art_quick_lmod 13094360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe subl LITERAL(12), %esp // alignment padding 13103f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(12) 13114360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH ebx // pass arg4 b.hi 13124360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH edx // pass arg3 b.lo 13134360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH ecx // pass arg2 a.hi 13144360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH eax // pass arg1 a.lo 13154360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe call SYMBOL(artLmod) // (jlong a, jlong b) 13164360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe addl LITERAL(28), %esp // pop arguments 13173f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(-28) 131855bd45f4ea40b9a0af323f813d07f23d7a8ed397Ian Rogers ret 1319a9a8254c920ce8e22210abfc16c9842ce0aea28fIan RogersEND_FUNCTION art_quick_lmod 132055bd45f4ea40b9a0af323f813d07f23d7a8ed397Ian Rogers 1321468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_lmul 13224360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe imul %eax, %ebx // ebx = a.lo(eax) * b.hi(ebx) 13234360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe imul %edx, %ecx // ecx = b.lo(edx) * a.hi(ecx) 13244360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe mul %edx // edx:eax = a.lo(eax) * b.lo(edx) 13255793feaaafef40625b010429f3f79d8ee0bdfe28Ian Rogers add %ebx, %ecx 13264360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe add %ecx, %edx // edx += (a.lo * b.hi) + (b.lo * a.hi) 1327644d5310d7759f6d531a2c4220b1e2cc8f3b72d3jeffhao ret 1328468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_lmul 1329644d5310d7759f6d531a2c4220b1e2cc8f3b72d3jeffhao 1330468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_lshl 1331644d5310d7759f6d531a2c4220b1e2cc8f3b72d3jeffhao // ecx:eax << edx 1332141d62275f207bf68c55f583fb206fe586d857cfIan Rogers xchg %edx, %ecx 1333141d62275f207bf68c55f583fb206fe586d857cfIan Rogers shld %cl,%eax,%edx 1334141d62275f207bf68c55f583fb206fe586d857cfIan Rogers shl %cl,%eax 1335141d62275f207bf68c55f583fb206fe586d857cfIan Rogers test LITERAL(32), %cl 1336141d62275f207bf68c55f583fb206fe586d857cfIan Rogers jz 1f 1337141d62275f207bf68c55f583fb206fe586d857cfIan Rogers mov %eax, %edx 1338141d62275f207bf68c55f583fb206fe586d857cfIan Rogers xor %eax, %eax 1339141d62275f207bf68c55f583fb206fe586d857cfIan Rogers1: 1340141d62275f207bf68c55f583fb206fe586d857cfIan Rogers ret 1341468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_lshl 1342141d62275f207bf68c55f583fb206fe586d857cfIan Rogers 1343468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_lshr 1344644d5310d7759f6d531a2c4220b1e2cc8f3b72d3jeffhao // ecx:eax >> edx 1345141d62275f207bf68c55f583fb206fe586d857cfIan Rogers xchg %edx, %ecx 1346644d5310d7759f6d531a2c4220b1e2cc8f3b72d3jeffhao shrd %cl,%edx,%eax 1347644d5310d7759f6d531a2c4220b1e2cc8f3b72d3jeffhao sar %cl,%edx 1348141d62275f207bf68c55f583fb206fe586d857cfIan Rogers test LITERAL(32),%cl 1349141d62275f207bf68c55f583fb206fe586d857cfIan Rogers jz 1f 13505121e0b9699c8cd5e89ee323e30074b984b7b436jeffhao mov %edx, %eax 13515121e0b9699c8cd5e89ee323e30074b984b7b436jeffhao sar LITERAL(31), %edx 1352141d62275f207bf68c55f583fb206fe586d857cfIan Rogers1: 1353141d62275f207bf68c55f583fb206fe586d857cfIan Rogers ret 1354468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_lshr 1355141d62275f207bf68c55f583fb206fe586d857cfIan Rogers 1356468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_lushr 1357644d5310d7759f6d531a2c4220b1e2cc8f3b72d3jeffhao // ecx:eax >>> edx 1358141d62275f207bf68c55f583fb206fe586d857cfIan Rogers xchg %edx, %ecx 1359644d5310d7759f6d531a2c4220b1e2cc8f3b72d3jeffhao shrd %cl,%edx,%eax 1360644d5310d7759f6d531a2c4220b1e2cc8f3b72d3jeffhao shr %cl,%edx 1361644d5310d7759f6d531a2c4220b1e2cc8f3b72d3jeffhao test LITERAL(32),%cl 1362141d62275f207bf68c55f583fb206fe586d857cfIan Rogers jz 1f 13635121e0b9699c8cd5e89ee323e30074b984b7b436jeffhao mov %edx, %eax 13645121e0b9699c8cd5e89ee323e30074b984b7b436jeffhao xor %edx, %edx 1365141d62275f207bf68c55f583fb206fe586d857cfIan Rogers1: 1366141d62275f207bf68c55f583fb206fe586d857cfIan Rogers ret 1367468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_lushr 1368141d62275f207bf68c55f583fb206fe586d857cfIan Rogers 13691d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersONE_ARG_REF_DOWNCALL art_quick_get_boolean_static, artGetBooleanStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION 13701d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersONE_ARG_REF_DOWNCALL art_quick_get_byte_static, artGetByteStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION 13711d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersONE_ARG_REF_DOWNCALL art_quick_get_char_static, artGetCharStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION 13721d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersONE_ARG_REF_DOWNCALL art_quick_get_short_static, artGetShortStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION 13731d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersONE_ARG_REF_DOWNCALL art_quick_get32_static, artGet32StaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION 13741d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersONE_ARG_REF_DOWNCALL art_quick_get64_static, artGet64StaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION 13751d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersONE_ARG_REF_DOWNCALL art_quick_get_obj_static, artGetObjStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION 137637f05ef45e0393de812d51261dc293240c17294dFred Shih 13771d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersTWO_ARG_REF_DOWNCALL art_quick_get_boolean_instance, artGetBooleanInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION 13781d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersTWO_ARG_REF_DOWNCALL art_quick_get_byte_instance, artGetByteInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION 13791d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersTWO_ARG_REF_DOWNCALL art_quick_get_char_instance, artGetCharInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION 13801d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersTWO_ARG_REF_DOWNCALL art_quick_get_short_instance, artGetShortInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION 13811d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersTWO_ARG_REF_DOWNCALL art_quick_get32_instance, artGet32InstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION 13821d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersTWO_ARG_REF_DOWNCALL art_quick_get64_instance, artGet64InstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION 13831d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersTWO_ARG_REF_DOWNCALL art_quick_get_obj_instance, artGetObjInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION 138437f05ef45e0393de812d51261dc293240c17294dFred Shih 13851d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersTWO_ARG_REF_DOWNCALL art_quick_set8_static, artSet8StaticFromCode, RETURN_IF_EAX_ZERO 13861d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersTWO_ARG_REF_DOWNCALL art_quick_set16_static, artSet16StaticFromCode, RETURN_IF_EAX_ZERO 13871d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersTWO_ARG_REF_DOWNCALL art_quick_set32_static, artSet32StaticFromCode, RETURN_IF_EAX_ZERO 13881d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersTWO_ARG_REF_DOWNCALL art_quick_set_obj_static, artSetObjStaticFromCode, RETURN_IF_EAX_ZERO 13899dbb23e997f84d7c6c909b246e3faca50a912336jeffhao 13901d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersTHREE_ARG_REF_DOWNCALL art_quick_set8_instance, artSet8InstanceFromCode, RETURN_IF_EAX_ZERO 13911d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersTHREE_ARG_REF_DOWNCALL art_quick_set16_instance, artSet16InstanceFromCode, RETURN_IF_EAX_ZERO 13921d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersTHREE_ARG_REF_DOWNCALL art_quick_set32_instance, artSet32InstanceFromCode, RETURN_IF_EAX_ZERO 13931d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersTHREE_ARG_REF_DOWNCALL art_quick_set_obj_instance, artSetObjInstanceFromCode, RETURN_IF_EAX_ZERO 13941d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers 13951d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers// Call artSet64InstanceFromCode with 4 word size arguments and the referrer. 1396468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_set64_instance 1397e0b46a7513980b5bcb3c3af160a5b3ee077fad2dSerguei Katkov movd %ebx, %xmm0 13981d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers SETUP_REFS_ONLY_CALLEE_SAVE_FRAME ebx, ebx // save ref containing registers for GC 1399e0b46a7513980b5bcb3c3af160a5b3ee077fad2dSerguei Katkov movd %xmm0, %ebx 14001d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers // Outgoing argument set up 14011ff4cd7c1ec698845145edd1e9d0ba767ce45de1jeffhao subl LITERAL(8), %esp // alignment padding 14023f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(8) 14039dbb23e997f84d7c6c909b246e3faca50a912336jeffhao pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() 14043f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(4) 14051d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers pushl (FRAME_SIZE_REFS_ONLY_CALLEE_SAVE+12)(%esp) // pass referrer 14061d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers CFI_ADJUST_CFA_OFFSET(4) 1407aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers PUSH ebx // pass high half of new_val 1408aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers PUSH edx // pass low half of new_val 1409aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers PUSH ecx // pass object 1410aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers PUSH eax // pass field_idx 14111d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers call SYMBOL(artSet64InstanceFromCode) // (field_idx, Object*, new_val, referrer, Thread*) 14121ff4cd7c1ec698845145edd1e9d0ba767ce45de1jeffhao addl LITERAL(32), %esp // pop arguments 14133f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(-32) 14141d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address 14159dbb23e997f84d7c6c909b246e3faca50a912336jeffhao RETURN_IF_EAX_ZERO // return or deliver exception 1416468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_set64_instance 14179dbb23e997f84d7c6c909b246e3faca50a912336jeffhao 14181d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers// Call artSet64StaticFromCode with 3 word size arguments plus with the referrer in the 2nd position 14191d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers// so that new_val is aligned on even registers were we passing arguments in registers. 14201d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian RogersDEFINE_FUNCTION art_quick_set64_static 1421e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle // TODO: Implement SETUP_GOT_NOSAVE for got_reg = ecx to avoid moving around the registers. 1422e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle movd %ebx, %xmm0 14231d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers SETUP_REFS_ONLY_CALLEE_SAVE_FRAME ebx, ebx // save ref containing registers for GC 1424e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle movd %xmm0, %ebx 1425e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle mov FRAME_SIZE_REFS_ONLY_CALLEE_SAVE(%esp), %ecx // get referrer 14261ff4cd7c1ec698845145edd1e9d0ba767ce45de1jeffhao subl LITERAL(12), %esp // alignment padding 14273f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(12) 14289dbb23e997f84d7c6c909b246e3faca50a912336jeffhao pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() 14293f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(4) 1430e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle PUSH ebx // pass high half of new_val 1431e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle PUSH edx // pass low half of new_val 1432e460d1df1f789c7c8bb97024a8efbd713ac175e9Calin Juravle PUSH ecx // pass referrer 1433aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers PUSH eax // pass field_idx 14341d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers call SYMBOL(artSet64StaticFromCode) // (field_idx, referrer, new_val, Thread*) 14351ff4cd7c1ec698845145edd1e9d0ba767ce45de1jeffhao addl LITERAL(32), %esp // pop arguments 14363f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(-32) 14371d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address 14389dbb23e997f84d7c6c909b246e3faca50a912336jeffhao RETURN_IF_EAX_ZERO // return or deliver exception 1439468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_set64_static 14409dbb23e997f84d7c6c909b246e3faca50a912336jeffhao 14418dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienDEFINE_FUNCTION art_quick_proxy_invoke_handler 14421d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME_WITH_METHOD_IN_EAX 1443aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers PUSH esp // pass SP 1444d66a87583bebcd5f89906aeaae9f8fb104ef2ac9jeffhao pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() 14453f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(4) 1446aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers PUSH ecx // pass receiver 1447aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers PUSH eax // pass proxy method 144829b3841ad8c1c18ee7ddd2d8cab85806b3d62eaaAndreas Gampe call SYMBOL(artQuickProxyInvokeHandler) // (proxy method, receiver, Thread*, SP) 1449af6e67a4816d2593586115b89faa659225363246Ian Rogers movd %eax, %xmm0 // place return value also into floating point return value 1450af6e67a4816d2593586115b89faa659225363246Ian Rogers movd %edx, %xmm1 1451af6e67a4816d2593586115b89faa659225363246Ian Rogers punpckldq %xmm1, %xmm0 14529346ff0cfad6344d0bf4eaa69362dbe1987ac054Mathieu Chartier addl LITERAL(16 + FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE - FRAME_SIZE_REFS_ONLY_CALLEE_SAVE), %esp 14539346ff0cfad6344d0bf4eaa69362dbe1987ac054Mathieu Chartier CFI_ADJUST_CFA_OFFSET(-(16 + FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE - FRAME_SIZE_REFS_ONLY_CALLEE_SAVE)) 14549346ff0cfad6344d0bf4eaa69362dbe1987ac054Mathieu Chartier RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME 14557db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception 1456aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian RogersEND_FUNCTION art_quick_proxy_invoke_handler 14577db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers 145888474b416eb257078e590bf9bc7957cee604a186Jeff Hao /* 1459796d63050a18f263b93ea34951a61deaecab3422Nicolas Geoffray * Called to resolve an imt conflict. 1460796d63050a18f263b93ea34951a61deaecab3422Nicolas Geoffray * eax is the conflict ArtMethod. 1461796d63050a18f263b93ea34951a61deaecab3422Nicolas Geoffray * xmm7 is a hidden argument that holds the target interface method's dex method index. 1462796d63050a18f263b93ea34951a61deaecab3422Nicolas Geoffray * 1463796d63050a18f263b93ea34951a61deaecab3422Nicolas Geoffray * Note that this stub writes to eax. 1464796d63050a18f263b93ea34951a61deaecab3422Nicolas Geoffray * Because of lack of free registers, it also saves and restores edi. 146588474b416eb257078e590bf9bc7957cee604a186Jeff Hao */ 146688474b416eb257078e590bf9bc7957cee604a186Jeff HaoDEFINE_FUNCTION art_quick_imt_conflict_trampoline 1467796d63050a18f263b93ea34951a61deaecab3422Nicolas Geoffray PUSH EDI 1468796d63050a18f263b93ea34951a61deaecab3422Nicolas Geoffray movl 8(%esp), %edi // Load referrer 1469796d63050a18f263b93ea34951a61deaecab3422Nicolas Geoffray movl ART_METHOD_DEX_CACHE_METHODS_OFFSET_32(%edi), %edi // Load dex cache methods array 1470796d63050a18f263b93ea34951a61deaecab3422Nicolas Geoffray pushl ART_METHOD_JNI_OFFSET_32(%eax) // Push ImtConflictTable. 1471796d63050a18f263b93ea34951a61deaecab3422Nicolas Geoffray CFI_ADJUST_CFA_OFFSET(4) 14728ea18d0f066f63fa4e5d154f14327468bf288e2bNicolas Geoffray movd %xmm7, %eax // get target method index stored in xmm7 1473796d63050a18f263b93ea34951a61deaecab3422Nicolas Geoffray movl 0(%edi, %eax, __SIZEOF_POINTER__), %edi // Load interface method 1474796d63050a18f263b93ea34951a61deaecab3422Nicolas Geoffray popl %eax // Pop ImtConflictTable. 1475796d63050a18f263b93ea34951a61deaecab3422Nicolas Geoffray CFI_ADJUST_CFA_OFFSET(-4) 1476796d63050a18f263b93ea34951a61deaecab3422Nicolas Geoffray.Limt_table_iterate: 1477796d63050a18f263b93ea34951a61deaecab3422Nicolas Geoffray cmpl %edi, 0(%eax) 1478796d63050a18f263b93ea34951a61deaecab3422Nicolas Geoffray jne .Limt_table_next_entry 147959028d90d51a800bcea8be354d77d7be924da3a0Goran Jakovljevic // We successfully hit an entry in the table. Load the target method 1480796d63050a18f263b93ea34951a61deaecab3422Nicolas Geoffray // and jump to it. 1481796d63050a18f263b93ea34951a61deaecab3422Nicolas Geoffray POP EDI 1482796d63050a18f263b93ea34951a61deaecab3422Nicolas Geoffray movl __SIZEOF_POINTER__(%eax), %eax 1483796d63050a18f263b93ea34951a61deaecab3422Nicolas Geoffray jmp *ART_METHOD_QUICK_CODE_OFFSET_32(%eax) 1484796d63050a18f263b93ea34951a61deaecab3422Nicolas Geoffray.Limt_table_next_entry: 1485796d63050a18f263b93ea34951a61deaecab3422Nicolas Geoffray // If the entry is null, the interface method is not in the ImtConflictTable. 1486796d63050a18f263b93ea34951a61deaecab3422Nicolas Geoffray cmpl LITERAL(0), 0(%eax) 1487796d63050a18f263b93ea34951a61deaecab3422Nicolas Geoffray jz .Lconflict_trampoline 1488796d63050a18f263b93ea34951a61deaecab3422Nicolas Geoffray // Iterate over the entries of the ImtConflictTable. 1489796d63050a18f263b93ea34951a61deaecab3422Nicolas Geoffray addl LITERAL(2 * __SIZEOF_POINTER__), %eax 1490796d63050a18f263b93ea34951a61deaecab3422Nicolas Geoffray jmp .Limt_table_iterate 1491796d63050a18f263b93ea34951a61deaecab3422Nicolas Geoffray.Lconflict_trampoline: 1492796d63050a18f263b93ea34951a61deaecab3422Nicolas Geoffray // Call the runtime stub to populate the ImtConflictTable and jump to the 1493796d63050a18f263b93ea34951a61deaecab3422Nicolas Geoffray // resolved method. 1494796d63050a18f263b93ea34951a61deaecab3422Nicolas Geoffray POP EDI 149555978b87877f4774af213b405c9492dc08549912Andreas Gampe INVOKE_TRAMPOLINE_BODY artInvokeInterfaceTrampoline 149688474b416eb257078e590bf9bc7957cee604a186Jeff HaoEND_FUNCTION art_quick_imt_conflict_trampoline 149788474b416eb257078e590bf9bc7957cee604a186Jeff Hao 1498468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_resolution_trampoline 14991d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME ebx, ebx 150035e1e6ad4b50f1adbe9f93fe467766f042491896Tong Shen movl %esp, %edi 150135e1e6ad4b50f1adbe9f93fe467766f042491896Tong Shen PUSH EDI // pass SP. do not just PUSH ESP; that messes up unwinding 1502468532ea115657709bc32ee498e701a4c71762d4Ian Rogers pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() 15033f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(4) 1504468532ea115657709bc32ee498e701a4c71762d4Ian Rogers PUSH ecx // pass receiver 1505468532ea115657709bc32ee498e701a4c71762d4Ian Rogers PUSH eax // pass method 150629b3841ad8c1c18ee7ddd2d8cab85806b3d62eaaAndreas Gampe call SYMBOL(artQuickResolutionTrampoline) // (Method* called, receiver, Thread*, SP) 1507468532ea115657709bc32ee498e701a4c71762d4Ian Rogers movl %eax, %edi // remember code pointer in EDI 1508468532ea115657709bc32ee498e701a4c71762d4Ian Rogers addl LITERAL(16), %esp // pop arguments 15099f5e1d9b63ef44e05c2cc7b141ef788ecc0084c7Christopher Ferris CFI_ADJUST_CFA_OFFSET(-16) 15102cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier test %eax, %eax // if code pointer is null goto deliver pending exception 1511468532ea115657709bc32ee498e701a4c71762d4Ian Rogers jz 1f 1512966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell RESTORE_REFS_AND_ARGS_CALLEE_SAVE_FRAME_AND_JUMP 1513468532ea115657709bc32ee498e701a4c71762d4Ian Rogers1: 15141d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers RESTORE_REFS_AND_ARGS_CALLEE_SAVE_FRAME 1515468532ea115657709bc32ee498e701a4c71762d4Ian Rogers DELIVER_PENDING_EXCEPTION 1516468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_resolution_trampoline 1517468532ea115657709bc32ee498e701a4c71762d4Ian Rogers 15186f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian RogersDEFINE_FUNCTION art_quick_generic_jni_trampoline 15191d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME_WITH_METHOD_IN_EAX 15204360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe movl %esp, %ebp // save SP at callee-save frame 1521c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe CFI_DEF_CFA_REGISTER(ebp) 1522779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe subl LITERAL(5120), %esp 1523779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe // prepare for artQuickGenericJniTrampoline call 1524779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe // (Thread*, SP) 1525779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe // (esp) 4(esp) <= C calling convention 1526779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe // fs:... ebp <= where they are 1527779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe 1528779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe subl LITERAL(8), %esp // Padding for 16B alignment. 1529779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe pushl %ebp // Pass SP (to ArtMethod). 1530779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe pushl %fs:THREAD_SELF_OFFSET // Pass Thread::Current(). 153129b3841ad8c1c18ee7ddd2d8cab85806b3d62eaaAndreas Gampe call SYMBOL(artQuickGenericJniTrampoline) // (Thread*, sp) 1532779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe 1533c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe // The C call will have registered the complete save-frame on success. 1534c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe // The result of the call is: 1535c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe // eax: pointer to native code, 0 on error. 1536c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe // edx: pointer to the bottom of the used area of the alloca, can restore stack till there. 1537779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe 1538c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe // Check for error = 0. 1539779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe test %eax, %eax 1540126d65952a03b3e44d5021208673c01920a982a4Nicolas Geoffray jz .Lexception_in_native 1541779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe 1542c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe // Release part of the alloca. 1543c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe movl %edx, %esp 1544779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe 1545779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe // On x86 there are no registers passed, so nothing to pop here. 1546779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe // Native call. 1547779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe call *%eax 1548779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe 1549779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe // result sign extension is handled in C code 1550779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe // prepare for artQuickGenericJniEndTrampoline call 1551c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe // (Thread*, result, result_f) 1552c200a4abeca91e19969f5b35543f17f812ba32b9Andreas Gampe // (esp) 4(esp) 12(esp) <= C calling convention 155354accbca0b549b1b1ad3ef09655dad438bc1e104Nicolas Geoffray // fs:... eax:edx fp0 <= where they are 1554779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe 15554360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe subl LITERAL(20), %esp // Padding & pass float result. 155654accbca0b549b1b1ad3ef09655dad438bc1e104Nicolas Geoffray fstpl (%esp) 1557779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe pushl %edx // Pass int result. 1558779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe pushl %eax 1559779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe pushl %fs:THREAD_SELF_OFFSET // Pass Thread::Current(). 156029b3841ad8c1c18ee7ddd2d8cab85806b3d62eaaAndreas Gampe call SYMBOL(artQuickGenericJniEndTrampoline) 1561779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe 1562779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe // Pending exceptions possible. 1563779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe mov %fs:THREAD_EXCEPTION_OFFSET, %ebx 1564779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe testl %ebx, %ebx 1565779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe jnz .Lexception_in_native 1566779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe 1567126d65952a03b3e44d5021208673c01920a982a4Nicolas Geoffray // Tear down the alloca. 1568126d65952a03b3e44d5021208673c01920a982a4Nicolas Geoffray movl %ebp, %esp 1569126d65952a03b3e44d5021208673c01920a982a4Nicolas Geoffray CFI_DEF_CFA_REGISTER(esp) 1570126d65952a03b3e44d5021208673c01920a982a4Nicolas Geoffray 1571126d65952a03b3e44d5021208673c01920a982a4Nicolas Geoffray 1572779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe // Tear down the callee-save frame. 1573966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Remove space for FPR args and EAX 1574966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell addl LITERAL(4 + 4 * 8), %esp 1575966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell CFI_ADJUST_CFA_OFFSET(-(4 + 4 * 8)) 1576966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 1577779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe POP ecx 15784360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe addl LITERAL(4), %esp // Avoid edx, as it may be part of the result. 1579779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe CFI_ADJUST_CFA_OFFSET(-4) 1580779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe POP ebx 1581779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe POP ebp // Restore callee saves 1582779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe POP esi 1583779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe POP edi 158454accbca0b549b1b1ad3ef09655dad438bc1e104Nicolas Geoffray // Quick expects the return value to be in xmm0. 1585779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe movd %eax, %xmm0 1586779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe movd %edx, %xmm1 1587779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe punpckldq %xmm1, %xmm0 1588779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe ret 1589779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe.Lexception_in_native: 1590126d65952a03b3e44d5021208673c01920a982a4Nicolas Geoffray movl %fs:THREAD_TOP_QUICK_FRAME_OFFSET, %esp 1591126d65952a03b3e44d5021208673c01920a982a4Nicolas Geoffray // Do a call to push a new save-all frame required by the runtime. 1592126d65952a03b3e44d5021208673c01920a982a4Nicolas Geoffray call .Lexception_call 1593126d65952a03b3e44d5021208673c01920a982a4Nicolas Geoffray.Lexception_call: 1594779f8c951c0fbe36d4b213113a99541132947bb7Andreas Gampe DELIVER_PENDING_EXCEPTION 15952da882315a61072664f7ce3c212307342e907207Andreas GampeEND_FUNCTION art_quick_generic_jni_trampoline 15962da882315a61072664f7ce3c212307342e907207Andreas Gampe 15976f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian RogersDEFINE_FUNCTION art_quick_to_interpreter_bridge 15981d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME ebx, ebx // save frame 1599aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers mov %esp, %edx // remember SP 1600aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers PUSH eax // alignment padding 1601aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers PUSH edx // pass SP 16027db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() 16033f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(4) 1604aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers PUSH eax // pass method 160529b3841ad8c1c18ee7ddd2d8cab85806b3d62eaaAndreas Gampe call SYMBOL(artQuickToInterpreterBridge) // (method, Thread*, SP) 1606949c91fb91f40a4a80b2b492913cf8541008975eVladimir Marko addl LITERAL(16), %esp // pop arguments 1607949c91fb91f40a4a80b2b492913cf8541008975eVladimir Marko CFI_ADJUST_CFA_OFFSET(-16) 1608966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 1609966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Return eax:edx in xmm0 also. 1610966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movd %eax, %xmm0 1611966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movd %edx, %xmm1 1612966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell punpckldq %xmm1, %xmm0 1613966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 1614966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell addl LITERAL(48), %esp // Remove FPRs and EAX, ECX, EDX, EBX. 1615966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell CFI_ADJUST_CFA_OFFSET(-48) 1616966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 16174360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe POP ebp // Restore callee saves 1618966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell POP esi 1619966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell POP edi 1620966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 1621d66a87583bebcd5f89906aeaae9f8fb104ef2ac9jeffhao RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception 1622468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_to_interpreter_bridge 16239dbb23e997f84d7c6c909b246e3faca50a912336jeffhao 16247e4fcb813d6c2657a5b9190a7c10168a2680bc45jeffhao /* 16257e4fcb813d6c2657a5b9190a7c10168a2680bc45jeffhao * Routine that intercepts method calls and returns. 16267e4fcb813d6c2657a5b9190a7c10168a2680bc45jeffhao */ 1627468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_instrumentation_entry 16281d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers SETUP_REFS_AND_ARGS_CALLEE_SAVE_FRAME ebx, edx 162962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers PUSH eax // Save eax which will be clobbered by the callee-save method. 16301d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers subl LITERAL(12), %esp // Align stack. 16311d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers CFI_ADJUST_CFA_OFFSET(12) 163232b12f8ae491e1acfeaee334e9a30c6c0a232072Sebastien Hertz pushl FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE-4+16(%esp) // Pass LR. 16333f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(4) 163462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers pushl %fs:THREAD_SELF_OFFSET // Pass Thread::Current(). 16353f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(4) 163662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers PUSH ecx // Pass receiver. 163762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers PUSH eax // Pass Method*. 16381d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers call SYMBOL(artInstrumentationMethodEntryFromCode) // (Method*, Object*, Thread*, LR) 16397ac7e32fb84b6a933181d31694d8a2d81ddca6d6Elliott Hughes addl LITERAL(28), %esp // Pop arguments upto saved Method*. 16409f5e1d9b63ef44e05c2cc7b141ef788ecc0084c7Christopher Ferris CFI_ADJUST_CFA_OFFSET(-28) 1641966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movl 60(%esp), %edi // Restore edi. 1642966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movl %eax, 60(%esp) // Place code* over edi, just under return pc. 16437ac7e32fb84b6a933181d31694d8a2d81ddca6d6Elliott Hughes movl SYMBOL(art_quick_instrumentation_exit)@GOT(%ebx), %ebx 16441d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers // Place instrumentation exit as return pc. ebx holds the GOT computed on entry. 1645966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movl %ebx, 64(%esp) 1646966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movl 0(%esp), %eax // Restore eax. 1647966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Restore FPRs (extra 4 bytes of offset due to EAX push at top). 1648966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movsd 8(%esp), %xmm0 1649966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movsd 16(%esp), %xmm1 1650966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movsd 24(%esp), %xmm2 1651966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movsd 32(%esp), %xmm3 1652966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell 1653966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell // Restore GPRs. 1654966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movl 40(%esp), %ecx // Restore ecx. 1655f551d1bd8da75d14fd858e4a7c9b60612aec5430Sebastien Hertz movl 44(%esp), %edx // Restore edx. 1656966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movl 48(%esp), %ebx // Restore ebx. 1657966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movl 52(%esp), %ebp // Restore ebp. 1658966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell movl 56(%esp), %esi // Restore esi. 1659966c3ae95d3c699ee9fbdbccc1acdaaf02325fafMark P Mendell addl LITERAL(60), %esp // Wind stack back upto code*. 16609f5e1d9b63ef44e05c2cc7b141ef788ecc0084c7Christopher Ferris CFI_ADJUST_CFA_OFFSET(-60) 166162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers ret // Call method (and pop). 1662468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_instrumentation_entry 166362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 1664468532ea115657709bc32ee498e701a4c71762d4Ian RogersDEFINE_FUNCTION art_quick_instrumentation_exit 166562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers pushl LITERAL(0) // Push a fake return PC as there will be none on the stack. 16669f5e1d9b63ef44e05c2cc7b141ef788ecc0084c7Christopher Ferris CFI_ADJUST_CFA_OFFSET(4) 16671d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers SETUP_REFS_ONLY_CALLEE_SAVE_FRAME ebx, ebx 166862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers mov %esp, %ecx // Remember SP 166962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers subl LITERAL(8), %esp // Save float return value. 16703f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(8) 1671fea29016a79f39ac12a4ba4ebdcbc86800c03427Andreas Gampe movq %xmm0, (%esp) 167262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers PUSH edx // Save gpr return value. 167362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers PUSH eax 1674cf2e7b0621dfe7fcacd56555dffabab65d1130e7Jeff Hao subl LITERAL(16), %esp // Align stack 1675cf2e7b0621dfe7fcacd56555dffabab65d1130e7Jeff Hao CFI_ADJUST_CFA_OFFSET(16) 1676fea29016a79f39ac12a4ba4ebdcbc86800c03427Andreas Gampe movq %xmm0, (%esp) // Pass float return value. 167762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers PUSH edx // Pass gpr return value. 167862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers PUSH eax 167962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers PUSH ecx // Pass SP. 168062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers pushl %fs:THREAD_SELF_OFFSET // Pass Thread::Current. 16813f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(4) 168229b3841ad8c1c18ee7ddd2d8cab85806b3d62eaaAndreas Gampe call SYMBOL(artInstrumentationMethodExitFromCode) // (Thread*, SP, gpr_result, fpr_result) 168362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers mov %eax, %ecx // Move returned link register. 168462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers addl LITERAL(32), %esp // Pop arguments. 16853f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(-32) 168662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers movl %edx, %ebx // Move returned link register for deopt 168762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // (ebx is pretending to be our LR). 168862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers POP eax // Restore gpr return value. 168962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers POP edx 1690fea29016a79f39ac12a4ba4ebdcbc86800c03427Andreas Gampe movq (%esp), %xmm0 // Restore fpr return value. 169162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers addl LITERAL(8), %esp 16923f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(-8) 16931d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers RESTORE_REFS_ONLY_CALLEE_SAVE_FRAME 169462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers addl LITERAL(4), %esp // Remove fake return pc. 16959f5e1d9b63ef44e05c2cc7b141ef788ecc0084c7Christopher Ferris CFI_ADJUST_CFA_OFFSET(-4) 169662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers jmp *%ecx // Return. 1697468532ea115657709bc32ee498e701a4c71762d4Ian RogersEND_FUNCTION art_quick_instrumentation_exit 1698162fd33474038f0de0388338ca007ecf400bb3dfjeffhao 16997e4fcb813d6c2657a5b9190a7c10168a2680bc45jeffhao /* 170062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers * Instrumentation has requested that we deoptimize into the interpreter. The deoptimization 170162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers * will long jump to the upcall with a special exception of -1. 17027e4fcb813d6c2657a5b9190a7c10168a2680bc45jeffhao */ 17038dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienDEFINE_FUNCTION art_quick_deoptimize 17049f5e1d9b63ef44e05c2cc7b141ef788ecc0084c7Christopher Ferris PUSH ebx // Entry point for a jump. Fake that we were called. 17051d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers SETUP_SAVE_ALL_CALLEE_SAVE_FRAME ebx, ebx 17061d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers subl LITERAL(12), %esp // Align stack. 17071d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers CFI_ADJUST_CFA_OFFSET(12) 170862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers pushl %fs:THREAD_SELF_OFFSET // Pass Thread::Current(). 17093f2d031f639b3b9dd4adbf9e70d23de931a9801dMark Mendell CFI_ADJUST_CFA_OFFSET(4) 17101d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers call SYMBOL(artDeoptimize) // artDeoptimize(Thread*) 17114360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe UNREACHABLE 1712aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian RogersEND_FUNCTION art_quick_deoptimize 1713162fd33474038f0de0388338ca007ecf400bb3dfjeffhao 171486e4671975752b112b2e8969ac6652c72c8e86c7jeffhao /* 17150747466fca310eedea5fc49e37d54f240a0b3c0fSebastien Hertz * Compiled code has requested that we deoptimize into the interpreter. The deoptimization 1716639bdd13993644a267f177f8f5936496bda65e2bAndreas Gampe * will long jump to the interpreter bridge. 17170747466fca310eedea5fc49e37d54f240a0b3c0fSebastien Hertz */ 17180747466fca310eedea5fc49e37d54f240a0b3c0fSebastien HertzDEFINE_FUNCTION art_quick_deoptimize_from_compiled_code 17190747466fca310eedea5fc49e37d54f240a0b3c0fSebastien Hertz SETUP_SAVE_ALL_CALLEE_SAVE_FRAME ebx, ebx 17200747466fca310eedea5fc49e37d54f240a0b3c0fSebastien Hertz subl LITERAL(12), %esp // Align stack. 17210747466fca310eedea5fc49e37d54f240a0b3c0fSebastien Hertz CFI_ADJUST_CFA_OFFSET(12) 17220747466fca310eedea5fc49e37d54f240a0b3c0fSebastien Hertz pushl %fs:THREAD_SELF_OFFSET // Pass Thread::Current(). 17230747466fca310eedea5fc49e37d54f240a0b3c0fSebastien Hertz CFI_ADJUST_CFA_OFFSET(4) 17240747466fca310eedea5fc49e37d54f240a0b3c0fSebastien Hertz call SYMBOL(artDeoptimizeFromCompiledCode) // artDeoptimizeFromCompiledCode(Thread*) 17250747466fca310eedea5fc49e37d54f240a0b3c0fSebastien Hertz UNREACHABLE 17260747466fca310eedea5fc49e37d54f240a0b3c0fSebastien HertzEND_FUNCTION art_quick_deoptimize_from_compiled_code 17270747466fca310eedea5fc49e37d54f240a0b3c0fSebastien Hertz 17280747466fca310eedea5fc49e37d54f240a0b3c0fSebastien Hertz /* 172986e4671975752b112b2e8969ac6652c72c8e86c7jeffhao * String's compareTo. 173086e4671975752b112b2e8969ac6652c72c8e86c7jeffhao * 173186e4671975752b112b2e8969ac6652c72c8e86c7jeffhao * On entry: 173286e4671975752b112b2e8969ac6652c72c8e86c7jeffhao * eax: this string object (known non-null) 173386e4671975752b112b2e8969ac6652c72c8e86c7jeffhao * ecx: comp string object (known non-null) 173486e4671975752b112b2e8969ac6652c72c8e86c7jeffhao */ 17358dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienDEFINE_FUNCTION art_quick_string_compareto 17364360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH esi // push callee save reg 17374360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe PUSH edi // push callee save reg 17381d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers mov MIRROR_STRING_COUNT_OFFSET(%eax), %edx 17391d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers mov MIRROR_STRING_COUNT_OFFSET(%ecx), %ebx 1740848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao lea MIRROR_STRING_VALUE_OFFSET(%eax), %esi 1741848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao lea MIRROR_STRING_VALUE_OFFSET(%ecx), %edi 174286e4671975752b112b2e8969ac6652c72c8e86c7jeffhao /* Calculate min length and count diff */ 174386e4671975752b112b2e8969ac6652c72c8e86c7jeffhao mov %edx, %ecx 174486e4671975752b112b2e8969ac6652c72c8e86c7jeffhao mov %edx, %eax 174586e4671975752b112b2e8969ac6652c72c8e86c7jeffhao subl %ebx, %eax 174686e4671975752b112b2e8969ac6652c72c8e86c7jeffhao cmovg %ebx, %ecx 174786e4671975752b112b2e8969ac6652c72c8e86c7jeffhao /* 174886e4671975752b112b2e8969ac6652c72c8e86c7jeffhao * At this point we have: 174986e4671975752b112b2e8969ac6652c72c8e86c7jeffhao * eax: value to return if first part of strings are equal 175086e4671975752b112b2e8969ac6652c72c8e86c7jeffhao * ecx: minimum among the lengths of the two strings 175186e4671975752b112b2e8969ac6652c72c8e86c7jeffhao * esi: pointer to this string data 175286e4671975752b112b2e8969ac6652c72c8e86c7jeffhao * edi: pointer to comp string data 175386e4671975752b112b2e8969ac6652c72c8e86c7jeffhao */ 17544554bfdc2859712a763a12e35a4176914fc7c994Alexei Zavjalov jecxz .Lkeep_length 175586e4671975752b112b2e8969ac6652c72c8e86c7jeffhao repe cmpsw // find nonmatching chars in [%esi] and [%edi], up to length %ecx 17568016a12a5f9c2ea70b52e353a0169ba836ee9402Ian Rogers jne .Lnot_equal 17574554bfdc2859712a763a12e35a4176914fc7c994Alexei Zavjalov.Lkeep_length: 1758aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers POP edi // pop callee save reg 1759aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers POP esi // pop callee save reg 176086e4671975752b112b2e8969ac6652c72c8e86c7jeffhao ret 176186e4671975752b112b2e8969ac6652c72c8e86c7jeffhao .balign 16 17628016a12a5f9c2ea70b52e353a0169ba836ee9402Ian Rogers.Lnot_equal: 17631b09b094a85e03f6ef5f687f58bb91c433273ba1Ian Rogers movzwl -2(%esi), %eax // get last compared char from this string 17641b09b094a85e03f6ef5f687f58bb91c433273ba1Ian Rogers movzwl -2(%edi), %ecx // get last compared char from comp string 176586e4671975752b112b2e8969ac6652c72c8e86c7jeffhao subl %ecx, %eax // return the difference 1766aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers POP edi // pop callee save reg 1767aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian Rogers POP esi // pop callee save reg 176886e4671975752b112b2e8969ac6652c72c8e86c7jeffhao ret 1769aeeada47ecd9c6a7f5ea17bb1921d2fdbd394df9Ian RogersEND_FUNCTION art_quick_string_compareto 177086e4671975752b112b2e8969ac6652c72c8e86c7jeffhao 17718ce6b9040747054b444a7fa706503cd257801936Dave Allison// Return from a nested signal: 17728ce6b9040747054b444a7fa706503cd257801936Dave Allison// Entry: 17738ce6b9040747054b444a7fa706503cd257801936Dave Allison// eax: address of jmp_buf in TLS 17748ce6b9040747054b444a7fa706503cd257801936Dave Allison 17758ce6b9040747054b444a7fa706503cd257801936Dave AllisonDEFINE_FUNCTION art_nested_signal_return 17761d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers SETUP_GOT_NOSAVE ebx // sets %ebx for call into PLT 17778ce6b9040747054b444a7fa706503cd257801936Dave Allison movl LITERAL(1), %ecx 17789f5e1d9b63ef44e05c2cc7b141ef788ecc0084c7Christopher Ferris PUSH ecx // second arg to longjmp (1) 17799f5e1d9b63ef44e05c2cc7b141ef788ecc0084c7Christopher Ferris PUSH eax // first arg to longjmp (jmp_buf) 17808ce6b9040747054b444a7fa706503cd257801936Dave Allison call PLT_SYMBOL(longjmp) 17814360be281a5f938e1762a1e3ec3b8a949ba05ff3Andreas Gampe UNREACHABLE 17828ce6b9040747054b444a7fa706503cd257801936Dave AllisonEND_FUNCTION art_nested_signal_return 17838ce6b9040747054b444a7fa706503cd257801936Dave Allison 17847c1559a06041c9c299d5ab514d54b2102f204a84Roland LevillainDEFINE_FUNCTION art_quick_read_barrier_mark 17857c1559a06041c9c299d5ab514d54b2102f204a84Roland Levillain PUSH eax // pass arg1 - obj 17867c1559a06041c9c299d5ab514d54b2102f204a84Roland Levillain call SYMBOL(artReadBarrierMark) // artReadBarrierMark(obj) 17877c1559a06041c9c299d5ab514d54b2102f204a84Roland Levillain addl LITERAL(4), %esp // pop argument 17887c1559a06041c9c299d5ab514d54b2102f204a84Roland Levillain CFI_ADJUST_CFA_OFFSET(-4) 17897c1559a06041c9c299d5ab514d54b2102f204a84Roland Levillain ret 17907c1559a06041c9c299d5ab514d54b2102f204a84Roland LevillainEND_FUNCTION art_quick_read_barrier_mark 17917c1559a06041c9c299d5ab514d54b2102f204a84Roland Levillain 17921aee900d5a0b3a8d78725a7551356bda0d8554e1Man CaoDEFINE_FUNCTION art_quick_read_barrier_slow 17930d5a281c671444bfa75d63caf1427a8c0e6e1177Roland Levillain PUSH edx // pass arg3 - offset 17940d5a281c671444bfa75d63caf1427a8c0e6e1177Roland Levillain PUSH ecx // pass arg2 - obj 17950d5a281c671444bfa75d63caf1427a8c0e6e1177Roland Levillain PUSH eax // pass arg1 - ref 17960d5a281c671444bfa75d63caf1427a8c0e6e1177Roland Levillain call SYMBOL(artReadBarrierSlow) // artReadBarrierSlow(ref, obj, offset) 17970d5a281c671444bfa75d63caf1427a8c0e6e1177Roland Levillain addl LITERAL(12), %esp // pop arguments 17981aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao CFI_ADJUST_CFA_OFFSET(-12) 17991aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao ret 18001aee900d5a0b3a8d78725a7551356bda0d8554e1Man CaoEND_FUNCTION art_quick_read_barrier_slow 18011aee900d5a0b3a8d78725a7551356bda0d8554e1Man Cao 18020d5a281c671444bfa75d63caf1427a8c0e6e1177Roland LevillainDEFINE_FUNCTION art_quick_read_barrier_for_root_slow 18030d5a281c671444bfa75d63caf1427a8c0e6e1177Roland Levillain PUSH eax // pass arg1 - root 18040d5a281c671444bfa75d63caf1427a8c0e6e1177Roland Levillain call SYMBOL(artReadBarrierForRootSlow) // artReadBarrierForRootSlow(root) 18050d5a281c671444bfa75d63caf1427a8c0e6e1177Roland Levillain addl LITERAL(4), %esp // pop argument 18060d5a281c671444bfa75d63caf1427a8c0e6e1177Roland Levillain CFI_ADJUST_CFA_OFFSET(-4) 18070d5a281c671444bfa75d63caf1427a8c0e6e1177Roland Levillain ret 18080d5a281c671444bfa75d63caf1427a8c0e6e1177Roland LevillainEND_FUNCTION art_quick_read_barrier_for_root_slow 18090d5a281c671444bfa75d63caf1427a8c0e6e1177Roland Levillain 1810b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray /* 1811b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray * On stack replacement stub. 1812b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray * On entry: 1813b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray * [sp] = return address 1814b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray * [sp + 4] = stack to copy 1815b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray * [sp + 8] = size of stack 1816b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray * [sp + 12] = pc to call 1817b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray * [sp + 16] = JValue* result 1818b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray * [sp + 20] = shorty 1819b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray * [sp + 24] = thread 1820b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray */ 1821b331febbab8e916680faba722cc84b66b84218a3Nicolas GeoffrayDEFINE_FUNCTION art_quick_osr_stub 1822b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray // Save native callee saves. 1823b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray PUSH ebp 1824b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray PUSH ebx 1825b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray PUSH esi 1826b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray PUSH edi 1827b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray mov 4+16(%esp), %esi // ESI = argument array 1828b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray mov 8+16(%esp), %ecx // ECX = size of args 1829b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray mov 12+16(%esp), %ebx // EBX = pc to call 1830b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray mov %esp, %ebp // Save stack pointer 1831b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray andl LITERAL(0xFFFFFFF0), %esp // Align stack 1832b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray PUSH ebp // Save old stack pointer 1833b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray subl LITERAL(12), %esp // Align stack 1834b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray movl LITERAL(0), (%esp) // Store null for ArtMethod* slot 1835b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray call .Losr_entry 1836b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray 1837b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray // Restore stack pointer. 1838b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray addl LITERAL(12), %esp 1839b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray POP ebp 1840b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray mov %ebp, %esp 1841b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray 1842b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray // Restore callee saves. 1843b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray POP edi 1844b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray POP esi 1845b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray POP ebx 1846b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray POP ebp 1847b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray mov 16(%esp), %ecx // Get JValue result 1848b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray mov %eax, (%ecx) // Store the result assuming it is a long, int or Object* 1849b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray mov %edx, 4(%ecx) // Store the other half of the result 1850b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray mov 20(%esp), %edx // Get the shorty 1851b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray cmpb LITERAL(68), (%edx) // Test if result type char == 'D' 1852b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray je .Losr_return_double_quick 1853b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray cmpb LITERAL(70), (%edx) // Test if result type char == 'F' 1854b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray je .Losr_return_float_quick 1855b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray ret 1856b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray.Losr_return_double_quick: 1857b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray movsd %xmm0, (%ecx) // Store the floating point result 1858b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray ret 1859b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray.Losr_return_float_quick: 1860b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray movss %xmm0, (%ecx) // Store the floating point result 1861b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray ret 1862b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray.Losr_entry: 1863b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray subl LITERAL(4), %ecx // Given stack size contains pushed frame pointer, substract it. 1864b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray subl %ecx, %esp 1865b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray mov %esp, %edi // EDI = beginning of stack 1866b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray rep movsb // while (ecx--) { *edi++ = *esi++ } 1867b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray jmp *%ebx 1868b331febbab8e916680faba722cc84b66b84218a3Nicolas GeoffrayEND_FUNCTION art_quick_osr_stub 1869b331febbab8e916680faba722cc84b66b84218a3Nicolas Geoffray 1870787ec205ee545b9c08f4fc6d3823cb43d10083afElliott Hughes // TODO: implement these! 18718dbb708c7dc05c786329eb5c3fff3194ab6472acLogan ChienUNIMPLEMENTED art_quick_memcmp16 1872