utility_x86.cc revision 7e399fd3a99ba9c9dbfafdf14f75dd318fa7d454
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" 211bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee 22e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbeenamespace art { 23e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 24b046e16d8b8da318d6055f9308950131f1255e08buzbee/* This file contains codegen for the X86 ISA */ 25e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 262700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpFpRegCopy(RegStorage r_dest, RegStorage r_src) { 27a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int opcode; 28a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* must be both DOUBLE or both not DOUBLE */ 29091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK(r_dest.IsFloat() || r_src.IsFloat()); 30091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK_EQ(r_dest.IsDouble(), r_src.IsDouble()); 31091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (r_dest.IsDouble()) { 32a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kX86MovsdRR; 33a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 34091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (r_dest.IsSingle()) { 35091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (r_src.IsSingle()) { 36a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kX86MovssRR; 37a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { // Fpr <- Gpr 38a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kX86MovdxrRR; 39a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 40a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { // Gpr <- Fpr 41091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK(r_src.IsSingle()) << "Raw: 0x" << std::hex << r_src.GetRawBits(); 42a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kX86MovdrxRR; 43e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 44a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 45ec13743da80a80c1817cf6660c28917fc28846bcbuzbee DCHECK_NE((EncodingMap[opcode].flags & IS_BINARY_OP), 0ULL); 462700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee LIR* res = RawLIR(current_dalvik_offset_, opcode, r_dest.GetReg(), r_src.GetReg()); 47fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (r_dest == r_src) { 48fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee res->flags.is_nop = true; 49a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 50a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return res; 51e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 52e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 532ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool X86Mir2Lir::InexpensiveConstantInt(int32_t value) { 54e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee return true; 55e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee} 56e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee 572ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool X86Mir2Lir::InexpensiveConstantFloat(int32_t value) { 584ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee return false; 594ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee} 604ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee 612ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool X86Mir2Lir::InexpensiveConstantLong(int64_t value) { 624ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee return true; 634ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee} 644ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee 652ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool X86Mir2Lir::InexpensiveConstantDouble(int64_t value) { 6667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell return value == 0; 674ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee} 684ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee 69e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee/* 70e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * Load a immediate using a shortcut if possible; otherwise 71e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * grab from the per-translation literal pool. If target is 72e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * a high register, build constant into a low register and copy. 73e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * 74e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * No additional register clobbering operation performed. Use this version when 75fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee * 1) r_dest is freshly returned from AllocTemp or 76e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * 2) The codegen is under fixed register usage 77e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee */ 782700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::LoadConstantNoClobber(RegStorage r_dest, int value) { 792700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee RegStorage r_dest_save = r_dest; 80091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (r_dest.IsFloat()) { 81b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers if (value == 0) { 822700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return NewLIR2(kX86XorpsRR, r_dest.GetReg(), r_dest.GetReg()); 83b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 841fd3346740dfb7f47be9922312b68a4227fada96buzbee r_dest = AllocTemp(); 856cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers } 86e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 87b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers LIR *res; 886cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers if (value == 0) { 892700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee res = NewLIR2(kX86Xor32RR, r_dest.GetReg(), r_dest.GetReg()); 906cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers } else { 912e9f7ed8d00271cb1cf082d68b4f4bc60702d6ecIan Rogers // Note, there is no byte immediate form of a 32 bit immediate move. 92e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu // 64-bit immediate is not supported by LIR structure 93e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu res = NewLIR2(kX86Mov32RI, r_dest.GetReg(), value); 946cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers } 95e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 96091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (r_dest_save.IsFloat()) { 972700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee NewLIR2(kX86MovdxrRR, r_dest_save.GetReg(), r_dest.GetReg()); 981fd3346740dfb7f47be9922312b68a4227fada96buzbee FreeTemp(r_dest); 996cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers } 100e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 1016cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers return res; 102e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 103e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 1042ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* X86Mir2Lir::OpUnconditionalBranch(LIR* target) { 105df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom LIR* res = NewLIR1(kX86Jmp8, 0 /* offset to be patched during assembly*/); 10602031b185b4653e6c72e21f7a51238b903f6d638buzbee res->target = target; 10702031b185b4653e6c72e21f7a51238b903f6d638buzbee return res; 108e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 109e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 1102ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* X86Mir2Lir::OpCondBranch(ConditionCode cc, LIR* target) { 1111fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* branch = NewLIR2(kX86Jcc8, 0 /* offset to be patched */, 11252a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee X86ConditionEncoding(cc)); 113b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers branch->target = target; 114b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers return branch; 115a7678db092ac6bb79f7cad490099a1015fbbc714buzbee} 116a7678db092ac6bb79f7cad490099a1015fbbc714buzbee 1172700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpReg(OpKind op, RegStorage r_dest_src) { 118b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers X86OpCode opcode = kX86Bkpt; 119b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers switch (op) { 120e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpNeg: opcode = r_dest_src.Is64Bit() ? kX86Neg64R : kX86Neg32R; break; 121e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpNot: opcode = r_dest_src.Is64Bit() ? kX86Not64R : kX86Not32R; break; 122a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko case kOpRev: opcode = kX86Bswap32R; break; 123b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpBlx: opcode = kX86CallR; break; 124b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers default: 12552a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee LOG(FATAL) << "Bad case in OpReg " << op; 126b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 1272700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return NewLIR1(opcode, r_dest_src.GetReg()); 128e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 129e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 1302700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpRegImm(OpKind op, RegStorage r_dest_src1, int value) { 131b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers X86OpCode opcode = kX86Bkpt; 132fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bool byte_imm = IS_SIMM8(value); 133091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK(!r_dest_src1.IsFloat()); 1349ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko if (r_dest_src1.Is64Bit()) { 1359ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko switch (op) { 1369ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko case kOpAdd: opcode = byte_imm ? kX86Add64RI8 : kX86Add64RI; break; 1379ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko case kOpSub: opcode = byte_imm ? kX86Sub64RI8 : kX86Sub64RI; break; 138e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpLsl: opcode = kX86Sal64RI; break; 139e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpLsr: opcode = kX86Shr64RI; break; 140e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpAsr: opcode = kX86Sar64RI; break; 1417e399fd3a99ba9c9dbfafdf14f75dd318fa7d454Chao-ying Fu case kOpCmp: opcode = byte_imm ? kX86Cmp64RI8 : kX86Cmp64RI; break; 1429ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko default: 1439ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko LOG(FATAL) << "Bad case in OpRegImm (64-bit) " << op; 1449ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko } 1459ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko } else { 1469ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko switch (op) { 1479ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko case kOpLsl: opcode = kX86Sal32RI; break; 1489ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko case kOpLsr: opcode = kX86Shr32RI; break; 1499ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko case kOpAsr: opcode = kX86Sar32RI; break; 1509ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko case kOpAdd: opcode = byte_imm ? kX86Add32RI8 : kX86Add32RI; break; 1519ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko case kOpOr: opcode = byte_imm ? kX86Or32RI8 : kX86Or32RI; break; 1529ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko case kOpAdc: opcode = byte_imm ? kX86Adc32RI8 : kX86Adc32RI; break; 1539ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko // case kOpSbb: opcode = kX86Sbb32RI; break; 1549ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko case kOpAnd: opcode = byte_imm ? kX86And32RI8 : kX86And32RI; break; 1559ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko case kOpSub: opcode = byte_imm ? kX86Sub32RI8 : kX86Sub32RI; break; 1569ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko case kOpXor: opcode = byte_imm ? kX86Xor32RI8 : kX86Xor32RI; break; 1579ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko case kOpCmp: opcode = byte_imm ? kX86Cmp32RI8 : kX86Cmp32RI; break; 1589ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko case kOpMov: 1599ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko /* 1609ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko * Moving the constant zero into register can be specialized as an xor of the register. 1619ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko * However, that sets eflags while the move does not. For that reason here, always do 1629ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko * the move and if caller is flexible, they should be calling LoadConstantNoClobber instead. 1639ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko */ 1649ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko opcode = kX86Mov32RI; 1659ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko break; 1669ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko case kOpMul: 1679ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko opcode = byte_imm ? kX86Imul32RRI8 : kX86Imul32RRI; 1689ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko return NewLIR3(opcode, r_dest_src1.GetReg(), r_dest_src1.GetReg(), value); 169e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell case kOp2Byte: 170e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell opcode = kX86Mov32RI; 171e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell value = static_cast<int8_t>(value); 172e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell break; 173e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell case kOp2Short: 174e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell opcode = kX86Mov32RI; 175e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell value = static_cast<int16_t>(value); 176e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell break; 177e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell case kOp2Char: 178e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell opcode = kX86Mov32RI; 179e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell value = static_cast<uint16_t>(value); 180e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell break; 181e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell case kOpNeg: 182e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell opcode = kX86Mov32RI; 183e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell value = -value; 184e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell break; 1859ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko default: 1869ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko LOG(FATAL) << "Bad case in OpRegImm " << op; 1879ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko } 188b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 1892700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return NewLIR2(opcode, r_dest_src1.GetReg(), value); 190e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 191e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 1922700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpRegReg(OpKind op, RegStorage r_dest_src1, RegStorage r_src2) { 193e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu bool is64Bit = r_dest_src1.Is64Bit(); 194a7678db092ac6bb79f7cad490099a1015fbbc714buzbee X86OpCode opcode = kX86Nop; 195d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers bool src2_must_be_cx = false; 196e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee switch (op) { 197b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers // X86 unary opcodes 198b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpMvn: 1991fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegCopy(r_dest_src1, r_src2); 2001fd3346740dfb7f47be9922312b68a4227fada96buzbee return OpReg(kOpNot, r_dest_src1); 201b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpNeg: 2021fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegCopy(r_dest_src1, r_src2); 2031fd3346740dfb7f47be9922312b68a4227fada96buzbee return OpReg(kOpNeg, r_dest_src1); 204a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko case kOpRev: 205a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko OpRegCopy(r_dest_src1, r_src2); 206a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko return OpReg(kOpRev, r_dest_src1); 207a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko case kOpRevsh: 208a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko OpRegCopy(r_dest_src1, r_src2); 209a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko OpReg(kOpRev, r_dest_src1); 210a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko return OpRegImm(kOpAsr, r_dest_src1, 16); 211b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers // X86 binary opcodes 212e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpSub: opcode = is64Bit ? kX86Sub64RR : kX86Sub32RR; break; 213e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpSbc: opcode = is64Bit ? kX86Sbb64RR : kX86Sbb32RR; break; 214e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpLsl: opcode = is64Bit ? kX86Sal64RC : kX86Sal32RC; src2_must_be_cx = true; break; 215e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpLsr: opcode = is64Bit ? kX86Shr64RC : kX86Shr32RC; src2_must_be_cx = true; break; 216e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpAsr: opcode = is64Bit ? kX86Sar64RC : kX86Sar32RC; src2_must_be_cx = true; break; 217e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpMov: opcode = is64Bit ? kX86Mov64RR : kX86Mov32RR; break; 218e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpCmp: opcode = is64Bit ? kX86Cmp64RR : kX86Cmp32RR; break; 219e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpAdd: opcode = is64Bit ? kX86Add64RR : kX86Add32RR; break; 220e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpAdc: opcode = is64Bit ? kX86Adc64RR : kX86Adc32RR; break; 221e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpAnd: opcode = is64Bit ? kX86And64RR : kX86And32RR; break; 222e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpOr: opcode = is64Bit ? kX86Or64RR : kX86Or32RR; break; 223e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpXor: opcode = is64Bit ? kX86Xor64RR : kX86Xor32RR; break; 224703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao case kOp2Byte: 225091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee // TODO: there are several instances of this check. A utility function perhaps? 226091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee // TODO: Similar to Arm's reg < 8 check. Perhaps add attribute checks to RegStorage? 227703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao // Use shifts instead of a byte operand if the source can't be byte accessed. 228091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (r_src2.GetRegNum() >= rs_rX86_SP.GetRegNum()) { 229e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu NewLIR2(is64Bit ? kX86Mov64RR : kX86Mov32RR, r_dest_src1.GetReg(), r_src2.GetReg()); 230e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu NewLIR2(is64Bit ? kX86Sal64RI : kX86Sal32RI, r_dest_src1.GetReg(), is64Bit ? 56 : 24); 231e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu return NewLIR2(is64Bit ? kX86Sar64RI : kX86Sar32RI, r_dest_src1.GetReg(), 232e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu is64Bit ? 56 : 24); 233703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao } else { 234e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu opcode = is64Bit ? kX86Bkpt : kX86Movsx8RR; 235703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao } 236703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao break; 237e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOp2Short: opcode = is64Bit ? kX86Bkpt : kX86Movsx16RR; break; 238e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOp2Char: opcode = is64Bit ? kX86Bkpt : kX86Movzx16RR; break; 239e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpMul: opcode = is64Bit ? kX86Bkpt : kX86Imul32RR; break; 240b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers default: 24152a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee LOG(FATAL) << "Bad case in OpRegReg " << op; 242b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 243e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 244091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(!src2_must_be_cx || r_src2.GetReg() == rs_rCX.GetReg()); 2452700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return NewLIR2(opcode, r_dest_src1.GetReg(), r_src2.GetReg()); 246e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 247e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 2482700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpMovRegMem(RegStorage r_dest, RegStorage r_base, int offset, MoveType move_type) { 249091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK(!r_base.IsFloat()); 2502c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru X86OpCode opcode = kX86Nop; 2512700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee int dest = r_dest.IsPair() ? r_dest.GetLowReg() : r_dest.GetReg(); 2522c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru switch (move_type) { 2532c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMov8GP: 254091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(!r_dest.IsFloat()); 2552c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86Mov8RM; 2562c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 2572c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMov16GP: 258091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(!r_dest.IsFloat()); 2592c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86Mov16RM; 2602c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 2612c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMov32GP: 262091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(!r_dest.IsFloat()); 2632c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86Mov32RM; 2642c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 2652c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMov32FP: 266091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(r_dest.IsFloat()); 2672c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86MovssRM; 2682c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 2692c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMov64FP: 270091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(r_dest.IsFloat()); 2712c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86MovsdRM; 2722c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 2732c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMovU128FP: 274091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(r_dest.IsFloat()); 2752c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86MovupsRM; 2762c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 2772c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMovA128FP: 278091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(r_dest.IsFloat()); 2792c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86MovapsRM; 2802c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 2812c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMovLo128FP: 282091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(r_dest.IsFloat()); 2832c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86MovlpsRM; 2842c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 2852c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMovHi128FP: 286091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(r_dest.IsFloat()); 2872c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86MovhpsRM; 2882c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 2892c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMov64GP: 2902c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMovLo64FP: 2912c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMovHi64FP: 2922c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru default: 2932c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru LOG(FATAL) << "Bad case in OpMovRegMem"; 2942c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 2952c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru } 2962c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru 2972700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return NewLIR3(opcode, dest, r_base.GetReg(), offset); 2982c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru} 2992c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru 3002700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpMovMemReg(RegStorage r_base, int offset, RegStorage r_src, MoveType move_type) { 301091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK(!r_base.IsFloat()); 3022700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee int src = r_src.IsPair() ? r_src.GetLowReg() : r_src.GetReg(); 3032c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru 3042c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru X86OpCode opcode = kX86Nop; 3052c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru switch (move_type) { 3062c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMov8GP: 307091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(!r_src.IsFloat()); 3082c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86Mov8MR; 3092c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 3102c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMov16GP: 311091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(!r_src.IsFloat()); 3122c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86Mov16MR; 3132c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 3142c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMov32GP: 315091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(!r_src.IsFloat()); 3162c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86Mov32MR; 3172c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 3182c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMov32FP: 319091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(r_src.IsFloat()); 3202c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86MovssMR; 3212c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 3222c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMov64FP: 323091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(r_src.IsFloat()); 3242c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86MovsdMR; 3252c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 3262c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMovU128FP: 327091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(r_src.IsFloat()); 3282c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86MovupsMR; 3292c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 3302c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMovA128FP: 331091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(r_src.IsFloat()); 3322c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86MovapsMR; 3332c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 3342c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMovLo128FP: 335091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(r_src.IsFloat()); 3362c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86MovlpsMR; 3372c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 3382c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMovHi128FP: 339091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee CHECK(r_src.IsFloat()); 3402c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru opcode = kX86MovhpsMR; 3412c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 3422c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMov64GP: 3432c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMovLo64FP: 3442c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru case kMovHi64FP: 3452c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru default: 3462c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru LOG(FATAL) << "Bad case in OpMovMemReg"; 3472c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru break; 3482c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru } 3492c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru 3502700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return NewLIR3(opcode, r_base.GetReg(), offset, src); 3512c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru} 3522c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru 3532700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpCondRegReg(OpKind op, ConditionCode cc, RegStorage r_dest, RegStorage r_src) { 354bd288c2c1206bc99fafebfb9120a83f13cf9723bRazvan A Lupusoru // The only conditional reg to reg operation supported is Cmov 355bd288c2c1206bc99fafebfb9120a83f13cf9723bRazvan A Lupusoru DCHECK_EQ(op, kOpCmov); 3562700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return NewLIR3(kX86Cmov32RRC, r_dest.GetReg(), r_src.GetReg(), X86ConditionEncoding(cc)); 357bd288c2c1206bc99fafebfb9120a83f13cf9723bRazvan A Lupusoru} 358bd288c2c1206bc99fafebfb9120a83f13cf9723bRazvan A Lupusoru 3592700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpRegMem(OpKind op, RegStorage r_dest, RegStorage r_base, int offset) { 360e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu bool is64Bit = r_dest.Is64Bit(); 361b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers X86OpCode opcode = kX86Nop; 362b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers switch (op) { 363b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers // X86 binary opcodes 364e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpSub: opcode = is64Bit ? kX86Sub64RM : kX86Sub32RM; break; 365e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpMov: opcode = is64Bit ? kX86Mov64RM : kX86Mov32RM; break; 366e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpCmp: opcode = is64Bit ? kX86Cmp64RM : kX86Cmp32RM; break; 367e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpAdd: opcode = is64Bit ? kX86Add64RM : kX86Add32RM; break; 368e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpAnd: opcode = is64Bit ? kX86And64RM : kX86And32RM; break; 369e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpOr: opcode = is64Bit ? kX86Or64RM : kX86Or32RM; break; 370e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpXor: opcode = is64Bit ? kX86Xor64RM : kX86Xor32RM; break; 371b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOp2Byte: opcode = kX86Movsx8RM; break; 372b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOp2Short: opcode = kX86Movsx16RM; break; 373b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOp2Char: opcode = kX86Movzx16RM; break; 374b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpMul: 375b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers default: 37652a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee LOG(FATAL) << "Bad case in OpRegMem " << op; 377b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 378b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 3792700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee LIR *l = NewLIR3(opcode, r_dest.GetReg(), r_base.GetReg(), offset); 3808dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko if (mem_ref_type_ == ResourceMask::kDalvikReg) { 3818dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko DCHECK(r_base == rs_rX86_SP); 382feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell AnnotateDalvikRegAccess(l, offset >> 2, true /* is_load */, false /* is_64bit */); 383feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell } 384feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell return l; 385feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell} 386feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell 387feb2b4e2d1c6538777bb80b60f3a247537b6221dMark MendellLIR* X86Mir2Lir::OpMemReg(OpKind op, RegLocation rl_dest, int r_value) { 388feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell DCHECK_NE(rl_dest.location, kLocPhysReg); 389feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell int displacement = SRegOffset(rl_dest.s_reg_low); 390e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu bool is64Bit = rl_dest.wide != 0; 391feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell X86OpCode opcode = kX86Nop; 392feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell switch (op) { 393e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpSub: opcode = is64Bit ? kX86Sub64MR : kX86Sub32MR; break; 394e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpMov: opcode = is64Bit ? kX86Mov64MR : kX86Mov32MR; break; 395e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpCmp: opcode = is64Bit ? kX86Cmp64MR : kX86Cmp32MR; break; 396e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpAdd: opcode = is64Bit ? kX86Add64MR : kX86Add32MR; break; 397e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpAnd: opcode = is64Bit ? kX86And64MR : kX86And32MR; break; 398e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpOr: opcode = is64Bit ? kX86Or64MR : kX86Or32MR; break; 399e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpXor: opcode = is64Bit ? kX86Xor64MR : kX86Xor32MR; break; 400e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpLsl: opcode = is64Bit ? kX86Sal64MC : kX86Sal32MC; break; 401e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpLsr: opcode = is64Bit ? kX86Shr64MC : kX86Shr32MC; break; 402e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpAsr: opcode = is64Bit ? kX86Sar64MC : kX86Sar32MC; break; 403feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell default: 404feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell LOG(FATAL) << "Bad case in OpMemReg " << op; 405feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell break; 406feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell } 407091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee LIR *l = NewLIR3(opcode, rs_rX86_SP.GetReg(), displacement, r_value); 4088dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko if (mem_ref_type_ == ResourceMask::kDalvikReg) { 4098dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko AnnotateDalvikRegAccess(l, displacement >> 2, true /* is_load */, is64Bit /* is_64bit */); 4108dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko AnnotateDalvikRegAccess(l, displacement >> 2, false /* is_load */, is64Bit /* is_64bit */); 4118dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko } 412feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell return l; 413feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell} 414feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell 4152700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpRegMem(OpKind op, RegStorage r_dest, RegLocation rl_value) { 416feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell DCHECK_NE(rl_value.location, kLocPhysReg); 417e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu bool is64Bit = r_dest.Is64Bit(); 418feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell int displacement = SRegOffset(rl_value.s_reg_low); 419feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell X86OpCode opcode = kX86Nop; 420feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell switch (op) { 421e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpSub: opcode = is64Bit ? kX86Sub64RM : kX86Sub32RM; break; 422e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpMov: opcode = is64Bit ? kX86Mov64RM : kX86Mov32RM; break; 423e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpCmp: opcode = is64Bit ? kX86Cmp64RM : kX86Cmp32RM; break; 424e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpAdd: opcode = is64Bit ? kX86Add64RM : kX86Add32RM; break; 425e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpAnd: opcode = is64Bit ? kX86And64RM : kX86And32RM; break; 426e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpOr: opcode = is64Bit ? kX86Or64RM : kX86Or32RM; break; 427e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpXor: opcode = is64Bit ? kX86Xor64RM : kX86Xor32RM; break; 428e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu case kOpMul: opcode = is64Bit ? kX86Bkpt : kX86Imul32RM; break; 429feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell default: 430feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell LOG(FATAL) << "Bad case in OpRegMem " << op; 431feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell break; 432feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell } 433091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee LIR *l = NewLIR3(opcode, r_dest.GetReg(), rs_rX86_SP.GetReg(), displacement); 4348dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko if (mem_ref_type_ == ResourceMask::kDalvikReg) { 4358dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko AnnotateDalvikRegAccess(l, displacement >> 2, true /* is_load */, is64Bit /* is_64bit */); 4368dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko } 437feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell return l; 438b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers} 439e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 4402700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpRegRegReg(OpKind op, RegStorage r_dest, RegStorage r_src1, 4412700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee RegStorage r_src2) { 442e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu bool is64Bit = r_dest.Is64Bit(); 443fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (r_dest != r_src1 && r_dest != r_src2) { 4447934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom if (op == kOpAdd) { // lea special case, except can't encode rbp as base 445fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (r_src1 == r_src2) { 4461fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegCopy(r_dest, r_src1); 4471fd3346740dfb7f47be9922312b68a4227fada96buzbee return OpRegImm(kOpLsl, r_dest, 1); 4482700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee } else if (r_src1 != rs_rBP) { 449e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu return NewLIR5(is64Bit ? kX86Lea64RA : kX86Lea32RA, r_dest.GetReg(), 450e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu r_src1.GetReg() /* base */, r_src2.GetReg() /* index */, 451e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu 0 /* scale */, 0 /* disp */); 452b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 453e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu return NewLIR5(is64Bit ? kX86Lea64RA : kX86Lea32RA, r_dest.GetReg(), 454e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu r_src2.GetReg() /* base */, r_src1.GetReg() /* index */, 455e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu 0 /* scale */, 0 /* disp */); 456b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 457b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 4581fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegCopy(r_dest, r_src1); 4591fd3346740dfb7f47be9922312b68a4227fada96buzbee return OpRegReg(op, r_dest, r_src2); 460e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 461fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee } else if (r_dest == r_src1) { 4621fd3346740dfb7f47be9922312b68a4227fada96buzbee return OpRegReg(op, r_dest, r_src2); 463fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee } else { // r_dest == r_src2 464b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers switch (op) { 465b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpSub: // non-commutative 4661fd3346740dfb7f47be9922312b68a4227fada96buzbee OpReg(kOpNeg, r_dest); 467b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers op = kOpAdd; 468b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 469b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpSbc: 470b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpLsl: case kOpLsr: case kOpAsr: case kOpRor: { 4712700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee RegStorage t_reg = AllocTemp(); 4721fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegCopy(t_reg, r_src1); 4731fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegReg(op, t_reg, r_src2); 4747a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee LIR* res = OpRegCopyNoInsert(r_dest, t_reg); 4757a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee AppendLIR(res); 4761fd3346740dfb7f47be9922312b68a4227fada96buzbee FreeTemp(t_reg); 477b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers return res; 478b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 479b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpAdd: // commutative 480b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpOr: 481b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpAdc: 482b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpAnd: 483b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpXor: 484b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 485b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers default: 48652a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee LOG(FATAL) << "Bad case in OpRegRegReg " << op; 487e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 4881fd3346740dfb7f47be9922312b68a4227fada96buzbee return OpRegReg(op, r_dest, r_src1); 489b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 490e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 491e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 4922700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpRegRegImm(OpKind op, RegStorage r_dest, RegStorage r_src, int value) { 493e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu if (op == kOpMul && !Gen64Bit()) { 494b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers X86OpCode opcode = IS_SIMM8(value) ? kX86Imul32RRI8 : kX86Imul32RRI; 4952700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return NewLIR3(opcode, r_dest.GetReg(), r_src.GetReg(), value); 496e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu } else if (op == kOpAnd && !Gen64Bit()) { 497091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (value == 0xFF && r_src.Low4()) { 4982700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return NewLIR2(kX86Movzx8RR, r_dest.GetReg(), r_src.GetReg()); 499b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } else if (value == 0xFFFF) { 5002700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return NewLIR2(kX86Movzx16RR, r_dest.GetReg(), r_src.GetReg()); 501b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 502b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 503fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (r_dest != r_src) { 5047934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom if (false && op == kOpLsl && value >= 0 && value <= 3) { // lea shift special case 5057caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers // TODO: fix bug in LEA encoding when disp == 0 5062700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return NewLIR5(kX86Lea32RA, r_dest.GetReg(), r5sib_no_base /* base */, 5072700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee r_src.GetReg() /* index */, value /* scale */, 0 /* disp */); 5087934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom } else if (op == kOpAdd) { // lea add special case 5097e399fd3a99ba9c9dbfafdf14f75dd318fa7d454Chao-ying Fu return NewLIR5(r_dest.Is64Bit() ? kX86Lea64RA : kX86Lea32RA, r_dest.GetReg(), 510e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu r_src.GetReg() /* base */, rs_rX86_SP.GetReg()/*r4sib_no_index*/ /* index */, 511e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu 0 /* scale */, value /* disp */); 512e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 5131fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegCopy(r_dest, r_src); 514b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 5151fd3346740dfb7f47be9922312b68a4227fada96buzbee return OpRegImm(op, r_dest, value); 516e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 517e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 518dd7624d2b9e599d57762d12031b10b89defc9807Ian RogersLIR* X86Mir2Lir::OpThreadMem(OpKind op, ThreadOffset<4> thread_offset) { 5192f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe DCHECK_EQ(kX86, cu_->instruction_set); 5202f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe X86OpCode opcode = kX86Bkpt; 5212f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe switch (op) { 5222f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe case kOpBlx: opcode = kX86CallT; break; 5232f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe case kOpBx: opcode = kX86JmpT; break; 5242f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe default: 5252f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe LOG(FATAL) << "Bad opcode: " << op; 5262f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe break; 5272f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe } 5282f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe return NewLIR1(opcode, thread_offset.Int32Value()); 5292f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe} 5302f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe 5312f244e9faccfcca68af3c5484c397a01a1c3a342Andreas GampeLIR* X86Mir2Lir::OpThreadMem(OpKind op, ThreadOffset<8> thread_offset) { 5322f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe DCHECK_EQ(kX86_64, cu_->instruction_set); 5336cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers X86OpCode opcode = kX86Bkpt; 5346cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers switch (op) { 5356cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers case kOpBlx: opcode = kX86CallT; break; 53660d7a65f7fb60f502160a2e479e86014c7787553Brian Carlstrom case kOpBx: opcode = kX86JmpT; break; 5376cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers default: 5386cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers LOG(FATAL) << "Bad opcode: " << op; 5396cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers break; 5406cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers } 541468532ea115657709bc32ee498e701a4c71762d4Ian Rogers return NewLIR1(opcode, thread_offset.Int32Value()); 5426cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers} 5436cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers 5442700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpMem(OpKind op, RegStorage r_base, int disp) { 5456cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers X86OpCode opcode = kX86Bkpt; 5466cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers switch (op) { 5476cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers case kOpBlx: opcode = kX86CallM; break; 5486cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers default: 5496cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers LOG(FATAL) << "Bad opcode: " << op; 5506cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers break; 5516cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers } 5522700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return NewLIR2(opcode, r_base.GetReg(), disp); 5536cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers} 5546cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers 5552700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::LoadConstantWide(RegStorage r_dest, int64_t value) { 5564ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee int32_t val_lo = Low32Bits(value); 5574ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee int32_t val_hi = High32Bits(value); 5582700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee int32_t low_reg_val = r_dest.IsPair() ? r_dest.GetLowReg() : r_dest.GetReg(); 559e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee LIR *res; 560e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell bool is_fp = r_dest.IsFloat(); 5612700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee // TODO: clean this up once we fully recognize 64-bit storage containers. 5622700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee if (is_fp) { 5634ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (value == 0) { 5642700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee return NewLIR2(kX86XorpsRR, low_reg_val, low_reg_val); 56567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } else if (base_of_code_ != nullptr) { 56667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // We will load the value from the literal area. 56767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell LIR* data_target = ScanLiteralPoolWide(literal_list_, val_lo, val_hi); 56867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell if (data_target == NULL) { 56967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell data_target = AddWideData(&literal_list_, val_lo, val_hi); 57067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } 57167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell 57267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // Address the start of the method 57367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell RegLocation rl_method = mir_graph_->GetRegLocation(base_of_code_->s_reg_low); 574e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu if (rl_method.wide) { 575e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu rl_method = LoadValueWide(rl_method, kCoreReg); 576e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu } else { 577e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu rl_method = LoadValue(rl_method, kCoreReg); 578e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu } 57967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell 58067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // Load the proper value from the literal area. 58167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // We don't know the proper offset for the value, so pick one that will force 58267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // 4 byte offset. We will fix this up in the assembler later to have the right 58367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // value. 5848dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko ScopedMemRefType mem_ref_type(this, ResourceMask::kLiteral); 5850c52451e9be14a6bff9ffefce89ff1d60691af60Mark Mendell res = LoadBaseDisp(rl_method.reg, 256 /* bogus */, RegStorage::FloatSolo64(low_reg_val), 5863bf7c60a86d49bf8c05c5d2ac5ca8e9f80bd9824Vladimir Marko kDouble); 58767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell res->target = data_target; 58867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell res->flags.fixup = kFixupLoad; 58955d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell store_method_addr_used_ = true; 590b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } else { 591fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (val_lo == 0) { 5922700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee res = NewLIR2(kX86XorpsRR, low_reg_val, low_reg_val); 593b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } else { 594d44f1a6027b04c0d080089e6a8d87a4d19b5933fMark Mendell res = LoadConstantNoClobber(RegStorage::FloatSolo32(low_reg_val), val_lo); 595b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 596fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (val_hi != 0) { 5972700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee RegStorage r_dest_hi = AllocTempDouble(); 598091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee LoadConstantNoClobber(r_dest_hi, val_hi); 599091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee NewLIR2(kX86PunpckldqRR, low_reg_val, r_dest_hi.GetReg()); 600d61ba4ba6fcde666adb5d5c81b1c32f0534fb2c8Bill Buzbee FreeTemp(r_dest_hi); 601b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 602b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 603b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } else { 604e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu if (r_dest.IsPair()) { 605e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu res = LoadConstantNoClobber(r_dest.GetLow(), val_lo); 606e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu LoadConstantNoClobber(r_dest.GetHigh(), val_hi); 607e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu } else { 608e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu // TODO(64) make int64_t value parameter of LoadConstantNoClobber 609e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu if (val_lo < 0) { 610e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu val_hi += 1; 611e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu } 612e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu res = LoadConstantNoClobber(RegStorage::Solo32(r_dest.GetReg()), val_hi); 613e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu NewLIR2(kX86Sal64RI, r_dest.GetReg(), 32); 614e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu if (val_lo != 0) { 615e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu NewLIR2(kX86Add64RI, r_dest.GetReg(), val_lo); 616e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu } 617e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu } 618b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 619e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee return res; 620e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 621e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 6222700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::LoadBaseIndexedDisp(RegStorage r_base, RegStorage r_index, int scale, 6233bf7c60a86d49bf8c05c5d2ac5ca8e9f80bd9824Vladimir Marko int displacement, RegStorage r_dest, OpSize size) { 624b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers LIR *load = NULL; 625b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers LIR *load2 = NULL; 6262700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee bool is_array = r_index.Valid(); 627091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee bool pair = r_dest.IsPair(); 628091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee bool is64bit = ((size == k64) || (size == kDouble)); 629b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers X86OpCode opcode = kX86Nop; 630b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers switch (size) { 631695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee case k64: 632b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kDouble: 633091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (r_dest.IsFloat()) { 634fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86MovsdRA : kX86MovsdRM; 635e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu } else if (!pair) { 636e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu opcode = is_array ? kX86Mov64RA : kX86Mov64RM; 637b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 638fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Mov32RA : kX86Mov32RM; 639b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 640b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers // TODO: double store is to unaligned address 641b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ((displacement & 0x3), 0); 642b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 6439ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko case kWord: 6449ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko if (Gen64Bit()) { 6459ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko opcode = is_array ? kX86Mov64RA : kX86Mov64RM; 6469ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko CHECK_EQ(is_array, false); 6479ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko CHECK_EQ(r_dest.IsFloat(), false); 6489ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko break; 6499ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko } // else fall-through to k32 case 650695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee case k32: 651b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kSingle: 652695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee case kReference: // TODO: update for reference decompression on 64-bit targets. 653fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Mov32RA : kX86Mov32RM; 654091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (r_dest.IsFloat()) { 655fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86MovssRA : kX86MovssRM; 656091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK(r_dest.IsFloat()); 657b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 658b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ((displacement & 0x3), 0); 659b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 660b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kUnsignedHalf: 661fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Movzx16RA : kX86Movzx16RM; 662b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ((displacement & 0x1), 0); 663b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 664b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kSignedHalf: 665fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Movsx16RA : kX86Movsx16RM; 666b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ((displacement & 0x1), 0); 667b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 668b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kUnsignedByte: 669fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Movzx8RA : kX86Movzx8RM; 670b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 671b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kSignedByte: 672fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Movsx8RA : kX86Movsx8RM; 673b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 674b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers default: 67552a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee LOG(FATAL) << "Bad case in LoadBaseIndexedDispBody"; 676b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 677b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 678fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (!is_array) { 679b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers if (!pair) { 6802700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee load = NewLIR3(opcode, r_dest.GetReg(), r_base.GetReg(), displacement + LOWORD_OFFSET); 681e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } else { 682091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK(!r_dest.IsFloat()); // Make sure we're not still using a pair here. 683091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (r_base == r_dest.GetLow()) { 684091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee load2 = NewLIR3(opcode, r_dest.GetHighReg(), r_base.GetReg(), 685fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao displacement + HIWORD_OFFSET); 686091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee load = NewLIR3(opcode, r_dest.GetLowReg(), r_base.GetReg(), displacement + LOWORD_OFFSET); 687fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao } else { 688091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee load = NewLIR3(opcode, r_dest.GetLowReg(), r_base.GetReg(), displacement + LOWORD_OFFSET); 689091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee load2 = NewLIR3(opcode, r_dest.GetHighReg(), r_base.GetReg(), 690fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao displacement + HIWORD_OFFSET); 691fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao } 692e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 6938dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko if (mem_ref_type_ == ResourceMask::kDalvikReg) { 6948dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko DCHECK(r_base == rs_rX86_SP); 6951fd3346740dfb7f47be9922312b68a4227fada96buzbee AnnotateDalvikRegAccess(load, (displacement + (pair ? LOWORD_OFFSET : 0)) >> 2, 69602031b185b4653e6c72e21f7a51238b903f6d638buzbee true /* is_load */, is64bit); 697f7d9ad39541dd09030e26d54d3b73a076f90cc74Ian Rogers if (pair) { 6981fd3346740dfb7f47be9922312b68a4227fada96buzbee AnnotateDalvikRegAccess(load2, (displacement + HIWORD_OFFSET) >> 2, 699fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee true /* is_load */, is64bit); 700b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 701e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 702b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 703b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers if (!pair) { 7042700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee load = NewLIR5(opcode, r_dest.GetReg(), r_base.GetReg(), r_index.GetReg(), scale, 705a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee displacement + LOWORD_OFFSET); 706b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 707091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK(!r_dest.IsFloat()); // Make sure we're not still using a pair here. 708091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (r_base == r_dest.GetLow()) { 709091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (r_dest.GetHigh() == r_index) { 710ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell // We can't use either register for the first load. 7112700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee RegStorage temp = AllocTemp(); 7122700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee load2 = NewLIR5(opcode, temp.GetReg(), r_base.GetReg(), r_index.GetReg(), scale, 713ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell displacement + HIWORD_OFFSET); 714091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee load = NewLIR5(opcode, r_dest.GetLowReg(), r_base.GetReg(), r_index.GetReg(), scale, 715ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell displacement + LOWORD_OFFSET); 716091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee OpRegCopy(r_dest.GetHigh(), temp); 717ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell FreeTemp(temp); 718ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell } else { 719091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee load2 = NewLIR5(opcode, r_dest.GetHighReg(), r_base.GetReg(), r_index.GetReg(), scale, 720ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell displacement + HIWORD_OFFSET); 721091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee load = NewLIR5(opcode, r_dest.GetLowReg(), r_base.GetReg(), r_index.GetReg(), scale, 722ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell displacement + LOWORD_OFFSET); 723ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell } 724fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao } else { 725091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (r_dest.GetLow() == r_index) { 726ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell // We can't use either register for the first load. 7272700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee RegStorage temp = AllocTemp(); 7282700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee load = NewLIR5(opcode, temp.GetReg(), r_base.GetReg(), r_index.GetReg(), scale, 729ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell displacement + LOWORD_OFFSET); 730091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee load2 = NewLIR5(opcode, r_dest.GetHighReg(), r_base.GetReg(), r_index.GetReg(), scale, 731ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell displacement + HIWORD_OFFSET); 732091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee OpRegCopy(r_dest.GetLow(), temp); 733ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell FreeTemp(temp); 734ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell } else { 735091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee load = NewLIR5(opcode, r_dest.GetLowReg(), r_base.GetReg(), r_index.GetReg(), scale, 736ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell displacement + LOWORD_OFFSET); 737091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee load2 = NewLIR5(opcode, r_dest.GetHighReg(), r_base.GetReg(), r_index.GetReg(), scale, 738ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell displacement + HIWORD_OFFSET); 739ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell } 740fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao } 741b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 742b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 743b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 744b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers return load; 745e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 746e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 7475772babbe824494ef9fe90a1b07a926d124bb7c7jeffhao/* Load value from base + scaled index. */ 7482700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::LoadBaseIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_dest, 7492700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee int scale, OpSize size) { 7503bf7c60a86d49bf8c05c5d2ac5ca8e9f80bd9824Vladimir Marko return LoadBaseIndexedDisp(r_base, r_index, scale, 0, r_dest, size); 7515772babbe824494ef9fe90a1b07a926d124bb7c7jeffhao} 7525772babbe824494ef9fe90a1b07a926d124bb7c7jeffhao 753674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir MarkoLIR* X86Mir2Lir::LoadBaseDispVolatile(RegStorage r_base, int displacement, RegStorage r_dest, 754674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko OpSize size) { 755674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko // LoadBaseDisp() will emit correct insn for atomic load on x86 756674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko // assuming r_dest is correctly prepared using RegClassForFieldLoadStore(). 757674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko return LoadBaseDisp(r_base, displacement, r_dest, size); 758674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko} 759674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko 760091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbeeLIR* X86Mir2Lir::LoadBaseDisp(RegStorage r_base, int displacement, RegStorage r_dest, 7613bf7c60a86d49bf8c05c5d2ac5ca8e9f80bd9824Vladimir Marko OpSize size) { 762091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee return LoadBaseIndexedDisp(r_base, RegStorage::InvalidReg(), 0, displacement, r_dest, 7633bf7c60a86d49bf8c05c5d2ac5ca8e9f80bd9824Vladimir Marko size); 764e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 765e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 7662700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::StoreBaseIndexedDisp(RegStorage r_base, RegStorage r_index, int scale, 7673bf7c60a86d49bf8c05c5d2ac5ca8e9f80bd9824Vladimir Marko int displacement, RegStorage r_src, OpSize size) { 768b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers LIR *store = NULL; 769e296248a124ed8287b38a9225463696c18d84cd6jeffhao LIR *store2 = NULL; 7702700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee bool is_array = r_index.Valid(); 771091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee bool pair = r_src.IsPair(); 772091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee bool is64bit = (size == k64) || (size == kDouble); 773b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers X86OpCode opcode = kX86Nop; 774b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers switch (size) { 775695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee case k64: 776b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kDouble: 777091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (r_src.IsFloat()) { 778fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86MovsdAR : kX86MovsdMR; 779e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu } else if (!pair) { 780e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu opcode = is_array ? kX86Mov64AR : kX86Mov64MR; 781b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 782e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu opcode = is_array ? kX86Mov32AR : kX86Mov32MR; 783b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 784b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers // TODO: double store is to unaligned address 785b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ((displacement & 0x3), 0); 786b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 7879ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko case kWord: 7889ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko if (Gen64Bit()) { 7899ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko opcode = is_array ? kX86Mov64AR : kX86Mov64MR; 7909ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko CHECK_EQ(is_array, false); 7919ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko CHECK_EQ(r_src.IsFloat(), false); 7929ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko break; 7939ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko } // else fall-through to k32 case 794695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee case k32: 795b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kSingle: 796695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee case kReference: 797fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Mov32AR : kX86Mov32MR; 798091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (r_src.IsFloat()) { 799fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86MovssAR : kX86MovssMR; 800091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK(r_src.IsSingle()); 801b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 802b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ((displacement & 0x3), 0); 803b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 804b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kUnsignedHalf: 805b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kSignedHalf: 806fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Mov16AR : kX86Mov16MR; 807b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ((displacement & 0x1), 0); 808b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 809b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kUnsignedByte: 810b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kSignedByte: 811fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Mov8AR : kX86Mov8MR; 812b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 813b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers default: 81400e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee LOG(FATAL) << "Bad case in StoreBaseIndexedDispBody"; 815b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 816b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 817fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (!is_array) { 818b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers if (!pair) { 8192700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee store = NewLIR3(opcode, r_base.GetReg(), displacement + LOWORD_OFFSET, r_src.GetReg()); 820b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } else { 821091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK(!r_src.IsFloat()); // Make sure we're not still using a pair here. 822091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee store = NewLIR3(opcode, r_base.GetReg(), displacement + LOWORD_OFFSET, r_src.GetLowReg()); 823091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee store2 = NewLIR3(opcode, r_base.GetReg(), displacement + HIWORD_OFFSET, r_src.GetHighReg()); 824e296248a124ed8287b38a9225463696c18d84cd6jeffhao } 8258dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko if (mem_ref_type_ == ResourceMask::kDalvikReg) { 8268dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko DCHECK(r_base == rs_rX86_SP); 8271fd3346740dfb7f47be9922312b68a4227fada96buzbee AnnotateDalvikRegAccess(store, (displacement + (pair ? LOWORD_OFFSET : 0)) >> 2, 82802031b185b4653e6c72e21f7a51238b903f6d638buzbee false /* is_load */, is64bit); 829e296248a124ed8287b38a9225463696c18d84cd6jeffhao if (pair) { 8301fd3346740dfb7f47be9922312b68a4227fada96buzbee AnnotateDalvikRegAccess(store2, (displacement + HIWORD_OFFSET) >> 2, 831fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee false /* is_load */, is64bit); 832e296248a124ed8287b38a9225463696c18d84cd6jeffhao } 833b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 834b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 835b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers if (!pair) { 8362700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee store = NewLIR5(opcode, r_base.GetReg(), r_index.GetReg(), scale, 8372700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee displacement + LOWORD_OFFSET, r_src.GetReg()); 838b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } else { 839091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK(!r_src.IsFloat()); // Make sure we're not still using a pair here. 8402700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee store = NewLIR5(opcode, r_base.GetReg(), r_index.GetReg(), scale, 841091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee displacement + LOWORD_OFFSET, r_src.GetLowReg()); 8422700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee store2 = NewLIR5(opcode, r_base.GetReg(), r_index.GetReg(), scale, 843091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee displacement + HIWORD_OFFSET, r_src.GetHighReg()); 844e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 845b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 846b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers return store; 847e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 848e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 849c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers/* store value base base + scaled index. */ 8502700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::StoreBaseIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_src, 8512ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom int scale, OpSize size) { 8523bf7c60a86d49bf8c05c5d2ac5ca8e9f80bd9824Vladimir Marko return StoreBaseIndexedDisp(r_base, r_index, scale, 0, r_src, size); 853c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers} 854c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers 855674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir MarkoLIR* X86Mir2Lir::StoreBaseDispVolatile(RegStorage r_base, int displacement, 856674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko RegStorage r_src, OpSize size) { 857674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko // StoreBaseDisp() will emit correct insn for atomic store on x86 858674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko // assuming r_dest is correctly prepared using RegClassForFieldLoadStore(). 859674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko return StoreBaseDisp(r_base, displacement, r_src, size); 860674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko} 861674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko 8622700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::StoreBaseDisp(RegStorage r_base, int displacement, 8632700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee RegStorage r_src, OpSize size) { 8643bf7c60a86d49bf8c05c5d2ac5ca8e9f80bd9824Vladimir Marko return StoreBaseIndexedDisp(r_base, RegStorage::InvalidReg(), 0, displacement, r_src, size); 865e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 866e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 8672700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpCmpMemImmBranch(ConditionCode cond, RegStorage temp_reg, RegStorage base_reg, 868766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell int offset, int check_value, LIR* target) { 8692700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee NewLIR3(IS_SIMM8(check_value) ? kX86Cmp32MI8 : kX86Cmp32MI, base_reg.GetReg(), offset, 870766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell check_value); 871766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell LIR* branch = OpCondBranch(cond, target); 872766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell return branch; 873766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell} 874766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell 87567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendellvoid X86Mir2Lir::AnalyzeMIR() { 87667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // Assume we don't need a pointer to the base of the code. 87767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell cu_->NewTimingSplit("X86 MIR Analysis"); 87867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell store_method_addr_ = false; 87967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell 88067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // Walk the MIR looking for interesting items. 88167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell PreOrderDfsIterator iter(mir_graph_); 88267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell BasicBlock* curr_bb = iter.Next(); 88367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell while (curr_bb != NULL) { 88467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell AnalyzeBB(curr_bb); 88567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell curr_bb = iter.Next(); 88667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } 88767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell 88867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // Did we need a pointer to the method code? 88967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell if (store_method_addr_) { 890e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu base_of_code_ = mir_graph_->GetNewCompilerTemp(kCompilerTempVR, Gen64Bit() == true); 89167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } else { 89267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell base_of_code_ = nullptr; 89367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } 89467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell} 89567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell 89667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendellvoid X86Mir2Lir::AnalyzeBB(BasicBlock * bb) { 89767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell if (bb->block_type == kDead) { 89867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // Ignore dead blocks 89967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell return; 90067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } 90167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell 90267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell for (MIR *mir = bb->first_mir_insn; mir != NULL; mir = mir->next) { 90367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell int opcode = mir->dalvikInsn.opcode; 90435ba7f3a78d38885ec54e61ed060d2771eeceea7buzbee if (MIRGraph::IsPseudoMirOp(opcode)) { 90567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell AnalyzeExtendedMIR(opcode, bb, mir); 90667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } else { 90767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell AnalyzeMIR(opcode, bb, mir); 90867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } 90967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } 91067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell} 91167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell 91267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell 91367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendellvoid X86Mir2Lir::AnalyzeExtendedMIR(int opcode, BasicBlock * bb, MIR *mir) { 91467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell switch (opcode) { 91567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // Instructions referencing doubles. 91667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell case kMirOpFusedCmplDouble: 91767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell case kMirOpFusedCmpgDouble: 91867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell AnalyzeFPInstruction(opcode, bb, mir); 91967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell break; 920d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell case kMirOpConstVector: 921d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell store_method_addr_ = true; 922d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell break; 92367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell default: 92467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // Ignore the rest. 92567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell break; 92667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } 92767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell} 92867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell 92967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendellvoid X86Mir2Lir::AnalyzeMIR(int opcode, BasicBlock * bb, MIR *mir) { 93067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // Looking for 93167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // - Do we need a pointer to the code (used for packed switches and double lits)? 93267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell 93367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell switch (opcode) { 93467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // Instructions referencing doubles. 93567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell case Instruction::CMPL_DOUBLE: 93667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell case Instruction::CMPG_DOUBLE: 93767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell case Instruction::NEG_DOUBLE: 93867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell case Instruction::ADD_DOUBLE: 93967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell case Instruction::SUB_DOUBLE: 94067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell case Instruction::MUL_DOUBLE: 94167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell case Instruction::DIV_DOUBLE: 94267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell case Instruction::REM_DOUBLE: 94367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell case Instruction::ADD_DOUBLE_2ADDR: 94467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell case Instruction::SUB_DOUBLE_2ADDR: 94567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell case Instruction::MUL_DOUBLE_2ADDR: 94667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell case Instruction::DIV_DOUBLE_2ADDR: 94767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell case Instruction::REM_DOUBLE_2ADDR: 94867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell AnalyzeFPInstruction(opcode, bb, mir); 94967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell break; 95055d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell 95167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // Packed switches and array fills need a pointer to the base of the method. 95267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell case Instruction::FILL_ARRAY_DATA: 95367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell case Instruction::PACKED_SWITCH: 95467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell store_method_addr_ = true; 95567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell break; 95667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell default: 95767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // Other instructions are not interesting yet. 95867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell break; 95967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } 96067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell} 96167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell 96267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendellvoid X86Mir2Lir::AnalyzeFPInstruction(int opcode, BasicBlock * bb, MIR *mir) { 96367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // Look at all the uses, and see if they are double constants. 964cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyler uint64_t attrs = MIRGraph::GetDataFlowAttributes(static_cast<Instruction::Code>(opcode)); 96567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell int next_sreg = 0; 96667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell if (attrs & DF_UA) { 96767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell if (attrs & DF_A_WIDE) { 96867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell AnalyzeDoubleUse(mir_graph_->GetSrcWide(mir, next_sreg)); 96967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell next_sreg += 2; 97067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } else { 97167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell next_sreg++; 97267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } 97367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } 97467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell if (attrs & DF_UB) { 97567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell if (attrs & DF_B_WIDE) { 97667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell AnalyzeDoubleUse(mir_graph_->GetSrcWide(mir, next_sreg)); 97767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell next_sreg += 2; 97867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } else { 97967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell next_sreg++; 98067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } 98167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } 98267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell if (attrs & DF_UC) { 98367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell if (attrs & DF_C_WIDE) { 98467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell AnalyzeDoubleUse(mir_graph_->GetSrcWide(mir, next_sreg)); 98567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } 98667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } 98767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell} 98867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell 98967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendellvoid X86Mir2Lir::AnalyzeDoubleUse(RegLocation use) { 99067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell // If this is a double literal, we will want it in the literal pool. 99167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell if (use.is_const) { 99267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell store_method_addr_ = true; 99367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } 99467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell} 99567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell 99630adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbeeRegLocation X86Mir2Lir::UpdateLocTyped(RegLocation loc, int reg_class) { 99730adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee loc = UpdateLoc(loc); 99830adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee if ((loc.location == kLocPhysReg) && (loc.fp != loc.reg.IsFloat())) { 99930adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee if (GetRegInfo(loc.reg)->IsTemp()) { 100030adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee Clobber(loc.reg); 100130adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee FreeTemp(loc.reg); 100230adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee loc.reg = RegStorage::InvalidReg(); 100330adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee loc.location = kLocDalvikFrame; 100430adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee } 100530adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee } 1006e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu DCHECK(CheckCorePoolSanity()); 100730adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee return loc; 100830adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee} 100930adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee 101030adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbeeRegLocation X86Mir2Lir::UpdateLocWideTyped(RegLocation loc, int reg_class) { 101130adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee loc = UpdateLocWide(loc); 101230adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee if ((loc.location == kLocPhysReg) && (loc.fp != loc.reg.IsFloat())) { 101330adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee if (GetRegInfo(loc.reg)->IsTemp()) { 101430adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee Clobber(loc.reg); 101530adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee FreeTemp(loc.reg); 101630adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee loc.reg = RegStorage::InvalidReg(); 101730adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee loc.location = kLocDalvikFrame; 101830adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee } 101930adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee } 1020e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu DCHECK(CheckCorePoolSanity()); 102130adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee return loc; 102230adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee} 1023e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} // namespace art 1024