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