1efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 2efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Copyright (C) 2012 The Android Open Source Project 3efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * 4efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Licensed under the Apache License, Version 2.0 (the "License"); 5efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * you may not use this file except in compliance with the License. 6efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * You may obtain a copy of the License at 7efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * 8efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * http://www.apache.org/licenses/LICENSE-2.0 9efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * 10efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Unless required by applicable law or agreed to in writing, software 11efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * distributed under the License is distributed on an "AS IS" BASIS, 12efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * See the License for the specific language governing permissions and 14efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * limitations under the License. 15efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 16efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 17efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* This file contains codegen for the X86 ISA */ 18efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 1902031b185b4653e6c72e21f7a51238b903f6d638buzbee#include "codegen_x86.h" 200b9203e7996ee1856f620f95d95d8a273c43a3dfAndreas Gampe 213d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier#include "art_method.h" 220b9203e7996ee1856f620f95d95d8a273c43a3dfAndreas Gampe#include "base/logging.h" 23848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao#include "dex/quick/dex_file_to_method_inliner_map.h" 247940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "dex/quick/mir_to_lir-inl.h" 250b9203e7996ee1856f620f95d95d8a273c43a3dfAndreas Gampe#include "driver/compiler_driver.h" 2620f85597828194c12be10d3a927999def066555eVladimir Marko#include "driver/compiler_options.h" 27576ca0cd692c0b6ae70e776de91015b8ff000a08Ian Rogers#include "gc/accounting/card_table.h" 28f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko#include "mirror/object_array-inl.h" 29dc56cc509d8e1718ad321f7a91661dbe85ec8cefVladimir Marko#include "utils/dex_cache_arrays_layout-inl.h" 30641ce0371c2f0dc95d26be02d8366124c8b66653Brian Carlstrom#include "x86_lir.h" 311bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee 32efc6369224b036a1fb77849f7ae65b3492c832c0buzbeenamespace art { 33efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 34efc6369224b036a1fb77849f7ae65b3492c832c0buzbee/* 35efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * The sparse table in the literal pool is an array of <key,displacement> 36efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * pairs. 37efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 3848971b3242e5126bcd800cc9c68df64596b43d13Andreas Gampevoid X86Mir2Lir::GenLargeSparseSwitch(MIR* mir, DexOffset table_offset, RegLocation rl_src) { 39da96aeda912ff317de2c41e5a49bd244427238acChao-ying Fu GenSmallSparseSwitch(mir, table_offset, rl_src); 40da96aeda912ff317de2c41e5a49bd244427238acChao-ying Fu} 41da96aeda912ff317de2c41e5a49bd244427238acChao-ying Fu 42da96aeda912ff317de2c41e5a49bd244427238acChao-ying Fu/* 43efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * Code pattern will look something like: 44efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * 45fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee * mov r_val, .. 46efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * call 0 47fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee * pop r_start_of_method 48fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee * sub r_start_of_method, .. 49fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee * mov r_key_reg, r_val 50fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee * sub r_key_reg, low_key 51fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee * cmp r_key_reg, size-1 ; bound check 52efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * ja done 53fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee * mov r_disp, [r_start_of_method + r_key_reg * 4 + table_offset] 54fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee * add r_start_of_method, r_disp 55fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee * jmp r_start_of_method 56efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * done: 57efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 5848971b3242e5126bcd800cc9c68df64596b43d13Andreas Gampevoid X86Mir2Lir::GenLargePackedSwitch(MIR* mir, DexOffset table_offset, RegLocation rl_src) { 5972f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu const uint16_t* table = mir_graph_->GetTable(mir, table_offset); 60efc6369224b036a1fb77849f7ae65b3492c832c0buzbee // Add the table to the list - we'll process it later 610d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee SwitchTable* tab_rec = 6283cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko static_cast<SwitchTable*>(arena_->Alloc(sizeof(SwitchTable), kArenaAllocData)); 6372f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu tab_rec->switch_mir = mir; 64fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee tab_rec->table = table; 651fd3346740dfb7f47be9922312b68a4227fada96buzbee tab_rec->vaddr = current_dalvik_offset_; 66efc6369224b036a1fb77849f7ae65b3492c832c0buzbee int size = table[1]; 67e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko switch_tables_.push_back(tab_rec); 68efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 69efc6369224b036a1fb77849f7ae65b3492c832c0buzbee // Get the switch value 701fd3346740dfb7f47be9922312b68a4227fada96buzbee rl_src = LoadValue(rl_src, kCoreReg); 7127dee8bcd7b4a53840b60818da8d2c819ef199bdMark Mendell 72fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int low_key = s4FromSwitchData(&table[2]); 732700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee RegStorage keyReg; 74efc6369224b036a1fb77849f7ae65b3492c832c0buzbee // Remove the bias, if necessary 75fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (low_key == 0) { 762700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee keyReg = rl_src.reg; 77efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } else { 781fd3346740dfb7f47be9922312b68a4227fada96buzbee keyReg = AllocTemp(); 792700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee OpRegRegImm(kOpSub, keyReg, rl_src.reg, low_key); 80efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 8127dee8bcd7b4a53840b60818da8d2c819ef199bdMark Mendell 82efc6369224b036a1fb77849f7ae65b3492c832c0buzbee // Bounds check - if < 0 or >= size continue following switch 83407a9d2847161b843966a443b71760b1280bd396Serguei Katkov OpRegImm(kOpCmp, keyReg, size - 1); 842cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier LIR* branch_over = OpCondBranch(kCondHi, nullptr); 85efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 8627dee8bcd7b4a53840b60818da8d2c819ef199bdMark Mendell RegStorage addr_for_jump; 8727dee8bcd7b4a53840b60818da8d2c819ef199bdMark Mendell if (cu_->target64) { 8827dee8bcd7b4a53840b60818da8d2c819ef199bdMark Mendell RegStorage table_base = AllocTempWide(); 8927dee8bcd7b4a53840b60818da8d2c819ef199bdMark Mendell // Load the address of the table into table_base. 9027dee8bcd7b4a53840b60818da8d2c819ef199bdMark Mendell LIR* lea = RawLIR(current_dalvik_offset_, kX86Lea64RM, table_base.GetReg(), kRIPReg, 9127dee8bcd7b4a53840b60818da8d2c819ef199bdMark Mendell 256, 0, WrapPointer(tab_rec)); 9227dee8bcd7b4a53840b60818da8d2c819ef199bdMark Mendell lea->flags.fixup = kFixupSwitchTable; 9327dee8bcd7b4a53840b60818da8d2c819ef199bdMark Mendell AppendLIR(lea); 9427dee8bcd7b4a53840b60818da8d2c819ef199bdMark Mendell 9527dee8bcd7b4a53840b60818da8d2c819ef199bdMark Mendell // Load the offset from the table out of the table. 9627dee8bcd7b4a53840b60818da8d2c819ef199bdMark Mendell addr_for_jump = AllocTempWide(); 9727dee8bcd7b4a53840b60818da8d2c819ef199bdMark Mendell NewLIR5(kX86MovsxdRA, addr_for_jump.GetReg(), table_base.GetReg(), keyReg.GetReg(), 2, 0); 9827dee8bcd7b4a53840b60818da8d2c819ef199bdMark Mendell 9927dee8bcd7b4a53840b60818da8d2c819ef199bdMark Mendell // Add the offset from the table to the table base. 10027dee8bcd7b4a53840b60818da8d2c819ef199bdMark Mendell OpRegReg(kOpAdd, addr_for_jump, table_base); 1011961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko tab_rec->anchor = nullptr; // Unused for x86-64. 10227dee8bcd7b4a53840b60818da8d2c819ef199bdMark Mendell } else { 1031961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko // Get the PC to a register and get the anchor. 1041961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko LIR* anchor; 1051961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko RegStorage r_pc = GetPcAndAnchor(&anchor); 1061961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko 10727dee8bcd7b4a53840b60818da8d2c819ef199bdMark Mendell // Load the displacement from the switch table. 10827dee8bcd7b4a53840b60818da8d2c819ef199bdMark Mendell addr_for_jump = AllocTemp(); 1091961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko NewLIR5(kX86PcRelLoadRA, addr_for_jump.GetReg(), r_pc.GetReg(), keyReg.GetReg(), 11027dee8bcd7b4a53840b60818da8d2c819ef199bdMark Mendell 2, WrapPointer(tab_rec)); 1111961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko // Add displacement and r_pc to get the address. 1121961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko OpRegReg(kOpAdd, addr_for_jump, r_pc); 1131961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko tab_rec->anchor = anchor; 11427dee8bcd7b4a53840b60818da8d2c819ef199bdMark Mendell } 11527dee8bcd7b4a53840b60818da8d2c819ef199bdMark Mendell 116efc6369224b036a1fb77849f7ae65b3492c832c0buzbee // ..and go! 1171961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko NewLIR1(kX86JmpR, addr_for_jump.GetReg()); 118efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 119fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee /* branch_over target here */ 1201fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* target = NewLIR0(kPseudoTargetLabel); 121fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee branch_over->target = target; 122efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 123efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 1242ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid X86Mir2Lir::GenMoveException(RegLocation rl_dest) { 12533ae5583bdd69847a7316ab38a8fa8ccd63093efbuzbee int ex_offset = cu_->target64 ? 1262f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe Thread::ExceptionOffset<8>().Int32Value() : 1272f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe Thread::ExceptionOffset<4>().Int32Value(); 128a0cd2d701f29e0bc6275f1b13c0edfd4ec391879buzbee RegLocation rl_result = EvalLoc(rl_dest, kRefReg, true); 129407a9d2847161b843966a443b71760b1280bd396Serguei Katkov NewLIR2(cu_->target64 ? kX86Mov64RT : kX86Mov32RT, rl_result.reg.GetReg(), ex_offset); 130407a9d2847161b843966a443b71760b1280bd396Serguei Katkov NewLIR2(cu_->target64 ? kX86Mov64TI : kX86Mov32TI, ex_offset, 0); 1311fd3346740dfb7f47be9922312b68a4227fada96buzbee StoreValue(rl_dest, rl_result); 1321eab958cde39a7e2f0e5ce01730f4e2e75c72519jeffhao} 1331eab958cde39a7e2f0e5ce01730f4e2e75c72519jeffhao 134bf535be514570fc33fc0a6347a87dcd9097d9bfdVladimir Markovoid X86Mir2Lir::UnconditionallyMarkGCCard(RegStorage tgt_addr_reg) { 135407a9d2847161b843966a443b71760b1280bd396Serguei Katkov DCHECK_EQ(tgt_addr_reg.Is64Bit(), cu_->target64); 136407a9d2847161b843966a443b71760b1280bd396Serguei Katkov RegStorage reg_card_base = AllocTempRef(); 137407a9d2847161b843966a443b71760b1280bd396Serguei Katkov RegStorage reg_card_no = AllocTempRef(); 13833ae5583bdd69847a7316ab38a8fa8ccd63093efbuzbee int ct_offset = cu_->target64 ? 1392f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe Thread::CardTableOffset<8>().Int32Value() : 1402f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe Thread::CardTableOffset<4>().Int32Value(); 141407a9d2847161b843966a443b71760b1280bd396Serguei Katkov NewLIR2(cu_->target64 ? kX86Mov64RT : kX86Mov32RT, reg_card_base.GetReg(), ct_offset); 1421d54e73444e017d3a65234e0f193846f3e27472bIan Rogers OpRegRegImm(kOpLsr, reg_card_no, tgt_addr_reg, gc::accounting::CardTable::kCardShift); 1432700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee StoreBaseIndexed(reg_card_base, reg_card_no, reg_card_base, 0, kUnsignedByte); 1441fd3346740dfb7f47be9922312b68a4227fada96buzbee FreeTemp(reg_card_base); 1451fd3346740dfb7f47be9922312b68a4227fada96buzbee FreeTemp(reg_card_no); 146efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 147efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 1481109fb3cacc8bb667979780c2b4b12ce5bb64549David Srbeckystatic dwarf::Reg DwarfCoreReg(bool is_x86_64, int num) { 1491109fb3cacc8bb667979780c2b4b12ce5bb64549David Srbecky return is_x86_64 ? dwarf::Reg::X86_64Core(num) : dwarf::Reg::X86Core(num); 1501109fb3cacc8bb667979780c2b4b12ce5bb64549David Srbecky} 1511109fb3cacc8bb667979780c2b4b12ce5bb64549David Srbecky 1522ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid X86Mir2Lir::GenEntrySequence(RegLocation* ArgLocs, RegLocation rl_method) { 153efc6369224b036a1fb77849f7ae65b3492c832c0buzbee /* 154efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * On entry, rX86_ARG0, rX86_ARG1, rX86_ARG2 are live. Let the register 155efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * allocation mechanism know so it doesn't try to use any of them when 156efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * expanding the frame or flushing. This leaves the utility 157efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * code with no spare temps. 158efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 159b28c1c06236751aa5c9e64dcb68b3c940341e496Ian Rogers const RegStorage arg0 = TargetReg32(kArg0); 160b28c1c06236751aa5c9e64dcb68b3c940341e496Ian Rogers const RegStorage arg1 = TargetReg32(kArg1); 161b28c1c06236751aa5c9e64dcb68b3c940341e496Ian Rogers const RegStorage arg2 = TargetReg32(kArg2); 162b28c1c06236751aa5c9e64dcb68b3c940341e496Ian Rogers LockTemp(arg0); 163b28c1c06236751aa5c9e64dcb68b3c940341e496Ian Rogers LockTemp(arg1); 164b28c1c06236751aa5c9e64dcb68b3c940341e496Ian Rogers LockTemp(arg2); 165efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 166efc6369224b036a1fb77849f7ae65b3492c832c0buzbee /* 167efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * We can safely skip the stack overflow check if we're 168efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * a leaf *and* our frame size < fudge factor. 169efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 170b28c1c06236751aa5c9e64dcb68b3c940341e496Ian Rogers const InstructionSet isa = cu_->target64 ? kX86_64 : kX86; 171648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison bool skip_overflow_check = mir_graph_->MethodIsLeaf() && !FrameNeedsStackCheck(frame_size_, isa); 172b28c1c06236751aa5c9e64dcb68b3c940341e496Ian Rogers const RegStorage rs_rSP = cu_->target64 ? rs_rX86_SP_64 : rs_rX86_SP_32; 17369dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison 17469dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison // If we doing an implicit stack overflow check, perform the load immediately 17569dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison // before the stack pointer is decremented and anything is saved. 17669dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison if (!skip_overflow_check && 17769dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison cu_->compiler_driver->GetCompilerOptions().GetImplicitStackOverflowChecks()) { 17869dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison // Implicit stack overflow check. 17969dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison // test eax,[esp + -overflow] 18069dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison int overflow = GetStackOverflowReservedBytes(isa); 181b28c1c06236751aa5c9e64dcb68b3c940341e496Ian Rogers NewLIR3(kX86Test32RM, rs_rAX.GetReg(), rs_rSP.GetReg(), -overflow); 18269dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison MarkPossibleStackOverflowException(); 18369dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison } 18469dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison 18569dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison /* Build frame, return address already on stack */ 1861109fb3cacc8bb667979780c2b4b12ce5bb64549David Srbecky cfi_.SetCurrentCFAOffset(GetInstructionSetPointerSize(cu_->instruction_set)); 1878c57831b2b07185ee1986b9af68a351e1ca584c3David Srbecky OpRegImm(kOpSub, rs_rSP, frame_size_ - GetInstructionSetPointerSize(cu_->instruction_set)); 1881109fb3cacc8bb667979780c2b4b12ce5bb64549David Srbecky cfi_.DefCFAOffset(frame_size_); 18969dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison 190efc6369224b036a1fb77849f7ae65b3492c832c0buzbee /* Spill core callee saves */ 1911fd3346740dfb7f47be9922312b68a4227fada96buzbee SpillCoreRegs(); 192c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov SpillFPRegs(); 193fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (!skip_overflow_check) { 1940d507d1e0441e6bd6f3affca3a60774ea920f317Mathieu Chartier class StackOverflowSlowPath : public LIRSlowPath { 1950d507d1e0441e6bd6f3affca3a60774ea920f317Mathieu Chartier public: 1960d507d1e0441e6bd6f3affca3a60774ea920f317Mathieu Chartier StackOverflowSlowPath(Mir2Lir* m2l, LIR* branch, size_t sp_displace) 1970b40ecf156e309aa17c72a28cd1b0237dbfb8746Vladimir Marko : LIRSlowPath(m2l, branch), sp_displace_(sp_displace) { 1980d507d1e0441e6bd6f3affca3a60774ea920f317Mathieu Chartier } 1990d507d1e0441e6bd6f3affca3a60774ea920f317Mathieu Chartier void Compile() OVERRIDE { 2000d507d1e0441e6bd6f3affca3a60774ea920f317Mathieu Chartier m2l_->ResetRegPool(); 2010d507d1e0441e6bd6f3affca3a60774ea920f317Mathieu Chartier m2l_->ResetDefTracking(); 2026ffcfa04ebb2660e238742a6000f5ccebdd5df15Mingyao Yang GenerateTargetLabel(kPseudoThrowTarget); 203b28c1c06236751aa5c9e64dcb68b3c940341e496Ian Rogers const RegStorage local_rs_rSP = cu_->target64 ? rs_rX86_SP_64 : rs_rX86_SP_32; 204b28c1c06236751aa5c9e64dcb68b3c940341e496Ian Rogers m2l_->OpRegImm(kOpAdd, local_rs_rSP, sp_displace_); 2051109fb3cacc8bb667979780c2b4b12ce5bb64549David Srbecky m2l_->cfi().AdjustCFAOffset(-sp_displace_); 2060d507d1e0441e6bd6f3affca3a60774ea920f317Mathieu Chartier m2l_->ClobberCallerSave(); 2070d507d1e0441e6bd6f3affca3a60774ea920f317Mathieu Chartier // Assumes codegen and target are in thumb2 mode. 208984305917bf57b3f8d92965e4715a0370cc5bcfbAndreas Gampe m2l_->CallHelper(RegStorage::InvalidReg(), kQuickThrowStackOverflow, 209984305917bf57b3f8d92965e4715a0370cc5bcfbAndreas Gampe false /* MarkSafepointPC */, false /* UseLink */); 2101109fb3cacc8bb667979780c2b4b12ce5bb64549David Srbecky m2l_->cfi().AdjustCFAOffset(sp_displace_); 2110d507d1e0441e6bd6f3affca3a60774ea920f317Mathieu Chartier } 2120d507d1e0441e6bd6f3affca3a60774ea920f317Mathieu Chartier 2130d507d1e0441e6bd6f3affca3a60774ea920f317Mathieu Chartier private: 2140d507d1e0441e6bd6f3affca3a60774ea920f317Mathieu Chartier const size_t sp_displace_; 2150d507d1e0441e6bd6f3affca3a60774ea920f317Mathieu Chartier }; 21669dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison if (!cu_->compiler_driver->GetCompilerOptions().GetImplicitStackOverflowChecks()) { 21769dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison // TODO: for large frames we should do something like: 21869dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison // spill ebp 21969dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison // lea ebp, [esp + frame_size] 22069dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison // cmp ebp, fs:[stack_end_] 22169dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison // jcc stack_overflow_exception 22269dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison // mov esp, ebp 22369dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison // in case a signal comes in that's not using an alternate signal stack and the large frame 22469dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison // may have moved us outside of the reserved area at the end of the stack. 22569dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison // cmp rs_rX86_SP, fs:[stack_end_]; jcc throw_slowpath 22669dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison if (cu_->target64) { 227b28c1c06236751aa5c9e64dcb68b3c940341e496Ian Rogers OpRegThreadMem(kOpCmp, rs_rX86_SP_64, Thread::StackEndOffset<8>()); 22869dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison } else { 229b28c1c06236751aa5c9e64dcb68b3c940341e496Ian Rogers OpRegThreadMem(kOpCmp, rs_rX86_SP_32, Thread::StackEndOffset<4>()); 23069dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison } 23169dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison LIR* branch = OpCondBranch(kCondUlt, nullptr); 23269dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison AddSlowPath( 233e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu new(arena_)StackOverflowSlowPath(this, branch, 234e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu frame_size_ - 235e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu GetInstructionSetPointerSize(cu_->instruction_set))); 23669dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison } 237efc6369224b036a1fb77849f7ae65b3492c832c0buzbee } 238efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 2391fd3346740dfb7f47be9922312b68a4227fada96buzbee FlushIns(ArgLocs, rl_method); 240efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 2411961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko // We can promote the PC of an anchor for PC-relative addressing to a register 2421961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko // if it's used at least twice. Without investigating where we should lazily 2431961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko // load the reference, we conveniently load it after flushing inputs. 2441961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko if (pc_rel_base_reg_.Valid()) { 2451961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko DCHECK(!cu_->target64); 2461961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko setup_pc_rel_base_reg_ = OpLoadPc(pc_rel_base_reg_); 24767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } 24867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell 249b28c1c06236751aa5c9e64dcb68b3c940341e496Ian Rogers FreeTemp(arg0); 250b28c1c06236751aa5c9e64dcb68b3c940341e496Ian Rogers FreeTemp(arg1); 251b28c1c06236751aa5c9e64dcb68b3c940341e496Ian Rogers FreeTemp(arg2); 252efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 253efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 2541fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid X86Mir2Lir::GenExitSequence() { 2551109fb3cacc8bb667979780c2b4b12ce5bb64549David Srbecky cfi_.RememberState(); 256efc6369224b036a1fb77849f7ae65b3492c832c0buzbee /* 257efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * In the exit path, rX86_RET0/rX86_RET1 are live - make sure they aren't 258efc6369224b036a1fb77849f7ae65b3492c832c0buzbee * allocated by the register utilities as temps. 259efc6369224b036a1fb77849f7ae65b3492c832c0buzbee */ 260091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee LockTemp(rs_rX86_RET0); 261091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee LockTemp(rs_rX86_RET1); 262efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 2631fd3346740dfb7f47be9922312b68a4227fada96buzbee UnSpillCoreRegs(); 264c380191f3048db2a3796d65db8e5d5a5e7b08c65Serguei Katkov UnSpillFPRegs(); 265efc6369224b036a1fb77849f7ae65b3492c832c0buzbee /* Remove frame except for return address */ 266b28c1c06236751aa5c9e64dcb68b3c940341e496Ian Rogers const RegStorage rs_rSP = cu_->target64 ? rs_rX86_SP_64 : rs_rX86_SP_32; 2678c57831b2b07185ee1986b9af68a351e1ca584c3David Srbecky int adjust = frame_size_ - GetInstructionSetPointerSize(cu_->instruction_set); 2688c57831b2b07185ee1986b9af68a351e1ca584c3David Srbecky OpRegImm(kOpAdd, rs_rSP, adjust); 2691109fb3cacc8bb667979780c2b4b12ce5bb64549David Srbecky cfi_.AdjustCFAOffset(-adjust); 2701109fb3cacc8bb667979780c2b4b12ce5bb64549David Srbecky // There is only the return PC on the stack now. 2711fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR0(kX86Ret); 2721109fb3cacc8bb667979780c2b4b12ce5bb64549David Srbecky // The CFI should be restored for any code that follows the exit block. 2731109fb3cacc8bb667979780c2b4b12ce5bb64549David Srbecky cfi_.RestoreState(); 2741109fb3cacc8bb667979780c2b4b12ce5bb64549David Srbecky cfi_.DefCFAOffset(frame_size_); 275efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} 276efc6369224b036a1fb77849f7ae65b3492c832c0buzbee 2773bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoruvoid X86Mir2Lir::GenSpecialExitSequence() { 2783bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru NewLIR0(kX86Ret); 2793bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru} 2803bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru 2816ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Markovoid X86Mir2Lir::GenSpecialEntryForSuspend() { 2826ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Marko // Keep 16-byte stack alignment, there's already the return address, so 2836ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Marko // - for 32-bit push EAX, i.e. ArtMethod*, ESI, EDI, 2846ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Marko // - for 64-bit push RAX, i.e. ArtMethod*. 2851109fb3cacc8bb667979780c2b4b12ce5bb64549David Srbecky const int kRegSize = cu_->target64 ? 8 : 4; 2861109fb3cacc8bb667979780c2b4b12ce5bb64549David Srbecky cfi_.SetCurrentCFAOffset(kRegSize); // Return address. 2876ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Marko if (!cu_->target64) { 2886ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Marko DCHECK(!IsTemp(rs_rSI)); 2896ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Marko DCHECK(!IsTemp(rs_rDI)); 2906ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Marko core_spill_mask_ = 291d7a5e553e0ee0a2090c719312f7d24dae3746cecVladimir Marko (1u << rs_rDI.GetRegNum()) | (1u << rs_rSI.GetRegNum()) | (1u << rs_rRET.GetRegNum()); 2926ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Marko num_core_spills_ = 3u; 2936ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Marko } else { 2946ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Marko core_spill_mask_ = (1u << rs_rRET.GetRegNum()); 2956ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Marko num_core_spills_ = 1u; 2966ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Marko } 2976ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Marko fp_spill_mask_ = 0u; 2986ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Marko num_fp_spills_ = 0u; 2996ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Marko frame_size_ = 16u; 3006ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Marko core_vmap_table_.clear(); 3016ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Marko fp_vmap_table_.clear(); 3026ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Marko if (!cu_->target64) { 3036ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Marko NewLIR1(kX86Push32R, rs_rDI.GetReg()); 3041109fb3cacc8bb667979780c2b4b12ce5bb64549David Srbecky cfi_.AdjustCFAOffset(kRegSize); 3051109fb3cacc8bb667979780c2b4b12ce5bb64549David Srbecky cfi_.RelOffset(DwarfCoreReg(cu_->target64, rs_rDI.GetRegNum()), 0); 3066ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Marko NewLIR1(kX86Push32R, rs_rSI.GetReg()); 3071109fb3cacc8bb667979780c2b4b12ce5bb64549David Srbecky cfi_.AdjustCFAOffset(kRegSize); 3081109fb3cacc8bb667979780c2b4b12ce5bb64549David Srbecky cfi_.RelOffset(DwarfCoreReg(cu_->target64, rs_rSI.GetRegNum()), 0); 3096ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Marko } 3106ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Marko NewLIR1(kX86Push32R, TargetReg(kArg0, kRef).GetReg()); // ArtMethod* 3111109fb3cacc8bb667979780c2b4b12ce5bb64549David Srbecky cfi_.AdjustCFAOffset(kRegSize); 3121109fb3cacc8bb667979780c2b4b12ce5bb64549David Srbecky // Do not generate CFI for scratch register. 3136ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Marko} 3146ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Marko 3156ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Markovoid X86Mir2Lir::GenSpecialExitForSuspend() { 3161109fb3cacc8bb667979780c2b4b12ce5bb64549David Srbecky const int kRegSize = cu_->target64 ? 8 : 4; 3176ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Marko // Pop the frame. (ArtMethod* no longer needed but restore it anyway.) 3186ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Marko NewLIR1(kX86Pop32R, TargetReg(kArg0, kRef).GetReg()); // ArtMethod* 3191109fb3cacc8bb667979780c2b4b12ce5bb64549David Srbecky cfi_.AdjustCFAOffset(-kRegSize); 3206ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Marko if (!cu_->target64) { 3216ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Marko NewLIR1(kX86Pop32R, rs_rSI.GetReg()); 3221109fb3cacc8bb667979780c2b4b12ce5bb64549David Srbecky cfi_.AdjustCFAOffset(-kRegSize); 3231109fb3cacc8bb667979780c2b4b12ce5bb64549David Srbecky cfi_.Restore(DwarfCoreReg(cu_->target64, rs_rSI.GetRegNum())); 3246ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Marko NewLIR1(kX86Pop32R, rs_rDI.GetReg()); 3251109fb3cacc8bb667979780c2b4b12ce5bb64549David Srbecky cfi_.AdjustCFAOffset(-kRegSize); 3261109fb3cacc8bb667979780c2b4b12ce5bb64549David Srbecky cfi_.Restore(DwarfCoreReg(cu_->target64, rs_rDI.GetRegNum())); 3276ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Marko } 3286ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Marko} 3296ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Marko 33069dfe51b684dd9d510dbcb63295fe180f998efdeDave Allisonvoid X86Mir2Lir::GenImplicitNullCheck(RegStorage reg, int opt_flags) { 33169dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison if (!(cu_->disable_opt & (1 << kNullCheckElimination)) && (opt_flags & MIR_IGNORE_NULL_CHECK)) { 33269dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison return; 33369dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison } 33469dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison // Implicit null pointer check. 33569dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison // test eax,[arg1+0] 33669dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison NewLIR3(kX86Test32RM, rs_rAX.GetReg(), reg.GetReg(), 0); 33769dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison MarkPossibleNullPointerException(opt_flags); 33869dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison} 33969dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison 340f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko/* 341f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko * Bit of a hack here - in the absence of a real scheduling pass, 342f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko * emit the next instruction in static & direct invoke sequences. 343f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko */ 344dc56cc509d8e1718ad321f7a91661dbe85ec8cefVladimir Markoint X86Mir2Lir::X86NextSDCallInsn(CompilationUnit* cu, CallInfo* info, 345dc56cc509d8e1718ad321f7a91661dbe85ec8cefVladimir Marko int state, const MethodReference& target_method, 346dc56cc509d8e1718ad321f7a91661dbe85ec8cefVladimir Marko uint32_t, 347848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao uintptr_t direct_code ATTRIBUTE_UNUSED, uintptr_t direct_method, 348dc56cc509d8e1718ad321f7a91661dbe85ec8cefVladimir Marko InvokeType type) { 349dc56cc509d8e1718ad321f7a91661dbe85ec8cefVladimir Marko X86Mir2Lir* cg = static_cast<X86Mir2Lir*>(cu->cg.get()); 350848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao if (info->string_init_offset != 0) { 351848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao RegStorage arg0_ref = cg->TargetReg(kArg0, kRef); 352848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao switch (state) { 353848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao case 0: { // Grab target method* from thread pointer 354848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao cg->NewLIR2(kX86Mov32RT, arg0_ref.GetReg(), info->string_init_offset); 355848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao break; 356848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao } 357848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao default: 358848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao return -1; 359848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao } 360848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao } else if (direct_method != 0) { 361f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko switch (state) { 362f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko case 0: // Get the current Method* [sets kArg0] 363f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko if (direct_method != static_cast<uintptr_t>(-1)) { 364921d6eb3c4e12a2000fe490c4e58d0e6e0628b90Mathieu Chartier auto target_reg = cg->TargetReg(kArg0, kRef); 365921d6eb3c4e12a2000fe490c4e58d0e6e0628b90Mathieu Chartier if (target_reg.Is64Bit()) { 366921d6eb3c4e12a2000fe490c4e58d0e6e0628b90Mathieu Chartier cg->LoadConstantWide(target_reg, direct_method); 367921d6eb3c4e12a2000fe490c4e58d0e6e0628b90Mathieu Chartier } else { 368921d6eb3c4e12a2000fe490c4e58d0e6e0628b90Mathieu Chartier cg->LoadConstant(target_reg, direct_method); 369921d6eb3c4e12a2000fe490c4e58d0e6e0628b90Mathieu Chartier } 370f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko } else { 371f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko cg->LoadMethodAddress(target_method, type, kArg0); 372f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko } 373f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko break; 374f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko default: 375f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko return -1; 376f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko } 377dc56cc509d8e1718ad321f7a91661dbe85ec8cefVladimir Marko } else if (cg->CanUseOpPcRelDexCacheArrayLoad()) { 378dc56cc509d8e1718ad321f7a91661dbe85ec8cefVladimir Marko switch (state) { 379dc56cc509d8e1718ad321f7a91661dbe85ec8cefVladimir Marko case 0: { 380dc56cc509d8e1718ad321f7a91661dbe85ec8cefVladimir Marko CHECK_EQ(cu->dex_file, target_method.dex_file); 381dc56cc509d8e1718ad321f7a91661dbe85ec8cefVladimir Marko size_t offset = cg->dex_cache_arrays_layout_.MethodOffset(target_method.dex_method_index); 3823d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier cg->OpPcRelDexCacheArrayLoad(cu->dex_file, offset, cg->TargetReg(kArg0, kRef), 3833d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier cu->target64); 384dc56cc509d8e1718ad321f7a91661dbe85ec8cefVladimir Marko break; 385dc56cc509d8e1718ad321f7a91661dbe85ec8cefVladimir Marko } 386dc56cc509d8e1718ad321f7a91661dbe85ec8cefVladimir Marko default: 387dc56cc509d8e1718ad321f7a91661dbe85ec8cefVladimir Marko return -1; 388dc56cc509d8e1718ad321f7a91661dbe85ec8cefVladimir Marko } 389f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko } else { 390f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko RegStorage arg0_ref = cg->TargetReg(kArg0, kRef); 391f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko switch (state) { 392f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko case 0: // Get the current Method* [sets kArg0] 393f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko // TUNING: we can save a reg copy if Method* has been promoted. 394f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko cg->LoadCurrMethodDirect(arg0_ref); 395f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko break; 396f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko case 1: // Get method->dex_cache_resolved_methods_ 397f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko cg->LoadRefDisp(arg0_ref, 3983d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier ArtMethod::DexCacheResolvedMethodsOffset().Int32Value(), 399f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko arg0_ref, 400f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko kNotVolatile); 401f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko break; 4023d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier case 2: { 4033d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier // Grab target method* 404f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko CHECK_EQ(cu->dex_file, target_method.dex_file); 4053d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier const size_t pointer_size = GetInstructionSetPointerSize(cu->instruction_set); 4063d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier cg->LoadWordDisp(arg0_ref, 4073d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier mirror::Array::DataOffset(pointer_size).Uint32Value() + 4083d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier target_method.dex_method_index * pointer_size, 4093d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier arg0_ref); 410f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko break; 4113d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier } 412f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko default: 413f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko return -1; 414f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko } 415f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko } 416f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko return state + 1; 417f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko} 418f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko 419f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir MarkoNextCallInsn X86Mir2Lir::GetNextSDCallInsn() { 420f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko return X86NextSDCallInsn; 421f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko} 422f4da675bbc4615c5f854c81964cac9dd1153baeaVladimir Marko 423efc6369224b036a1fb77849f7ae65b3492c832c0buzbee} // namespace art 424