utility_x86.cc revision 37f05ef45e0393de812d51261dc293240c17294d
1e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee/* 2e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * Copyright (C) 2012 The Android Open Source Project 3e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * 4e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * Licensed under the Apache License, Version 2.0 (the "License"); 5e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * you may not use this file except in compliance with the License. 6e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * You may obtain a copy of the License at 7e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * 8e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * http://www.apache.org/licenses/LICENSE-2.0 9e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * 10e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * Unless required by applicable law or agreed to in writing, software 11e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * distributed under the License is distributed on an "AS IS" BASIS, 12e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * See the License for the specific language governing permissions and 14e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * limitations under the License. 15e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee */ 16e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 1702031b185b4653e6c72e21f7a51238b903f6d638buzbee#include "codegen_x86.h" 187940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "dex/quick/mir_to_lir-inl.h" 1967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell#include "dex/dataflow_iterator-inl.h" 20641ce0371c2f0dc95d26be02d8366124c8b66653Brian Carlstrom#include "x86_lir.h" 217071c8d5885175a746723a3b38a347855965be08Yixin Shou#include "dex/quick/dex_file_method_inliner.h" 227071c8d5885175a746723a3b38a347855965be08Yixin Shou#include "dex/quick/dex_file_to_method_inliner_map.h" 23b5860fb459f1ed71f39d8a87b45bee6727d79fe8buzbee#include "dex/reg_storage_eq.h" 241bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee 25e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbeenamespace art { 26e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 27b046e16d8b8da318d6055f9308950131f1255e08buzbee/* This file contains codegen for the X86 ISA */ 28e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 292700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpFpRegCopy(RegStorage r_dest, RegStorage r_src) { 30a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int opcode; 31a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* must be both DOUBLE or both not DOUBLE */ 32091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK(r_dest.IsFloat() || r_src.IsFloat()); 33091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK_EQ(r_dest.IsDouble(), r_src.IsDouble()); 34091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (r_dest.IsDouble()) { 35a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kX86MovsdRR; 36a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 37091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (r_dest.IsSingle()) { 38091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (r_src.IsSingle()) { 39a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kX86MovssRR; 40a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { // Fpr <- Gpr 41a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kX86MovdxrRR; 42a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 43a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { // Gpr <- Fpr 44091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK(r_src.IsSingle()) << "Raw: 0x" << std::hex << r_src.GetRawBits(); 45a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kX86MovdrxRR; 46e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 47a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 48ec13743da80a80c1817cf6660c28917fc28846bcbuzbee DCHECK_NE((EncodingMap[opcode].flags & IS_BINARY_OP), 0ULL); 492700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee LIR* res = RawLIR(current_dalvik_offset_, opcode, r_dest.GetReg(), r_src.GetReg()); 50fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (r_dest == r_src) { 51fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee res->flags.is_nop = true; 52a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 53a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return res; 54e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 55e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 562ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool X86Mir2Lir::InexpensiveConstantInt(int32_t value) { 57e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee return true; 58e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee} 59e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee 602ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool X86Mir2Lir::InexpensiveConstantFloat(int32_t value) { 614ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee return false; 624ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee} 634ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee 642ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool X86Mir2Lir::InexpensiveConstantLong(int64_t value) { 654ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee return true; 664ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee} 674ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee 682ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool X86Mir2Lir::InexpensiveConstantDouble(int64_t value) { 6967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell return value == 0; 704ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee} 714ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee 72e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee/* 73e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * Load a immediate using a shortcut if possible; otherwise 74e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * grab from the per-translation literal pool. If target is 75e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * a high register, build constant into a low register and copy. 76e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * 77e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * No additional register clobbering operation performed. Use this version when 78fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee * 1) r_dest is freshly returned from AllocTemp or 79e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * 2) The codegen is under fixed register usage 80e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee */ 812700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::LoadConstantNoClobber(RegStorage r_dest, int value) { 822700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee RegStorage r_dest_save = r_dest; 83091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (r_dest.IsFloat()) { 84b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers if (value == 0) { 852700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return NewLIR2(kX86XorpsRR, r_dest.GetReg(), r_dest.GetReg()); 86b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 871fd3346740dfb7f47be9922312b68a4227fada96buzbee r_dest = AllocTemp(); 886cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers } 89e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 90b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers LIR *res; 916cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers if (value == 0) { 922700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee res = NewLIR2(kX86Xor32RR, r_dest.GetReg(), r_dest.GetReg()); 936cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers } else { 942e9f7ed8d00271cb1cf082d68b4f4bc60702d6ecIan Rogers // Note, there is no byte immediate form of a 32 bit immediate move. 95e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu // 64-bit immediate is not supported by LIR structure 96e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu res = NewLIR2(kX86Mov32RI, r_dest.GetReg(), value); 976cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers } 98e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 99091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (r_dest_save.IsFloat()) { 1002700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee NewLIR2(kX86MovdxrRR, r_dest_save.GetReg(), r_dest.GetReg()); 1011fd3346740dfb7f47be9922312b68a4227fada96buzbee FreeTemp(r_dest); 1026cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers } 103e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 1046cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers return res; 105e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 106e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 1072ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* X86Mir2Lir::OpUnconditionalBranch(LIR* target) { 108df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom LIR* res = NewLIR1(kX86Jmp8, 0 /* offset to be patched during assembly*/); 10902031b185b4653e6c72e21f7a51238b903f6d638buzbee res->target = target; 11002031b185b4653e6c72e21f7a51238b903f6d638buzbee return res; 111e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 112e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 1132ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* X86Mir2Lir::OpCondBranch(ConditionCode cc, LIR* target) { 1141fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* branch = NewLIR2(kX86Jcc8, 0 /* offset to be patched */, 11552a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee X86ConditionEncoding(cc)); 116b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers branch->target = target; 117b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers return branch; 118a7678db092ac6bb79f7cad490099a1015fbbc714buzbee} 119a7678db092ac6bb79f7cad490099a1015fbbc714buzbee 1202700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpReg(OpKind op, RegStorage r_dest_src) { 121b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers X86OpCode opcode = kX86Bkpt; 122b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers switch (op) { 123e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpNeg: opcode = r_dest_src.Is64Bit() ? kX86Neg64R : kX86Neg32R; break; 124e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpNot: opcode = r_dest_src.Is64Bit() ? kX86Not64R : kX86Not32R; break; 125c5e4ce116e4d44bfdf162f0c949e77772d7e0654nikolay serdjuk case kOpRev: opcode = r_dest_src.Is64Bit() ? kX86Bswap64R : kX86Bswap32R; break; 126b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpBlx: opcode = kX86CallR; break; 127b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers default: 12852a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee LOG(FATAL) << "Bad case in OpReg " << op; 129b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 1302700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return NewLIR1(opcode, r_dest_src.GetReg()); 131e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 132e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 1332700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpRegImm(OpKind op, RegStorage r_dest_src1, int value) { 134b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers X86OpCode opcode = kX86Bkpt; 135fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bool byte_imm = IS_SIMM8(value); 136091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK(!r_dest_src1.IsFloat()); 1379ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko if (r_dest_src1.Is64Bit()) { 1389ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko switch (op) { 1399ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko case kOpAdd: opcode = byte_imm ? kX86Add64RI8 : kX86Add64RI; break; 1409ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko case kOpSub: opcode = byte_imm ? kX86Sub64RI8 : kX86Sub64RI; break; 141e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpLsl: opcode = kX86Sal64RI; break; 142e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpLsr: opcode = kX86Shr64RI; break; 143e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpAsr: opcode = kX86Sar64RI; break; 1447e399fd3a99ba9c9dbfafdf14f75dd318fa7d454Chao-ying Fu case kOpCmp: opcode = byte_imm ? kX86Cmp64RI8 : kX86Cmp64RI; break; 1459ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko default: 1469ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko LOG(FATAL) << "Bad case in OpRegImm (64-bit) " << op; 1479ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko } 1489ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko } else { 1499ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko switch (op) { 1509ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko case kOpLsl: opcode = kX86Sal32RI; break; 1519ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko case kOpLsr: opcode = kX86Shr32RI; break; 1529ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko case kOpAsr: opcode = kX86Sar32RI; break; 1539ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko case kOpAdd: opcode = byte_imm ? kX86Add32RI8 : kX86Add32RI; break; 1549ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko case kOpOr: opcode = byte_imm ? kX86Or32RI8 : kX86Or32RI; break; 1559ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko case kOpAdc: opcode = byte_imm ? kX86Adc32RI8 : kX86Adc32RI; break; 1569ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko // case kOpSbb: opcode = kX86Sbb32RI; break; 1579ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko case kOpAnd: opcode = byte_imm ? kX86And32RI8 : kX86And32RI; break; 1589ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko case kOpSub: opcode = byte_imm ? kX86Sub32RI8 : kX86Sub32RI; break; 1599ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko case kOpXor: opcode = byte_imm ? kX86Xor32RI8 : kX86Xor32RI; break; 1609ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko case kOpCmp: opcode = byte_imm ? kX86Cmp32RI8 : kX86Cmp32RI; break; 1619ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko case kOpMov: 1629ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko /* 1639ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko * Moving the constant zero into register can be specialized as an xor of the register. 1649ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko * However, that sets eflags while the move does not. For that reason here, always do 1659ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko * the move and if caller is flexible, they should be calling LoadConstantNoClobber instead. 1669ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko */ 1679ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko opcode = kX86Mov32RI; 1689ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko break; 1699ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko case kOpMul: 1709ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko opcode = byte_imm ? kX86Imul32RRI8 : kX86Imul32RRI; 1719ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko return NewLIR3(opcode, r_dest_src1.GetReg(), r_dest_src1.GetReg(), value); 172e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell case kOp2Byte: 173e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell opcode = kX86Mov32RI; 174e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell value = static_cast<int8_t>(value); 175e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell break; 176e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell case kOp2Short: 177e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell opcode = kX86Mov32RI; 178e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell value = static_cast<int16_t>(value); 179e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell break; 180e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell case kOp2Char: 181e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell opcode = kX86Mov32RI; 182e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell value = static_cast<uint16_t>(value); 183e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell break; 184e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell case kOpNeg: 185e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell opcode = kX86Mov32RI; 186e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell value = -value; 187e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell break; 1889ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko default: 1899ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko LOG(FATAL) << "Bad case in OpRegImm " << op; 1909ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko } 191b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 1922700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return NewLIR2(opcode, r_dest_src1.GetReg(), value); 193e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 194e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 1952700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpRegReg(OpKind op, RegStorage r_dest_src1, RegStorage r_src2) { 196e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu bool is64Bit = r_dest_src1.Is64Bit(); 197a7678db092ac6bb79f7cad490099a1015fbbc714buzbee X86OpCode opcode = kX86Nop; 198d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers bool src2_must_be_cx = false; 199e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee switch (op) { 200b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers // X86 unary opcodes 201b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpMvn: 2021fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegCopy(r_dest_src1, r_src2); 2031fd3346740dfb7f47be9922312b68a4227fada96buzbee return OpReg(kOpNot, r_dest_src1); 204b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpNeg: 2051fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegCopy(r_dest_src1, r_src2); 2061fd3346740dfb7f47be9922312b68a4227fada96buzbee return OpReg(kOpNeg, r_dest_src1); 207a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko case kOpRev: 208a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko OpRegCopy(r_dest_src1, r_src2); 209a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko return OpReg(kOpRev, r_dest_src1); 210a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko case kOpRevsh: 211a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko OpRegCopy(r_dest_src1, r_src2); 212a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko OpReg(kOpRev, r_dest_src1); 213a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko return OpRegImm(kOpAsr, r_dest_src1, 16); 214b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers // X86 binary opcodes 215e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpSub: opcode = is64Bit ? kX86Sub64RR : kX86Sub32RR; break; 216e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpSbc: opcode = is64Bit ? kX86Sbb64RR : kX86Sbb32RR; break; 217e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpLsl: opcode = is64Bit ? kX86Sal64RC : kX86Sal32RC; src2_must_be_cx = true; break; 218e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpLsr: opcode = is64Bit ? kX86Shr64RC : kX86Shr32RC; src2_must_be_cx = true; break; 219e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpAsr: opcode = is64Bit ? kX86Sar64RC : kX86Sar32RC; src2_must_be_cx = true; break; 220e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpMov: opcode = is64Bit ? kX86Mov64RR : kX86Mov32RR; break; 221e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpCmp: opcode = is64Bit ? kX86Cmp64RR : kX86Cmp32RR; break; 222e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpAdd: opcode = is64Bit ? kX86Add64RR : kX86Add32RR; break; 223e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpAdc: opcode = is64Bit ? kX86Adc64RR : kX86Adc32RR; break; 224e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpAnd: opcode = is64Bit ? kX86And64RR : kX86And32RR; break; 225e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpOr: opcode = is64Bit ? kX86Or64RR : kX86Or32RR; break; 226e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpXor: opcode = is64Bit ? kX86Xor64RR : kX86Xor32RR; break; 227703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao case kOp2Byte: 228091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee // TODO: there are several instances of this check. A utility function perhaps? 229091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee // TODO: Similar to Arm's reg < 8 check. Perhaps add attribute checks to RegStorage? 230703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao // Use shifts instead of a byte operand if the source can't be byte accessed. 231091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (r_src2.GetRegNum() >= rs_rX86_SP.GetRegNum()) { 232e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu NewLIR2(is64Bit ? kX86Mov64RR : kX86Mov32RR, r_dest_src1.GetReg(), r_src2.GetReg()); 233e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu NewLIR2(is64Bit ? kX86Sal64RI : kX86Sal32RI, r_dest_src1.GetReg(), is64Bit ? 56 : 24); 234e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu return NewLIR2(is64Bit ? kX86Sar64RI : kX86Sar32RI, r_dest_src1.GetReg(), 235e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu is64Bit ? 56 : 24); 236703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao } else { 237e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu opcode = is64Bit ? kX86Bkpt : kX86Movsx8RR; 238703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao } 239703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao break; 240e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOp2Short: opcode = is64Bit ? kX86Bkpt : kX86Movsx16RR; break; 241e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOp2Char: opcode = is64Bit ? kX86Bkpt : kX86Movzx16RR; break; 242e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpMul: opcode = is64Bit ? kX86Bkpt : kX86Imul32RR; break; 243b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers default: 24452a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee LOG(FATAL) << "Bad case in OpRegReg " << op; 245b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 246e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 247091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(!src2_must_be_cx || r_src2.GetReg() == rs_rCX.GetReg()); 2482700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return NewLIR2(opcode, r_dest_src1.GetReg(), r_src2.GetReg()); 249e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 250e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 2512700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpMovRegMem(RegStorage r_dest, RegStorage r_base, int offset, MoveType move_type) { 252091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK(!r_base.IsFloat()); 2532c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru X86OpCode opcode = kX86Nop; 2542700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee int dest = r_dest.IsPair() ? r_dest.GetLowReg() : r_dest.GetReg(); 2552c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru switch (move_type) { 2562c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMov8GP: 257091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(!r_dest.IsFloat()); 2582c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86Mov8RM; 2592c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 2602c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMov16GP: 261091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(!r_dest.IsFloat()); 2622c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86Mov16RM; 2632c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 2642c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMov32GP: 265091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(!r_dest.IsFloat()); 2662c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86Mov32RM; 2672c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 2682c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMov32FP: 269091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(r_dest.IsFloat()); 2702c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86MovssRM; 2712c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 2722c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMov64FP: 273091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(r_dest.IsFloat()); 2742c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86MovsdRM; 2752c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 2762c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMovU128FP: 277091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(r_dest.IsFloat()); 2782c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86MovupsRM; 2792c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 2802c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMovA128FP: 281091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(r_dest.IsFloat()); 2822c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86MovapsRM; 2832c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 2842c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMovLo128FP: 285091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(r_dest.IsFloat()); 2862c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86MovlpsRM; 2872c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 2882c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMovHi128FP: 289091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(r_dest.IsFloat()); 2902c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86MovhpsRM; 2912c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 2922c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMov64GP: 2932c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMovLo64FP: 2942c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMovHi64FP: 2952c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru default: 2962c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru LOG(FATAL) << "Bad case in OpMovRegMem"; 2972c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 2982c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru } 2992c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru 3002700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return NewLIR3(opcode, dest, r_base.GetReg(), offset); 3012c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru} 3022c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru 3032700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpMovMemReg(RegStorage r_base, int offset, RegStorage r_src, MoveType move_type) { 304091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK(!r_base.IsFloat()); 3052700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee int src = r_src.IsPair() ? r_src.GetLowReg() : r_src.GetReg(); 3062c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru 3072c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru X86OpCode opcode = kX86Nop; 3082c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru switch (move_type) { 3092c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMov8GP: 310091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(!r_src.IsFloat()); 3112c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86Mov8MR; 3122c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 3132c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMov16GP: 314091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(!r_src.IsFloat()); 3152c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86Mov16MR; 3162c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 3172c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMov32GP: 318091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(!r_src.IsFloat()); 3192c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86Mov32MR; 3202c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 3212c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMov32FP: 322091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(r_src.IsFloat()); 3232c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86MovssMR; 3242c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 3252c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMov64FP: 326091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(r_src.IsFloat()); 3272c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86MovsdMR; 3282c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 3292c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMovU128FP: 330091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(r_src.IsFloat()); 3312c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86MovupsMR; 3322c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 3332c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMovA128FP: 334091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(r_src.IsFloat()); 3352c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86MovapsMR; 3362c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 3372c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMovLo128FP: 338091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(r_src.IsFloat()); 3392c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86MovlpsMR; 3402c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 3412c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMovHi128FP: 342091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(r_src.IsFloat()); 3432c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86MovhpsMR; 3442c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 3452c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMov64GP: 3462c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMovLo64FP: 3472c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMovHi64FP: 3482c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru default: 3492c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru LOG(FATAL) << "Bad case in OpMovMemReg"; 3502c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 3512c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru } 3522c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru 3532700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return NewLIR3(opcode, r_base.GetReg(), offset, src); 3542c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru} 3552c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru 3562700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpCondRegReg(OpKind op, ConditionCode cc, RegStorage r_dest, RegStorage r_src) { 357bd288c2c1206bc99fafebfb9120a83f13cf9723bRazvan A Lupusoru // The only conditional reg to reg operation supported is Cmov 358bd288c2c1206bc99fafebfb9120a83f13cf9723bRazvan A Lupusoru DCHECK_EQ(op, kOpCmov); 359c5e4ce116e4d44bfdf162f0c949e77772d7e0654nikolay serdjuk DCHECK_EQ(r_dest.Is64Bit(), r_src.Is64Bit()); 360c5e4ce116e4d44bfdf162f0c949e77772d7e0654nikolay serdjuk return NewLIR3(r_dest.Is64Bit() ? kX86Cmov64RRC : kX86Cmov32RRC, r_dest.GetReg(), 361c5e4ce116e4d44bfdf162f0c949e77772d7e0654nikolay serdjuk r_src.GetReg(), X86ConditionEncoding(cc)); 362bd288c2c1206bc99fafebfb9120a83f13cf9723bRazvan A Lupusoru} 363bd288c2c1206bc99fafebfb9120a83f13cf9723bRazvan A Lupusoru 3642700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpRegMem(OpKind op, RegStorage r_dest, RegStorage r_base, int offset) { 365e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu bool is64Bit = r_dest.Is64Bit(); 366b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers X86OpCode opcode = kX86Nop; 367b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers switch (op) { 368b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers // X86 binary opcodes 369e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpSub: opcode = is64Bit ? kX86Sub64RM : kX86Sub32RM; break; 370e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpMov: opcode = is64Bit ? kX86Mov64RM : kX86Mov32RM; break; 371e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpCmp: opcode = is64Bit ? kX86Cmp64RM : kX86Cmp32RM; break; 372e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpAdd: opcode = is64Bit ? kX86Add64RM : kX86Add32RM; break; 373e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpAnd: opcode = is64Bit ? kX86And64RM : kX86And32RM; break; 374e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpOr: opcode = is64Bit ? kX86Or64RM : kX86Or32RM; break; 375e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpXor: opcode = is64Bit ? kX86Xor64RM : kX86Xor32RM; break; 376b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOp2Byte: opcode = kX86Movsx8RM; break; 377b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOp2Short: opcode = kX86Movsx16RM; break; 378b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOp2Char: opcode = kX86Movzx16RM; break; 379b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpMul: 380b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers default: 38152a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee LOG(FATAL) << "Bad case in OpRegMem " << op; 382b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 383b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 3842700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee LIR *l = NewLIR3(opcode, r_dest.GetReg(), r_base.GetReg(), offset); 3858dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko if (mem_ref_type_ == ResourceMask::kDalvikReg) { 3868dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko DCHECK(r_base == rs_rX86_SP); 387feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell AnnotateDalvikRegAccess(l, offset >> 2, true /* is_load */, false /* is_64bit */); 388feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell } 389feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell return l; 390feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell} 391feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell 392feb2b4e2d1c6538777bb80b60f3a247537b6221dMark MendellLIR* X86Mir2Lir::OpMemReg(OpKind op, RegLocation rl_dest, int r_value) { 393feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell DCHECK_NE(rl_dest.location, kLocPhysReg); 394feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell int displacement = SRegOffset(rl_dest.s_reg_low); 395e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu bool is64Bit = rl_dest.wide != 0; 396feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell X86OpCode opcode = kX86Nop; 397feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell switch (op) { 398e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpSub: opcode = is64Bit ? kX86Sub64MR : kX86Sub32MR; break; 399e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpMov: opcode = is64Bit ? kX86Mov64MR : kX86Mov32MR; break; 400e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpCmp: opcode = is64Bit ? kX86Cmp64MR : kX86Cmp32MR; break; 401e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpAdd: opcode = is64Bit ? kX86Add64MR : kX86Add32MR; break; 402e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpAnd: opcode = is64Bit ? kX86And64MR : kX86And32MR; break; 403e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpOr: opcode = is64Bit ? kX86Or64MR : kX86Or32MR; break; 404e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpXor: opcode = is64Bit ? kX86Xor64MR : kX86Xor32MR; break; 405e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpLsl: opcode = is64Bit ? kX86Sal64MC : kX86Sal32MC; break; 406e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpLsr: opcode = is64Bit ? kX86Shr64MC : kX86Shr32MC; break; 407e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpAsr: opcode = is64Bit ? kX86Sar64MC : kX86Sar32MC; break; 408feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell default: 409feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell LOG(FATAL) << "Bad case in OpMemReg " << op; 410feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell break; 411feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell } 412091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee LIR *l = NewLIR3(opcode, rs_rX86_SP.GetReg(), displacement, r_value); 4138dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko if (mem_ref_type_ == ResourceMask::kDalvikReg) { 4148dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko AnnotateDalvikRegAccess(l, displacement >> 2, true /* is_load */, is64Bit /* is_64bit */); 4158dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko AnnotateDalvikRegAccess(l, displacement >> 2, false /* is_load */, is64Bit /* is_64bit */); 4168dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko } 417feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell return l; 418feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell} 419feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell 4202700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpRegMem(OpKind op, RegStorage r_dest, RegLocation rl_value) { 421feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell DCHECK_NE(rl_value.location, kLocPhysReg); 422e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu bool is64Bit = r_dest.Is64Bit(); 423feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell int displacement = SRegOffset(rl_value.s_reg_low); 424feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell X86OpCode opcode = kX86Nop; 425feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell switch (op) { 426e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpSub: opcode = is64Bit ? kX86Sub64RM : kX86Sub32RM; break; 427e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpMov: opcode = is64Bit ? kX86Mov64RM : kX86Mov32RM; break; 428e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpCmp: opcode = is64Bit ? kX86Cmp64RM : kX86Cmp32RM; break; 429e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpAdd: opcode = is64Bit ? kX86Add64RM : kX86Add32RM; break; 430e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpAnd: opcode = is64Bit ? kX86And64RM : kX86And32RM; break; 431e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpOr: opcode = is64Bit ? kX86Or64RM : kX86Or32RM; break; 432e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpXor: opcode = is64Bit ? kX86Xor64RM : kX86Xor32RM; break; 433e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpMul: opcode = is64Bit ? kX86Bkpt : kX86Imul32RM; break; 434feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell default: 435feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell LOG(FATAL) << "Bad case in OpRegMem " << op; 436feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell break; 437feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell } 438091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee LIR *l = NewLIR3(opcode, r_dest.GetReg(), rs_rX86_SP.GetReg(), displacement); 4398dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko if (mem_ref_type_ == ResourceMask::kDalvikReg) { 4408dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko AnnotateDalvikRegAccess(l, displacement >> 2, true /* is_load */, is64Bit /* is_64bit */); 4418dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko } 442feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell return l; 443b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers} 444e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 4452700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpRegRegReg(OpKind op, RegStorage r_dest, RegStorage r_src1, 4462700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee RegStorage r_src2) { 447e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu bool is64Bit = r_dest.Is64Bit(); 448fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (r_dest != r_src1 && r_dest != r_src2) { 4497934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom if (op == kOpAdd) { // lea special case, except can't encode rbp as base 450fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (r_src1 == r_src2) { 4511fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegCopy(r_dest, r_src1); 4521fd3346740dfb7f47be9922312b68a4227fada96buzbee return OpRegImm(kOpLsl, r_dest, 1); 4532700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee } else if (r_src1 != rs_rBP) { 454e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu return NewLIR5(is64Bit ? kX86Lea64RA : kX86Lea32RA, r_dest.GetReg(), 455e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu r_src1.GetReg() /* base */, r_src2.GetReg() /* index */, 456e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu 0 /* scale */, 0 /* disp */); 457b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 458e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu return NewLIR5(is64Bit ? kX86Lea64RA : kX86Lea32RA, r_dest.GetReg(), 459e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu r_src2.GetReg() /* base */, r_src1.GetReg() /* index */, 460e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu 0 /* scale */, 0 /* disp */); 461b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 462b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 4631fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegCopy(r_dest, r_src1); 4641fd3346740dfb7f47be9922312b68a4227fada96buzbee return OpRegReg(op, r_dest, r_src2); 465e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 466fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee } else if (r_dest == r_src1) { 4671fd3346740dfb7f47be9922312b68a4227fada96buzbee return OpRegReg(op, r_dest, r_src2); 468fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee } else { // r_dest == r_src2 469b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers switch (op) { 470b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpSub: // non-commutative 4711fd3346740dfb7f47be9922312b68a4227fada96buzbee OpReg(kOpNeg, r_dest); 472b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers op = kOpAdd; 473b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 474b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpSbc: 475b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpLsl: case kOpLsr: case kOpAsr: case kOpRor: { 4762700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee RegStorage t_reg = AllocTemp(); 4771fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegCopy(t_reg, r_src1); 4781fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegReg(op, t_reg, r_src2); 4797a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee LIR* res = OpRegCopyNoInsert(r_dest, t_reg); 4807a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee AppendLIR(res); 4811fd3346740dfb7f47be9922312b68a4227fada96buzbee FreeTemp(t_reg); 482b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers return res; 483b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 484b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpAdd: // commutative 485b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpOr: 486b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpAdc: 487b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpAnd: 488b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpXor: 489b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 490b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers default: 49152a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee LOG(FATAL) << "Bad case in OpRegRegReg " << op; 492e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 4931fd3346740dfb7f47be9922312b68a4227fada96buzbee return OpRegReg(op, r_dest, r_src1); 494b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 495e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 496e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 4972700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpRegRegImm(OpKind op, RegStorage r_dest, RegStorage r_src, int value) { 498dd64450b37776f68b9bfc47f8d9a88bc72c95727Elena Sayapina if (op == kOpMul && !cu_->target64) { 499b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers X86OpCode opcode = IS_SIMM8(value) ? kX86Imul32RRI8 : kX86Imul32RRI; 5002700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return NewLIR3(opcode, r_dest.GetReg(), r_src.GetReg(), value); 501dd64450b37776f68b9bfc47f8d9a88bc72c95727Elena Sayapina } else if (op == kOpAnd && !cu_->target64) { 502091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (value == 0xFF && r_src.Low4()) { 5032700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return NewLIR2(kX86Movzx8RR, r_dest.GetReg(), r_src.GetReg()); 504b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } else if (value == 0xFFFF) { 5052700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return NewLIR2(kX86Movzx16RR, r_dest.GetReg(), r_src.GetReg()); 506b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 507b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 508fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (r_dest != r_src) { 5097934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom if (false && op == kOpLsl && value >= 0 && value <= 3) { // lea shift special case 5107caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers // TODO: fix bug in LEA encoding when disp == 0 5112700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return NewLIR5(kX86Lea32RA, r_dest.GetReg(), r5sib_no_base /* base */, 5122700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee r_src.GetReg() /* index */, value /* scale */, 0 /* disp */); 5137934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom } else if (op == kOpAdd) { // lea add special case 5147e399fd3a99ba9c9dbfafdf14f75dd318fa7d454Chao-ying Fu return NewLIR5(r_dest.Is64Bit() ? kX86Lea64RA : kX86Lea32RA, r_dest.GetReg(), 515e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu r_src.GetReg() /* base */, rs_rX86_SP.GetReg()/*r4sib_no_index*/ /* index */, 516e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu 0 /* scale */, value /* disp */); 517e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 5181fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegCopy(r_dest, r_src); 519b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 5201fd3346740dfb7f47be9922312b68a4227fada96buzbee return OpRegImm(op, r_dest, value); 521e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 522e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 523dd7624d2b9e599d57762d12031b10b89defc9807Ian RogersLIR* X86Mir2Lir::OpThreadMem(OpKind op, ThreadOffset<4> thread_offset) { 5242f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe DCHECK_EQ(kX86, cu_->instruction_set); 5252f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe X86OpCode opcode = kX86Bkpt; 5262f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe switch (op) { 5272f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe case kOpBlx: opcode = kX86CallT; break; 5282f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe case kOpBx: opcode = kX86JmpT; break; 5292f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe default: 5302f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe LOG(FATAL) << "Bad opcode: " << op; 5312f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe break; 5322f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe } 5332f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe return NewLIR1(opcode, thread_offset.Int32Value()); 5342f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe} 5352f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe 5362f244e9faccfcca68af3c5484c397a01a1c3a342Andreas GampeLIR* X86Mir2Lir::OpThreadMem(OpKind op, ThreadOffset<8> thread_offset) { 5372f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe DCHECK_EQ(kX86_64, cu_->instruction_set); 5386cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers X86OpCode opcode = kX86Bkpt; 5396cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers switch (op) { 5406cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers case kOpBlx: opcode = kX86CallT; break; 54160d7a65f7fb60f502160a2e479e86014c7787553Brian Carlstrom case kOpBx: opcode = kX86JmpT; break; 5426cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers default: 5436cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers LOG(FATAL) << "Bad opcode: " << op; 5446cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers break; 5456cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers } 546468532ea115657709bc32ee498e701a4c71762d4Ian Rogers return NewLIR1(opcode, thread_offset.Int32Value()); 5476cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers} 5486cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers 5492700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpMem(OpKind op, RegStorage r_base, int disp) { 5506cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers X86OpCode opcode = kX86Bkpt; 5516cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers switch (op) { 5526cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers case kOpBlx: opcode = kX86CallM; break; 5536cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers default: 5546cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers LOG(FATAL) << "Bad opcode: " << op; 5556cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers break; 5566cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers } 5572700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return NewLIR2(opcode, r_base.GetReg(), disp); 5586cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers} 5596cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers 5602700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::LoadConstantWide(RegStorage r_dest, int64_t value) { 5614ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee int32_t val_lo = Low32Bits(value); 5624ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee int32_t val_hi = High32Bits(value); 5632700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee int32_t low_reg_val = r_dest.IsPair() ? r_dest.GetLowReg() : r_dest.GetReg(); 564e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee LIR *res; 565e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell bool is_fp = r_dest.IsFloat(); 5662700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee // TODO: clean this up once we fully recognize 64-bit storage containers. 5672700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee if (is_fp) { 5680e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov DCHECK(r_dest.IsDouble()); 5694ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (value == 0) { 5702700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return NewLIR2(kX86XorpsRR, low_reg_val, low_reg_val); 57167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } else if (base_of_code_ != nullptr) { 57267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // We will load the value from the literal area. 57367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell LIR* data_target = ScanLiteralPoolWide(literal_list_, val_lo, val_hi); 57467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell if (data_target == NULL) { 57567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell data_target = AddWideData(&literal_list_, val_lo, val_hi); 57667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } 57767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell 57867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // Address the start of the method 57967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell RegLocation rl_method = mir_graph_->GetRegLocation(base_of_code_->s_reg_low); 580e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu if (rl_method.wide) { 581e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu rl_method = LoadValueWide(rl_method, kCoreReg); 582e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu } else { 583e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu rl_method = LoadValue(rl_method, kCoreReg); 584e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu } 58567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell 58667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // Load the proper value from the literal area. 58767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // We don't know the proper offset for the value, so pick one that will force 58867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // 4 byte offset. We will fix this up in the assembler later to have the right 58967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // value. 5908dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko ScopedMemRefType mem_ref_type(this, ResourceMask::kLiteral); 5910c52451e9be14a6bff9ffefce89ff1d60691af60Mark Mendell res = LoadBaseDisp(rl_method.reg, 256 /* bogus */, RegStorage::FloatSolo64(low_reg_val), 5923c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe kDouble, kNotVolatile); 59367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell res->target = data_target; 59467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell res->flags.fixup = kFixupLoad; 59554659e3a2c83d3949957a10436e55e525a430a15Alexei Zavjalov Clobber(rl_method.reg); 59655d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell store_method_addr_used_ = true; 597b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } else { 5980e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov if (r_dest.IsPair()) { 5990e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov if (val_lo == 0) { 6000e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov res = NewLIR2(kX86XorpsRR, low_reg_val, low_reg_val); 6010e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov } else { 6020e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov res = LoadConstantNoClobber(RegStorage::FloatSolo32(low_reg_val), val_lo); 6030e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov } 6040e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov if (val_hi != 0) { 6050e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov RegStorage r_dest_hi = AllocTempDouble(); 6060e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov LoadConstantNoClobber(r_dest_hi, val_hi); 6070e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov NewLIR2(kX86PunpckldqRR, low_reg_val, r_dest_hi.GetReg()); 6080e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov FreeTemp(r_dest_hi); 6090e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov } 610b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } else { 6110e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov RegStorage r_temp = AllocTypedTempWide(false, kCoreReg); 6120e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov res = LoadConstantWide(r_temp, value); 6130e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov OpRegCopyWide(r_dest, r_temp); 6140e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov FreeTemp(r_temp); 615b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 616b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 617b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } else { 618e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu if (r_dest.IsPair()) { 619e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu res = LoadConstantNoClobber(r_dest.GetLow(), val_lo); 620e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu LoadConstantNoClobber(r_dest.GetHigh(), val_hi); 621e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu } else { 6225192cbb12856b12620dc346758605baaa1469cedYixin Shou if (value == 0) { 6231c55703526827b5fc63f5d4b8477f36574649342Serguei Katkov res = NewLIR2(kX86Xor64RR, r_dest.GetReg(), r_dest.GetReg()); 6245192cbb12856b12620dc346758605baaa1469cedYixin Shou } else if (value >= INT_MIN && value <= INT_MAX) { 6255192cbb12856b12620dc346758605baaa1469cedYixin Shou res = NewLIR2(kX86Mov64RI32, r_dest.GetReg(), val_lo); 6265192cbb12856b12620dc346758605baaa1469cedYixin Shou } else { 6275192cbb12856b12620dc346758605baaa1469cedYixin Shou res = NewLIR3(kX86Mov64RI64, r_dest.GetReg(), val_hi, val_lo); 628e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu } 629e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu } 630b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 631e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee return res; 632e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 633e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 6342700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::LoadBaseIndexedDisp(RegStorage r_base, RegStorage r_index, int scale, 6353bf7c60a86d49bf8c05c5d2ac5ca8e9f80bd9824Vladimir Marko int displacement, RegStorage r_dest, OpSize size) { 636b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers LIR *load = NULL; 637b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers LIR *load2 = NULL; 6382700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee bool is_array = r_index.Valid(); 639091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee bool pair = r_dest.IsPair(); 640091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee bool is64bit = ((size == k64) || (size == kDouble)); 641b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers X86OpCode opcode = kX86Nop; 642b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers switch (size) { 643695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee case k64: 644b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kDouble: 645091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (r_dest.IsFloat()) { 646fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86MovsdRA : kX86MovsdRM; 647e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu } else if (!pair) { 648e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu opcode = is_array ? kX86Mov64RA : kX86Mov64RM; 649b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 650fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Mov32RA : kX86Mov32RM; 651b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 652b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers // TODO: double store is to unaligned address 653b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ((displacement & 0x3), 0); 654b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 6559ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko case kWord: 656dd64450b37776f68b9bfc47f8d9a88bc72c95727Elena Sayapina if (cu_->target64) { 6579ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko opcode = is_array ? kX86Mov64RA : kX86Mov64RM; 6589ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko CHECK_EQ(is_array, false); 6599ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko CHECK_EQ(r_dest.IsFloat(), false); 6609ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko break; 6619ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko } // else fall-through to k32 case 662695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee case k32: 663b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kSingle: 664695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee case kReference: // TODO: update for reference decompression on 64-bit targets. 665fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Mov32RA : kX86Mov32RM; 666091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (r_dest.IsFloat()) { 667fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86MovssRA : kX86MovssRM; 668091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK(r_dest.IsFloat()); 669b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 670b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ((displacement & 0x3), 0); 671b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 672b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kUnsignedHalf: 673fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Movzx16RA : kX86Movzx16RM; 674b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ((displacement & 0x1), 0); 675b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 676b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kSignedHalf: 677fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Movsx16RA : kX86Movsx16RM; 678b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ((displacement & 0x1), 0); 679b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 680b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kUnsignedByte: 681fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Movzx8RA : kX86Movzx8RM; 682b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 683b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kSignedByte: 684fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Movsx8RA : kX86Movsx8RM; 685b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 686b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers default: 68752a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee LOG(FATAL) << "Bad case in LoadBaseIndexedDispBody"; 688b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 689b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 690fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (!is_array) { 691b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers if (!pair) { 6922700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee load = NewLIR3(opcode, r_dest.GetReg(), r_base.GetReg(), displacement + LOWORD_OFFSET); 693e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } else { 694091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK(!r_dest.IsFloat()); // Make sure we're not still using a pair here. 695091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (r_base == r_dest.GetLow()) { 69669dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison load = NewLIR3(opcode, r_dest.GetHighReg(), r_base.GetReg(), 697fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao displacement + HIWORD_OFFSET); 69869dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison load2 = NewLIR3(opcode, r_dest.GetLowReg(), r_base.GetReg(), displacement + LOWORD_OFFSET); 699fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao } else { 700091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee load = NewLIR3(opcode, r_dest.GetLowReg(), r_base.GetReg(), displacement + LOWORD_OFFSET); 701091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee load2 = NewLIR3(opcode, r_dest.GetHighReg(), r_base.GetReg(), 702fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao displacement + HIWORD_OFFSET); 703fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao } 704e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 7058dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko if (mem_ref_type_ == ResourceMask::kDalvikReg) { 7068dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko DCHECK(r_base == rs_rX86_SP); 7071fd3346740dfb7f47be9922312b68a4227fada96buzbee AnnotateDalvikRegAccess(load, (displacement + (pair ? LOWORD_OFFSET : 0)) >> 2, 70802031b185b4653e6c72e21f7a51238b903f6d638buzbee true /* is_load */, is64bit); 709f7d9ad39541dd09030e26d54d3b73a076f90cc74Ian Rogers if (pair) { 7101fd3346740dfb7f47be9922312b68a4227fada96buzbee AnnotateDalvikRegAccess(load2, (displacement + HIWORD_OFFSET) >> 2, 711fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee true /* is_load */, is64bit); 712b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 713e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 714b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 715b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers if (!pair) { 7162700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee load = NewLIR5(opcode, r_dest.GetReg(), r_base.GetReg(), r_index.GetReg(), scale, 717a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee displacement + LOWORD_OFFSET); 718b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 719091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK(!r_dest.IsFloat()); // Make sure we're not still using a pair here. 720091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (r_base == r_dest.GetLow()) { 721091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (r_dest.GetHigh() == r_index) { 722ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell // We can't use either register for the first load. 7232700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee RegStorage temp = AllocTemp(); 72469dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison load = NewLIR5(opcode, temp.GetReg(), r_base.GetReg(), r_index.GetReg(), scale, 725ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell displacement + HIWORD_OFFSET); 72669dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison load2 = NewLIR5(opcode, r_dest.GetLowReg(), r_base.GetReg(), r_index.GetReg(), scale, 727ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell displacement + LOWORD_OFFSET); 728091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee OpRegCopy(r_dest.GetHigh(), temp); 729ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell FreeTemp(temp); 730ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell } else { 73169dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison load = NewLIR5(opcode, r_dest.GetHighReg(), r_base.GetReg(), r_index.GetReg(), scale, 732ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell displacement + HIWORD_OFFSET); 73369dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison load2 = NewLIR5(opcode, r_dest.GetLowReg(), r_base.GetReg(), r_index.GetReg(), scale, 734ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell displacement + LOWORD_OFFSET); 735ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell } 736fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao } else { 737091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (r_dest.GetLow() == r_index) { 738ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell // We can't use either register for the first load. 7392700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee RegStorage temp = AllocTemp(); 7402700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee load = NewLIR5(opcode, temp.GetReg(), r_base.GetReg(), r_index.GetReg(), scale, 741ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell displacement + LOWORD_OFFSET); 742091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee load2 = NewLIR5(opcode, r_dest.GetHighReg(), r_base.GetReg(), r_index.GetReg(), scale, 743ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell displacement + HIWORD_OFFSET); 744091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee OpRegCopy(r_dest.GetLow(), temp); 745ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell FreeTemp(temp); 746ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell } else { 747091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee load = NewLIR5(opcode, r_dest.GetLowReg(), r_base.GetReg(), r_index.GetReg(), scale, 748ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell displacement + LOWORD_OFFSET); 749091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee load2 = NewLIR5(opcode, r_dest.GetHighReg(), r_base.GetReg(), r_index.GetReg(), scale, 750ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell displacement + HIWORD_OFFSET); 751ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell } 752fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao } 753b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 754b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 755b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 75669dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison // Always return first load generated as this might cause a fault if base is nullptr. 757b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers return load; 758e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 759e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 7605772babbe824494ef9fe90a1b07a926d124bb7c7jeffhao/* Load value from base + scaled index. */ 7612700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::LoadBaseIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_dest, 7622700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee int scale, OpSize size) { 7633bf7c60a86d49bf8c05c5d2ac5ca8e9f80bd9824Vladimir Marko return LoadBaseIndexedDisp(r_base, r_index, scale, 0, r_dest, size); 7645772babbe824494ef9fe90a1b07a926d124bb7c7jeffhao} 7655772babbe824494ef9fe90a1b07a926d124bb7c7jeffhao 7663c12c512faf6837844d5465b23b9410889e5eb11Andreas GampeLIR* X86Mir2Lir::LoadBaseDisp(RegStorage r_base, int displacement, RegStorage r_dest, 7673c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe OpSize size, VolatileKind is_volatile) { 768674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko // LoadBaseDisp() will emit correct insn for atomic load on x86 769674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko // assuming r_dest is correctly prepared using RegClassForFieldLoadStore(). 770674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko 7713c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe LIR* load = LoadBaseIndexedDisp(r_base, RegStorage::InvalidReg(), 0, displacement, r_dest, 7723c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe size); 7733c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe 7743c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe if (UNLIKELY(is_volatile == kVolatile)) { 77548f5c47907654350ce30a8dfdda0e977f5d3d39fHans Boehm GenMemBarrier(kLoadAny); // Only a scheduling barrier. 7763c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe } 7773c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe 7783c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe return load; 779e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 780e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 7812700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::StoreBaseIndexedDisp(RegStorage r_base, RegStorage r_index, int scale, 7823bf7c60a86d49bf8c05c5d2ac5ca8e9f80bd9824Vladimir Marko int displacement, RegStorage r_src, OpSize size) { 783b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers LIR *store = NULL; 784e296248a124ed8287b38a9225463696c18d84cd6jeffhao LIR *store2 = NULL; 7852700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee bool is_array = r_index.Valid(); 786091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee bool pair = r_src.IsPair(); 787091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee bool is64bit = (size == k64) || (size == kDouble); 788b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers X86OpCode opcode = kX86Nop; 789b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers switch (size) { 790695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee case k64: 791b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kDouble: 792091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (r_src.IsFloat()) { 793fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86MovsdAR : kX86MovsdMR; 794e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu } else if (!pair) { 795e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu opcode = is_array ? kX86Mov64AR : kX86Mov64MR; 796b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 797e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu opcode = is_array ? kX86Mov32AR : kX86Mov32MR; 798b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 799b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers // TODO: double store is to unaligned address 800b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ((displacement & 0x3), 0); 801b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 8029ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko case kWord: 803dd64450b37776f68b9bfc47f8d9a88bc72c95727Elena Sayapina if (cu_->target64) { 8049ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko opcode = is_array ? kX86Mov64AR : kX86Mov64MR; 8059ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko CHECK_EQ(is_array, false); 8069ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko CHECK_EQ(r_src.IsFloat(), false); 8079ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko break; 8089ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko } // else fall-through to k32 case 809695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee case k32: 810b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kSingle: 811695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee case kReference: 812fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Mov32AR : kX86Mov32MR; 813091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (r_src.IsFloat()) { 814fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86MovssAR : kX86MovssMR; 815091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK(r_src.IsSingle()); 816b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 817b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ((displacement & 0x3), 0); 818b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 819b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kUnsignedHalf: 820b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kSignedHalf: 821fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Mov16AR : kX86Mov16MR; 822b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ((displacement & 0x1), 0); 823b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 824b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kUnsignedByte: 825b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kSignedByte: 826fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Mov8AR : kX86Mov8MR; 827b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 828b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers default: 82900e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee LOG(FATAL) << "Bad case in StoreBaseIndexedDispBody"; 830b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 831b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 832fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (!is_array) { 833b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers if (!pair) { 8342700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee store = NewLIR3(opcode, r_base.GetReg(), displacement + LOWORD_OFFSET, r_src.GetReg()); 835b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } else { 836091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK(!r_src.IsFloat()); // Make sure we're not still using a pair here. 837091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee store = NewLIR3(opcode, r_base.GetReg(), displacement + LOWORD_OFFSET, r_src.GetLowReg()); 838091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee store2 = NewLIR3(opcode, r_base.GetReg(), displacement + HIWORD_OFFSET, r_src.GetHighReg()); 839e296248a124ed8287b38a9225463696c18d84cd6jeffhao } 8408dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko if (mem_ref_type_ == ResourceMask::kDalvikReg) { 8418dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko DCHECK(r_base == rs_rX86_SP); 8421fd3346740dfb7f47be9922312b68a4227fada96buzbee AnnotateDalvikRegAccess(store, (displacement + (pair ? LOWORD_OFFSET : 0)) >> 2, 84302031b185b4653e6c72e21f7a51238b903f6d638buzbee false /* is_load */, is64bit); 844e296248a124ed8287b38a9225463696c18d84cd6jeffhao if (pair) { 8451fd3346740dfb7f47be9922312b68a4227fada96buzbee AnnotateDalvikRegAccess(store2, (displacement + HIWORD_OFFSET) >> 2, 846fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee false /* is_load */, is64bit); 847e296248a124ed8287b38a9225463696c18d84cd6jeffhao } 848b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 849b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 850b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers if (!pair) { 8512700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee store = NewLIR5(opcode, r_base.GetReg(), r_index.GetReg(), scale, 8522700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee displacement + LOWORD_OFFSET, r_src.GetReg()); 853b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } else { 854091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK(!r_src.IsFloat()); // Make sure we're not still using a pair here. 8552700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee store = NewLIR5(opcode, r_base.GetReg(), r_index.GetReg(), scale, 856091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee displacement + LOWORD_OFFSET, r_src.GetLowReg()); 8572700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee store2 = NewLIR5(opcode, r_base.GetReg(), r_index.GetReg(), scale, 858091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee displacement + HIWORD_OFFSET, r_src.GetHighReg()); 859e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 860b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 861b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers return store; 862e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 863e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 864c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers/* store value base base + scaled index. */ 8652700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::StoreBaseIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_src, 8663c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe int scale, OpSize size) { 8673bf7c60a86d49bf8c05c5d2ac5ca8e9f80bd9824Vladimir Marko return StoreBaseIndexedDisp(r_base, r_index, scale, 0, r_src, size); 868c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers} 869c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers 8703c12c512faf6837844d5465b23b9410889e5eb11Andreas GampeLIR* X86Mir2Lir::StoreBaseDisp(RegStorage r_base, int displacement, RegStorage r_src, OpSize size, 8713c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe VolatileKind is_volatile) { 8723c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe if (UNLIKELY(is_volatile == kVolatile)) { 87348f5c47907654350ce30a8dfdda0e977f5d3d39fHans Boehm GenMemBarrier(kAnyStore); // Only a scheduling barrier. 8743c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe } 8753c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe 876674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko // StoreBaseDisp() will emit correct insn for atomic store on x86 877674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko // assuming r_dest is correctly prepared using RegClassForFieldLoadStore(). 87837f05ef45e0393de812d51261dc293240c17294dFred Shih // x86 only allows registers EAX-EDX to be used as byte registers, if the input src is not 87937f05ef45e0393de812d51261dc293240c17294dFred Shih // valid, allocate a temp. 88037f05ef45e0393de812d51261dc293240c17294dFred Shih bool allocated_temp = false; 88137f05ef45e0393de812d51261dc293240c17294dFred Shih if (size == kUnsignedByte || size == kSignedByte) { 88237f05ef45e0393de812d51261dc293240c17294dFred Shih if (!cu_->target64 && !r_src.Low4()) { 88337f05ef45e0393de812d51261dc293240c17294dFred Shih RegStorage r_input = r_src; 88437f05ef45e0393de812d51261dc293240c17294dFred Shih r_src = AllocateByteRegister(); 88537f05ef45e0393de812d51261dc293240c17294dFred Shih OpRegCopy(r_src, r_input); 88637f05ef45e0393de812d51261dc293240c17294dFred Shih allocated_temp = true; 88737f05ef45e0393de812d51261dc293240c17294dFred Shih } 88837f05ef45e0393de812d51261dc293240c17294dFred Shih } 889674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko 8903c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe LIR* store = StoreBaseIndexedDisp(r_base, RegStorage::InvalidReg(), 0, displacement, r_src, size); 8913c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe 8923c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe if (UNLIKELY(is_volatile == kVolatile)) { 89348f5c47907654350ce30a8dfdda0e977f5d3d39fHans Boehm // A volatile load might follow the volatile store so insert a StoreLoad barrier. 89448f5c47907654350ce30a8dfdda0e977f5d3d39fHans Boehm // This does require a fence, even on x86. 89548f5c47907654350ce30a8dfdda0e977f5d3d39fHans Boehm GenMemBarrier(kAnyAny); 8963c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe } 8973c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe 89837f05ef45e0393de812d51261dc293240c17294dFred Shih if (allocated_temp) { 89937f05ef45e0393de812d51261dc293240c17294dFred Shih FreeTemp(r_src); 90037f05ef45e0393de812d51261dc293240c17294dFred Shih } 90137f05ef45e0393de812d51261dc293240c17294dFred Shih 9023c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe return store; 903e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 904e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 9052700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpCmpMemImmBranch(ConditionCode cond, RegStorage temp_reg, RegStorage base_reg, 90669dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison int offset, int check_value, LIR* target, LIR** compare) { 90769dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison LIR* inst = NewLIR3(IS_SIMM8(check_value) ? kX86Cmp32MI8 : kX86Cmp32MI, base_reg.GetReg(), 90869dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison offset, check_value); 90969dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison if (compare != nullptr) { 91069dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison *compare = inst; 91169dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison } 912766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell LIR* branch = OpCondBranch(cond, target); 913766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell return branch; 914766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell} 915766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell 91667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendellvoid X86Mir2Lir::AnalyzeMIR() { 91767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // Assume we don't need a pointer to the base of the code. 91867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell cu_->NewTimingSplit("X86 MIR Analysis"); 91967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell store_method_addr_ = false; 92067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell 92167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // Walk the MIR looking for interesting items. 92267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell PreOrderDfsIterator iter(mir_graph_); 92367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell BasicBlock* curr_bb = iter.Next(); 92467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell while (curr_bb != NULL) { 92567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell AnalyzeBB(curr_bb); 92667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell curr_bb = iter.Next(); 92767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } 92867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell 92967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // Did we need a pointer to the method code? 93067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell if (store_method_addr_) { 931dd64450b37776f68b9bfc47f8d9a88bc72c95727Elena Sayapina base_of_code_ = mir_graph_->GetNewCompilerTemp(kCompilerTempVR, cu_->target64 == true); 93267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } else { 93367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell base_of_code_ = nullptr; 93467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } 93567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell} 93667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell 93767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendellvoid X86Mir2Lir::AnalyzeBB(BasicBlock * bb) { 93867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell if (bb->block_type == kDead) { 93967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // Ignore dead blocks 94067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell return; 94167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } 94267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell 94367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell for (MIR *mir = bb->first_mir_insn; mir != NULL; mir = mir->next) { 94467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell int opcode = mir->dalvikInsn.opcode; 9452ab40eb3c23559205ac7b9b039bd749458e8a761Jean Christophe Beyler if (MIR::DecodedInstruction::IsPseudoMirOp(opcode)) { 94667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell AnalyzeExtendedMIR(opcode, bb, mir); 94767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } else { 94867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell AnalyzeMIR(opcode, bb, mir); 94967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } 95067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } 95167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell} 95267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell 95367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell 95467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendellvoid X86Mir2Lir::AnalyzeExtendedMIR(int opcode, BasicBlock * bb, MIR *mir) { 95567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell switch (opcode) { 95667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // Instructions referencing doubles. 95767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell case kMirOpFusedCmplDouble: 95867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell case kMirOpFusedCmpgDouble: 95967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell AnalyzeFPInstruction(opcode, bb, mir); 96067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell break; 961d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell case kMirOpConstVector: 962d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell store_method_addr_ = true; 963d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell break; 96467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell default: 96567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // Ignore the rest. 96667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell break; 96767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } 96867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell} 96967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell 97067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendellvoid X86Mir2Lir::AnalyzeMIR(int opcode, BasicBlock * bb, MIR *mir) { 97167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // Looking for 97267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // - Do we need a pointer to the code (used for packed switches and double lits)? 97367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell 97467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell switch (opcode) { 97567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // Instructions referencing doubles. 97667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell case Instruction::CMPL_DOUBLE: 97767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell case Instruction::CMPG_DOUBLE: 97867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell case Instruction::NEG_DOUBLE: 97967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell case Instruction::ADD_DOUBLE: 98067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell case Instruction::SUB_DOUBLE: 98167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell case Instruction::MUL_DOUBLE: 98267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell case Instruction::DIV_DOUBLE: 98367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell case Instruction::REM_DOUBLE: 98467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell case Instruction::ADD_DOUBLE_2ADDR: 98567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell case Instruction::SUB_DOUBLE_2ADDR: 98667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell case Instruction::MUL_DOUBLE_2ADDR: 98767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell case Instruction::DIV_DOUBLE_2ADDR: 98867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell case Instruction::REM_DOUBLE_2ADDR: 98967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell AnalyzeFPInstruction(opcode, bb, mir); 99067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell break; 99155d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell 99267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // Packed switches and array fills need a pointer to the base of the method. 99367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell case Instruction::FILL_ARRAY_DATA: 99467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell case Instruction::PACKED_SWITCH: 99567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell store_method_addr_ = true; 99667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell break; 9977071c8d5885175a746723a3b38a347855965be08Yixin Shou case Instruction::INVOKE_STATIC: 9987071c8d5885175a746723a3b38a347855965be08Yixin Shou AnalyzeInvokeStatic(opcode, bb, mir); 9997071c8d5885175a746723a3b38a347855965be08Yixin Shou break; 100067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell default: 100167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // Other instructions are not interesting yet. 100267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell break; 100367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } 100467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell} 100567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell 100667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendellvoid X86Mir2Lir::AnalyzeFPInstruction(int opcode, BasicBlock * bb, MIR *mir) { 100767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // Look at all the uses, and see if they are double constants. 1008cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyler uint64_t attrs = MIRGraph::GetDataFlowAttributes(static_cast<Instruction::Code>(opcode)); 100967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell int next_sreg = 0; 101067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell if (attrs & DF_UA) { 101167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell if (attrs & DF_A_WIDE) { 101267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell AnalyzeDoubleUse(mir_graph_->GetSrcWide(mir, next_sreg)); 101367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell next_sreg += 2; 101467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } else { 101567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell next_sreg++; 101667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } 101767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } 101867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell if (attrs & DF_UB) { 101967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell if (attrs & DF_B_WIDE) { 102067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell AnalyzeDoubleUse(mir_graph_->GetSrcWide(mir, next_sreg)); 102167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell next_sreg += 2; 102267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } else { 102367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell next_sreg++; 102467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } 102567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } 102667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell if (attrs & DF_UC) { 102767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell if (attrs & DF_C_WIDE) { 102867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell AnalyzeDoubleUse(mir_graph_->GetSrcWide(mir, next_sreg)); 102967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } 103067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } 103167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell} 103267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell 103367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendellvoid X86Mir2Lir::AnalyzeDoubleUse(RegLocation use) { 10340e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov // If this is a double literal, we will want it in the literal pool on 32b platforms. 10350e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov if (use.is_const && !cu_->target64) { 103667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell store_method_addr_ = true; 103767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } 103867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell} 103967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell 104030adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbeeRegLocation X86Mir2Lir::UpdateLocTyped(RegLocation loc, int reg_class) { 104130adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee loc = UpdateLoc(loc); 104230adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee if ((loc.location == kLocPhysReg) && (loc.fp != loc.reg.IsFloat())) { 104330adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee if (GetRegInfo(loc.reg)->IsTemp()) { 104430adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee Clobber(loc.reg); 104530adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee FreeTemp(loc.reg); 104630adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee loc.reg = RegStorage::InvalidReg(); 104730adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee loc.location = kLocDalvikFrame; 104830adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee } 104930adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee } 1050e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu DCHECK(CheckCorePoolSanity()); 105130adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee return loc; 105230adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee} 105330adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee 105430adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbeeRegLocation X86Mir2Lir::UpdateLocWideTyped(RegLocation loc, int reg_class) { 105530adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee loc = UpdateLocWide(loc); 105630adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee if ((loc.location == kLocPhysReg) && (loc.fp != loc.reg.IsFloat())) { 105730adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee if (GetRegInfo(loc.reg)->IsTemp()) { 105830adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee Clobber(loc.reg); 105930adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee FreeTemp(loc.reg); 106030adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee loc.reg = RegStorage::InvalidReg(); 106130adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee loc.location = kLocDalvikFrame; 106230adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee } 106330adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee } 1064e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu DCHECK(CheckCorePoolSanity()); 106530adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee return loc; 106630adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee} 10677071c8d5885175a746723a3b38a347855965be08Yixin Shou 10687071c8d5885175a746723a3b38a347855965be08Yixin Shouvoid X86Mir2Lir::AnalyzeInvokeStatic(int opcode, BasicBlock * bb, MIR *mir) { 10690e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov // For now this is only actual for x86-32. 10700e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov if (cu_->target64) { 10710e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov return; 10720e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov } 10730e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov 10747071c8d5885175a746723a3b38a347855965be08Yixin Shou uint32_t index = mir->dalvikInsn.vB; 10757071c8d5885175a746723a3b38a347855965be08Yixin Shou if (!(mir->optimization_flags & MIR_INLINED)) { 10767071c8d5885175a746723a3b38a347855965be08Yixin Shou DCHECK(cu_->compiler_driver->GetMethodInlinerMap() != nullptr); 10770e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov DexFileMethodInliner* method_inliner = 10780e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov cu_->compiler_driver->GetMethodInlinerMap()->GetMethodInliner(cu_->dex_file); 10797071c8d5885175a746723a3b38a347855965be08Yixin Shou InlineMethod method; 10800e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov if (method_inliner->IsIntrinsic(index, &method)) { 10817071c8d5885175a746723a3b38a347855965be08Yixin Shou switch (method.opcode) { 10827071c8d5885175a746723a3b38a347855965be08Yixin Shou case kIntrinsicAbsDouble: 10831222c96fafe98061cfc57d3bd115f46edb64e624Alexei Zavjalov case kIntrinsicMinMaxDouble: 10847071c8d5885175a746723a3b38a347855965be08Yixin Shou store_method_addr_ = true; 10857071c8d5885175a746723a3b38a347855965be08Yixin Shou break; 10867071c8d5885175a746723a3b38a347855965be08Yixin Shou default: 10877071c8d5885175a746723a3b38a347855965be08Yixin Shou break; 10887071c8d5885175a746723a3b38a347855965be08Yixin Shou } 10897071c8d5885175a746723a3b38a347855965be08Yixin Shou } 10907071c8d5885175a746723a3b38a347855965be08Yixin Shou } 10917071c8d5885175a746723a3b38a347855965be08Yixin Shou} 1092984305917bf57b3f8d92965e4715a0370cc5bcfbAndreas Gampe 1093984305917bf57b3f8d92965e4715a0370cc5bcfbAndreas GampeLIR* X86Mir2Lir::InvokeTrampoline(OpKind op, RegStorage r_tgt, QuickEntrypointEnum trampoline) { 1094984305917bf57b3f8d92965e4715a0370cc5bcfbAndreas Gampe if (cu_->target64) { 1095984305917bf57b3f8d92965e4715a0370cc5bcfbAndreas Gampe return OpThreadMem(op, GetThreadOffset<8>(trampoline)); 1096984305917bf57b3f8d92965e4715a0370cc5bcfbAndreas Gampe } else { 1097984305917bf57b3f8d92965e4715a0370cc5bcfbAndreas Gampe return OpThreadMem(op, GetThreadOffset<4>(trampoline)); 1098984305917bf57b3f8d92965e4715a0370cc5bcfbAndreas Gampe } 1099984305917bf57b3f8d92965e4715a0370cc5bcfbAndreas Gampe} 1100984305917bf57b3f8d92965e4715a0370cc5bcfbAndreas Gampe 1101e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} // namespace art 1102