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"
180b9203e7996ee1856f620f95d95d8a273c43a3dfAndreas Gampe
190b9203e7996ee1856f620f95d95d8a273c43a3dfAndreas Gampe#include "base/logging.h"
201961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko#include "dex/mir_graph.h"
217940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "dex/quick/mir_to_lir-inl.h"
2267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell#include "dex/dataflow_iterator-inl.h"
237071c8d5885175a746723a3b38a347855965be08Yixin Shou#include "dex/quick/dex_file_method_inliner.h"
247071c8d5885175a746723a3b38a347855965be08Yixin Shou#include "dex/quick/dex_file_to_method_inliner_map.h"
25b5860fb459f1ed71f39d8a87b45bee6727d79fe8buzbee#include "dex/reg_storage_eq.h"
260b9203e7996ee1856f620f95d95d8a273c43a3dfAndreas Gampe#include "driver/compiler_driver.h"
270b9203e7996ee1856f620f95d95d8a273c43a3dfAndreas Gampe#include "x86_lir.h"
281bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee
29e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbeenamespace art {
30e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
31b046e16d8b8da318d6055f9308950131f1255e08buzbee/* This file contains codegen for the X86 ISA */
32e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
332700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpFpRegCopy(RegStorage r_dest, RegStorage r_src) {
34a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  int opcode;
35a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /* must be both DOUBLE or both not DOUBLE */
36091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  DCHECK(r_dest.IsFloat() || r_src.IsFloat());
37091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  DCHECK_EQ(r_dest.IsDouble(), r_src.IsDouble());
38091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  if (r_dest.IsDouble()) {
39a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    opcode = kX86MovsdRR;
40a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  } else {
41091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee    if (r_dest.IsSingle()) {
42091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      if (r_src.IsSingle()) {
43a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee        opcode = kX86MovssRR;
44a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      } else {  // Fpr <- Gpr
45a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee        opcode = kX86MovdxrRR;
46a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      }
47a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    } else {  // Gpr <- Fpr
48091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      DCHECK(r_src.IsSingle()) << "Raw: 0x" << std::hex << r_src.GetRawBits();
49a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      opcode = kX86MovdrxRR;
50e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee    }
51a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
52ec13743da80a80c1817cf6660c28917fc28846bcbuzbee  DCHECK_NE((EncodingMap[opcode].flags & IS_BINARY_OP), 0ULL);
532700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  LIR* res = RawLIR(current_dalvik_offset_, opcode, r_dest.GetReg(), r_src.GetReg());
54fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (r_dest == r_src) {
55fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    res->flags.is_nop = true;
56a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
57a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  return res;
58e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee}
59e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
602ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool X86Mir2Lir::InexpensiveConstantInt(int32_t value) {
616a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  UNUSED(value);
62e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee  return true;
63e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee}
64e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee
652ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool X86Mir2Lir::InexpensiveConstantFloat(int32_t value) {
666a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  return value == 0;
674ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee}
684ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee
692ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool X86Mir2Lir::InexpensiveConstantLong(int64_t value) {
706a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  UNUSED(value);
714ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee  return true;
724ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee}
734ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee
742ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool X86Mir2Lir::InexpensiveConstantDouble(int64_t value) {
7567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  return value == 0;
764ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee}
774ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee
78e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee/*
79e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * Load a immediate using a shortcut if possible; otherwise
80e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * grab from the per-translation literal pool.  If target is
81e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * a high register, build constant into a low register and copy.
82e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee *
83e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * No additional register clobbering operation performed. Use this version when
84fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee * 1) r_dest is freshly returned from AllocTemp or
85e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * 2) The codegen is under fixed register usage
86e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee */
872700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::LoadConstantNoClobber(RegStorage r_dest, int value) {
882700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  RegStorage r_dest_save = r_dest;
89091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  if (r_dest.IsFloat()) {
90b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers    if (value == 0) {
912700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      return NewLIR2(kX86XorpsRR, r_dest.GetReg(), r_dest.GetReg());
92b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers    }
931fd3346740dfb7f47be9922312b68a4227fada96buzbee    r_dest = AllocTemp();
946cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers  }
95e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
96b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers  LIR *res;
976cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers  if (value == 0) {
982700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    res = NewLIR2(kX86Xor32RR, r_dest.GetReg(), r_dest.GetReg());
996cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers  } else {
1002e9f7ed8d00271cb1cf082d68b4f4bc60702d6ecIan Rogers    // Note, there is no byte immediate form of a 32 bit immediate move.
101e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    // 64-bit immediate is not supported by LIR structure
102e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    res = NewLIR2(kX86Mov32RI, r_dest.GetReg(), value);
1036cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers  }
104e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
105091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  if (r_dest_save.IsFloat()) {
1062700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    NewLIR2(kX86MovdxrRR, r_dest_save.GetReg(), r_dest.GetReg());
1071fd3346740dfb7f47be9922312b68a4227fada96buzbee    FreeTemp(r_dest);
1086cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers  }
109e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
1106cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers  return res;
111e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee}
112e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
1132ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* X86Mir2Lir::OpUnconditionalBranch(LIR* target) {
114df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom  LIR* res = NewLIR1(kX86Jmp8, 0 /* offset to be patched during assembly*/);
11502031b185b4653e6c72e21f7a51238b903f6d638buzbee  res->target = target;
11602031b185b4653e6c72e21f7a51238b903f6d638buzbee  return res;
117e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee}
118e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
1192ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* X86Mir2Lir::OpCondBranch(ConditionCode cc, LIR* target) {
1201fd3346740dfb7f47be9922312b68a4227fada96buzbee  LIR* branch = NewLIR2(kX86Jcc8, 0 /* offset to be patched */,
12152a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee                        X86ConditionEncoding(cc));
122b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  branch->target = target;
123b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  return branch;
124a7678db092ac6bb79f7cad490099a1015fbbc714buzbee}
125a7678db092ac6bb79f7cad490099a1015fbbc714buzbee
1262700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpReg(OpKind op, RegStorage r_dest_src) {
127b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  X86OpCode opcode = kX86Bkpt;
128b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  switch (op) {
129e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    case kOpNeg: opcode = r_dest_src.Is64Bit() ? kX86Neg64R : kX86Neg32R; break;
130e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    case kOpNot: opcode = r_dest_src.Is64Bit() ? kX86Not64R : kX86Not32R; break;
131c5e4ce116e4d44bfdf162f0c949e77772d7e0654nikolay serdjuk    case kOpRev: opcode = r_dest_src.Is64Bit() ? kX86Bswap64R : kX86Bswap32R; break;
132b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kOpBlx: opcode = kX86CallR; break;
133b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    default:
13452a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee      LOG(FATAL) << "Bad case in OpReg " << op;
135b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  }
1362700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  return NewLIR1(opcode, r_dest_src.GetReg());
137e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee}
138e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
1392700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpRegImm(OpKind op, RegStorage r_dest_src1, int value) {
140b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  X86OpCode opcode = kX86Bkpt;
141fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  bool byte_imm = IS_SIMM8(value);
142091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  DCHECK(!r_dest_src1.IsFloat());
1439ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko  if (r_dest_src1.Is64Bit()) {
1449ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko    switch (op) {
1459ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      case kOpAdd: opcode = byte_imm ? kX86Add64RI8 : kX86Add64RI; break;
1469ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      case kOpSub: opcode = byte_imm ? kX86Sub64RI8 : kX86Sub64RI; break;
147e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      case kOpLsl: opcode = kX86Sal64RI; break;
148e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      case kOpLsr: opcode = kX86Shr64RI; break;
149e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      case kOpAsr: opcode = kX86Sar64RI; break;
1507e399fd3a99ba9c9dbfafdf14f75dd318fa7d454Chao-ying Fu      case kOpCmp: opcode = byte_imm ? kX86Cmp64RI8 : kX86Cmp64RI; break;
1519ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      default:
1529ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko        LOG(FATAL) << "Bad case in OpRegImm (64-bit) " << op;
1539ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko    }
1549ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko  } else {
1559ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko    switch (op) {
1569ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      case kOpLsl: opcode = kX86Sal32RI; break;
1579ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      case kOpLsr: opcode = kX86Shr32RI; break;
1589ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      case kOpAsr: opcode = kX86Sar32RI; break;
1599ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      case kOpAdd: opcode = byte_imm ? kX86Add32RI8 : kX86Add32RI; break;
1609ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      case kOpOr:  opcode = byte_imm ? kX86Or32RI8  : kX86Or32RI;  break;
1619ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      case kOpAdc: opcode = byte_imm ? kX86Adc32RI8 : kX86Adc32RI; break;
1629ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      // case kOpSbb: opcode = kX86Sbb32RI; break;
1639ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      case kOpAnd: opcode = byte_imm ? kX86And32RI8 : kX86And32RI; break;
1649ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      case kOpSub: opcode = byte_imm ? kX86Sub32RI8 : kX86Sub32RI; break;
1659ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      case kOpXor: opcode = byte_imm ? kX86Xor32RI8 : kX86Xor32RI; break;
1669ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      case kOpCmp: opcode = byte_imm ? kX86Cmp32RI8 : kX86Cmp32RI; break;
1679ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      case kOpMov:
1689ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko        /*
1699ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko         * Moving the constant zero into register can be specialized as an xor of the register.
1709ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko         * However, that sets eflags while the move does not. For that reason here, always do
1719ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko         * the move and if caller is flexible, they should be calling LoadConstantNoClobber instead.
1729ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko         */
1739ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko        opcode = kX86Mov32RI;
1749ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko        break;
1759ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      case kOpMul:
1769ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko        opcode = byte_imm ? kX86Imul32RRI8 : kX86Imul32RRI;
1779ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko        return NewLIR3(opcode, r_dest_src1.GetReg(), r_dest_src1.GetReg(), value);
178e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell      case kOp2Byte:
179e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell        opcode = kX86Mov32RI;
180e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell        value = static_cast<int8_t>(value);
181e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell        break;
182e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell      case kOp2Short:
183e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell        opcode = kX86Mov32RI;
184e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell        value = static_cast<int16_t>(value);
185e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell        break;
186e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell      case kOp2Char:
187e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell        opcode = kX86Mov32RI;
188e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell        value = static_cast<uint16_t>(value);
189e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell        break;
190e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell      case kOpNeg:
191e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell        opcode = kX86Mov32RI;
192e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell        value = -value;
193e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell        break;
1949ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      default:
1959ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko        LOG(FATAL) << "Bad case in OpRegImm " << op;
1969ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko    }
197b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  }
1982700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  return NewLIR2(opcode, r_dest_src1.GetReg(), value);
199e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee}
200e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
2012700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpRegReg(OpKind op, RegStorage r_dest_src1, RegStorage r_src2) {
202e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    bool is64Bit = r_dest_src1.Is64Bit();
203a7678db092ac6bb79f7cad490099a1015fbbc714buzbee    X86OpCode opcode = kX86Nop;
204d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers    bool src2_must_be_cx = false;
205e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee    switch (op) {
206b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers        // X86 unary opcodes
207b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      case kOpMvn:
2081fd3346740dfb7f47be9922312b68a4227fada96buzbee        OpRegCopy(r_dest_src1, r_src2);
2091fd3346740dfb7f47be9922312b68a4227fada96buzbee        return OpReg(kOpNot, r_dest_src1);
210b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      case kOpNeg:
2111fd3346740dfb7f47be9922312b68a4227fada96buzbee        OpRegCopy(r_dest_src1, r_src2);
2121fd3346740dfb7f47be9922312b68a4227fada96buzbee        return OpReg(kOpNeg, r_dest_src1);
213a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko      case kOpRev:
214a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko        OpRegCopy(r_dest_src1, r_src2);
215a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko        return OpReg(kOpRev, r_dest_src1);
216a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko      case kOpRevsh:
217a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko        OpRegCopy(r_dest_src1, r_src2);
218a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko        OpReg(kOpRev, r_dest_src1);
219a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko        return OpRegImm(kOpAsr, r_dest_src1, 16);
220b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers        // X86 binary opcodes
221e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      case kOpSub: opcode = is64Bit ? kX86Sub64RR : kX86Sub32RR; break;
222e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      case kOpSbc: opcode = is64Bit ? kX86Sbb64RR : kX86Sbb32RR; break;
223e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      case kOpLsl: opcode = is64Bit ? kX86Sal64RC : kX86Sal32RC; src2_must_be_cx = true; break;
224e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      case kOpLsr: opcode = is64Bit ? kX86Shr64RC : kX86Shr32RC; src2_must_be_cx = true; break;
225e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      case kOpAsr: opcode = is64Bit ? kX86Sar64RC : kX86Sar32RC; src2_must_be_cx = true; break;
226e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      case kOpMov: opcode = is64Bit ? kX86Mov64RR : kX86Mov32RR; break;
227e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      case kOpCmp: opcode = is64Bit ? kX86Cmp64RR : kX86Cmp32RR; break;
228e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      case kOpAdd: opcode = is64Bit ? kX86Add64RR : kX86Add32RR; break;
229e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      case kOpAdc: opcode = is64Bit ? kX86Adc64RR : kX86Adc32RR; break;
230e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      case kOpAnd: opcode = is64Bit ? kX86And64RR : kX86And32RR; break;
231e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      case kOpOr:  opcode = is64Bit ? kX86Or64RR : kX86Or32RR; break;
232e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      case kOpXor: opcode = is64Bit ? kX86Xor64RR : kX86Xor32RR; break;
233703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao      case kOp2Byte:
234091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee        // TODO: there are several instances of this check.  A utility function perhaps?
235091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee        // TODO: Similar to Arm's reg < 8 check.  Perhaps add attribute checks to RegStorage?
236703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao        // Use shifts instead of a byte operand if the source can't be byte accessed.
237b28c1c06236751aa5c9e64dcb68b3c940341e496Ian Rogers        if (r_src2.GetRegNum() >= rs_rX86_SP_32.GetRegNum()) {
238e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu          NewLIR2(is64Bit ? kX86Mov64RR : kX86Mov32RR, r_dest_src1.GetReg(), r_src2.GetReg());
239e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu          NewLIR2(is64Bit ? kX86Sal64RI : kX86Sal32RI, r_dest_src1.GetReg(), is64Bit ? 56 : 24);
240e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu          return NewLIR2(is64Bit ? kX86Sar64RI : kX86Sar32RI, r_dest_src1.GetReg(),
241e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu                         is64Bit ? 56 : 24);
242703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao        } else {
243e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu          opcode = is64Bit ? kX86Bkpt : kX86Movsx8RR;
244703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao        }
245703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao        break;
246e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      case kOp2Short: opcode = is64Bit ? kX86Bkpt : kX86Movsx16RR; break;
247e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      case kOp2Char: opcode = is64Bit ? kX86Bkpt : kX86Movzx16RR; break;
248e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      case kOpMul: opcode = is64Bit ? kX86Bkpt : kX86Imul32RR; break;
249b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      default:
25052a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee        LOG(FATAL) << "Bad case in OpRegReg " << op;
251b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers        break;
252e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee    }
253091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee    CHECK(!src2_must_be_cx || r_src2.GetReg() == rs_rCX.GetReg());
2542700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    return NewLIR2(opcode, r_dest_src1.GetReg(), r_src2.GetReg());
255e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee}
256e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
2572700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpMovRegMem(RegStorage r_dest, RegStorage r_base, int offset, MoveType move_type) {
258091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  DCHECK(!r_base.IsFloat());
2592c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru  X86OpCode opcode = kX86Nop;
2602700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  int dest = r_dest.IsPair() ? r_dest.GetLowReg() : r_dest.GetReg();
2612c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru  switch (move_type) {
2622c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMov8GP:
263091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(!r_dest.IsFloat());
2642c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86Mov8RM;
2652c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
2662c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMov16GP:
267091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(!r_dest.IsFloat());
2682c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86Mov16RM;
2692c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
2702c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMov32GP:
271091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(!r_dest.IsFloat());
2722c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86Mov32RM;
2732c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
2742c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMov32FP:
275091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(r_dest.IsFloat());
2762c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86MovssRM;
2772c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
2782c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMov64FP:
279091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(r_dest.IsFloat());
2802c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86MovsdRM;
2812c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
2822c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMovU128FP:
283091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(r_dest.IsFloat());
2842c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86MovupsRM;
2852c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
2862c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMovA128FP:
287091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(r_dest.IsFloat());
2882c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86MovapsRM;
2892c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
2902c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMovLo128FP:
291091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(r_dest.IsFloat());
2922c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86MovlpsRM;
2932c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
2942c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMovHi128FP:
295091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(r_dest.IsFloat());
2962c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86MovhpsRM;
2972c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
2982c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMov64GP:
2992c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMovLo64FP:
3002c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMovHi64FP:
3012c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    default:
3022c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      LOG(FATAL) << "Bad case in OpMovRegMem";
3032c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
3042c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru  }
3052c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru
3062700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  return NewLIR3(opcode, dest, r_base.GetReg(), offset);
3072c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru}
3082c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru
3092700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpMovMemReg(RegStorage r_base, int offset, RegStorage r_src, MoveType move_type) {
310091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  DCHECK(!r_base.IsFloat());
3112700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  int src = r_src.IsPair() ? r_src.GetLowReg() : r_src.GetReg();
3122c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru
3132c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru  X86OpCode opcode = kX86Nop;
3142c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru  switch (move_type) {
3152c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMov8GP:
316091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(!r_src.IsFloat());
3172c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86Mov8MR;
3182c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
3192c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMov16GP:
320091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(!r_src.IsFloat());
3212c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86Mov16MR;
3222c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
3232c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMov32GP:
324091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(!r_src.IsFloat());
3252c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86Mov32MR;
3262c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
3272c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMov32FP:
328091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(r_src.IsFloat());
3292c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86MovssMR;
3302c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
3312c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMov64FP:
332091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(r_src.IsFloat());
3332c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86MovsdMR;
3342c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
3352c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMovU128FP:
336091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(r_src.IsFloat());
3372c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86MovupsMR;
3382c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
3392c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMovA128FP:
340091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(r_src.IsFloat());
3412c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86MovapsMR;
3422c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
3432c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMovLo128FP:
344091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(r_src.IsFloat());
3452c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86MovlpsMR;
3462c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
3472c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMovHi128FP:
348091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(r_src.IsFloat());
3492c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86MovhpsMR;
3502c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
3512c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMov64GP:
3522c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMovLo64FP:
3532c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMovHi64FP:
3542c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    default:
3552c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      LOG(FATAL) << "Bad case in OpMovMemReg";
3562c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
3572c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru  }
3582c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru
3592700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  return NewLIR3(opcode, r_base.GetReg(), offset, src);
3602c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru}
3612c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru
3622700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpCondRegReg(OpKind op, ConditionCode cc, RegStorage r_dest, RegStorage r_src) {
363bd288c2c1206bc99fafebfb9120a83f13cf9723bRazvan A Lupusoru  // The only conditional reg to reg operation supported is Cmov
364bd288c2c1206bc99fafebfb9120a83f13cf9723bRazvan A Lupusoru  DCHECK_EQ(op, kOpCmov);
365c5e4ce116e4d44bfdf162f0c949e77772d7e0654nikolay serdjuk  DCHECK_EQ(r_dest.Is64Bit(), r_src.Is64Bit());
366c5e4ce116e4d44bfdf162f0c949e77772d7e0654nikolay serdjuk  return NewLIR3(r_dest.Is64Bit() ? kX86Cmov64RRC : kX86Cmov32RRC, r_dest.GetReg(),
367c5e4ce116e4d44bfdf162f0c949e77772d7e0654nikolay serdjuk                 r_src.GetReg(), X86ConditionEncoding(cc));
368bd288c2c1206bc99fafebfb9120a83f13cf9723bRazvan A Lupusoru}
369bd288c2c1206bc99fafebfb9120a83f13cf9723bRazvan A Lupusoru
3702700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpRegMem(OpKind op, RegStorage r_dest, RegStorage r_base, int offset) {
371e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu  bool is64Bit = r_dest.Is64Bit();
372b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  X86OpCode opcode = kX86Nop;
373b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  switch (op) {
374b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      // X86 binary opcodes
375e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    case kOpSub: opcode = is64Bit ? kX86Sub64RM : kX86Sub32RM; break;
376e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    case kOpMov: opcode = is64Bit ? kX86Mov64RM : kX86Mov32RM; break;
377e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    case kOpCmp: opcode = is64Bit ? kX86Cmp64RM : kX86Cmp32RM; break;
378e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    case kOpAdd: opcode = is64Bit ? kX86Add64RM : kX86Add32RM; break;
379e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    case kOpAnd: opcode = is64Bit ? kX86And64RM : kX86And32RM; break;
380e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    case kOpOr:  opcode = is64Bit ? kX86Or64RM : kX86Or32RM; break;
381e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    case kOpXor: opcode = is64Bit ? kX86Xor64RM : kX86Xor32RM; break;
382b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kOp2Byte: opcode = kX86Movsx8RM; break;
383b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kOp2Short: opcode = kX86Movsx16RM; break;
384b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kOp2Char: opcode = kX86Movzx16RM; break;
385b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kOpMul:
386b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    default:
38752a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee      LOG(FATAL) << "Bad case in OpRegMem " << op;
388b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      break;
389b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  }
3902700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  LIR *l = NewLIR3(opcode, r_dest.GetReg(), r_base.GetReg(), offset);
3918dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko  if (mem_ref_type_ == ResourceMask::kDalvikReg) {
392b28c1c06236751aa5c9e64dcb68b3c940341e496Ian Rogers    DCHECK_EQ(r_base, cu_->target64 ? rs_rX86_SP_64 : rs_rX86_SP_32);
393feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    AnnotateDalvikRegAccess(l, offset >> 2, true /* is_load */, false /* is_64bit */);
394feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  }
395feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  return l;
396feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell}
397feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell
398feb2b4e2d1c6538777bb80b60f3a247537b6221dMark MendellLIR* X86Mir2Lir::OpMemReg(OpKind op, RegLocation rl_dest, int r_value) {
399feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  DCHECK_NE(rl_dest.location, kLocPhysReg);
400feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  int displacement = SRegOffset(rl_dest.s_reg_low);
401e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu  bool is64Bit = rl_dest.wide != 0;
402feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  X86OpCode opcode = kX86Nop;
403feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  switch (op) {
404e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    case kOpSub: opcode = is64Bit ? kX86Sub64MR : kX86Sub32MR; break;
405e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    case kOpMov: opcode = is64Bit ? kX86Mov64MR : kX86Mov32MR; break;
406e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    case kOpCmp: opcode = is64Bit ? kX86Cmp64MR : kX86Cmp32MR; break;
407e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    case kOpAdd: opcode = is64Bit ? kX86Add64MR : kX86Add32MR; break;
408e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    case kOpAnd: opcode = is64Bit ? kX86And64MR : kX86And32MR; break;
409e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    case kOpOr:  opcode = is64Bit ? kX86Or64MR : kX86Or32MR; break;
410e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    case kOpXor: opcode = is64Bit ? kX86Xor64MR : kX86Xor32MR; break;
411e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    case kOpLsl: opcode = is64Bit ? kX86Sal64MC : kX86Sal32MC; break;
412e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    case kOpLsr: opcode = is64Bit ? kX86Shr64MC : kX86Shr32MC; break;
413e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    case kOpAsr: opcode = is64Bit ? kX86Sar64MC : kX86Sar32MC; break;
414feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    default:
415feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell      LOG(FATAL) << "Bad case in OpMemReg " << op;
416feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell      break;
417feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  }
418b28c1c06236751aa5c9e64dcb68b3c940341e496Ian Rogers  LIR *l = NewLIR3(opcode, rs_rX86_SP_32.GetReg(), displacement, r_value);
4198dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko  if (mem_ref_type_ == ResourceMask::kDalvikReg) {
4208dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko    AnnotateDalvikRegAccess(l, displacement >> 2, true /* is_load */, is64Bit /* is_64bit */);
4218dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko    AnnotateDalvikRegAccess(l, displacement >> 2, false /* is_load */, is64Bit /* is_64bit */);
4228dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko  }
423feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  return l;
424feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell}
425feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell
4262700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpRegMem(OpKind op, RegStorage r_dest, RegLocation rl_value) {
427feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  DCHECK_NE(rl_value.location, kLocPhysReg);
428e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu  bool is64Bit = r_dest.Is64Bit();
429feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  int displacement = SRegOffset(rl_value.s_reg_low);
430feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  X86OpCode opcode = kX86Nop;
431feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  switch (op) {
432e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    case kOpSub: opcode = is64Bit ? kX86Sub64RM : kX86Sub32RM; break;
433e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    case kOpMov: opcode = is64Bit ? kX86Mov64RM : kX86Mov32RM; break;
434e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    case kOpCmp: opcode = is64Bit ? kX86Cmp64RM : kX86Cmp32RM; break;
435e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    case kOpAdd: opcode = is64Bit ? kX86Add64RM : kX86Add32RM; break;
436e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    case kOpAnd: opcode = is64Bit ? kX86And64RM : kX86And32RM; break;
437e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    case kOpOr:  opcode = is64Bit ? kX86Or64RM : kX86Or32RM; break;
438e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    case kOpXor: opcode = is64Bit ? kX86Xor64RM : kX86Xor32RM; break;
439e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu    case kOpMul: opcode = is64Bit ? kX86Bkpt : kX86Imul32RM; break;
440feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    default:
441feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell      LOG(FATAL) << "Bad case in OpRegMem " << op;
442feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell      break;
443feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  }
444b28c1c06236751aa5c9e64dcb68b3c940341e496Ian Rogers  LIR *l = NewLIR3(opcode, r_dest.GetReg(), rs_rX86_SP_32.GetReg(), displacement);
4458dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko  if (mem_ref_type_ == ResourceMask::kDalvikReg) {
4468dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko    AnnotateDalvikRegAccess(l, displacement >> 2, true /* is_load */, is64Bit /* is_64bit */);
4478dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko  }
448feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  return l;
449b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers}
450e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
4512700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpRegRegReg(OpKind op, RegStorage r_dest, RegStorage r_src1,
4522700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee                             RegStorage r_src2) {
453e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu  bool is64Bit = r_dest.Is64Bit();
454fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (r_dest != r_src1 && r_dest != r_src2) {
4557934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom    if (op == kOpAdd) {  // lea special case, except can't encode rbp as base
456fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      if (r_src1 == r_src2) {
4571fd3346740dfb7f47be9922312b68a4227fada96buzbee        OpRegCopy(r_dest, r_src1);
4581fd3346740dfb7f47be9922312b68a4227fada96buzbee        return OpRegImm(kOpLsl, r_dest, 1);
4592700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      } else if (r_src1 != rs_rBP) {
460e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu        return NewLIR5(is64Bit ? kX86Lea64RA : kX86Lea32RA, r_dest.GetReg(),
461e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu                       r_src1.GetReg() /* base */, r_src2.GetReg() /* index */,
462e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu                       0 /* scale */, 0 /* disp */);
463b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      } else {
464e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu        return NewLIR5(is64Bit ? kX86Lea64RA : kX86Lea32RA, r_dest.GetReg(),
465e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu                       r_src2.GetReg() /* base */, r_src1.GetReg() /* index */,
466e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu                       0 /* scale */, 0 /* disp */);
467b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      }
468b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    } else {
4691fd3346740dfb7f47be9922312b68a4227fada96buzbee      OpRegCopy(r_dest, r_src1);
4701fd3346740dfb7f47be9922312b68a4227fada96buzbee      return OpRegReg(op, r_dest, r_src2);
471e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee    }
472fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  } else if (r_dest == r_src1) {
4731fd3346740dfb7f47be9922312b68a4227fada96buzbee    return OpRegReg(op, r_dest, r_src2);
474fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  } else {  // r_dest == r_src2
475b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    switch (op) {
476b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      case kOpSub:  // non-commutative
4771fd3346740dfb7f47be9922312b68a4227fada96buzbee        OpReg(kOpNeg, r_dest);
478b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers        op = kOpAdd;
479b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers        break;
480b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      case kOpSbc:
481b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      case kOpLsl: case kOpLsr: case kOpAsr: case kOpRor: {
4822700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee        RegStorage t_reg = AllocTemp();
4831fd3346740dfb7f47be9922312b68a4227fada96buzbee        OpRegCopy(t_reg, r_src1);
4841fd3346740dfb7f47be9922312b68a4227fada96buzbee        OpRegReg(op, t_reg, r_src2);
4857a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee        LIR* res = OpRegCopyNoInsert(r_dest, t_reg);
4867a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee        AppendLIR(res);
4871fd3346740dfb7f47be9922312b68a4227fada96buzbee        FreeTemp(t_reg);
488b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers        return res;
489b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      }
490b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      case kOpAdd:  // commutative
491b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      case kOpOr:
492b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      case kOpAdc:
493b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      case kOpAnd:
494b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      case kOpXor:
4954ee71b2df9eb74531d44528d028378bf0e90ecd7Pavel Vyssotski      case kOpMul:
496b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers        break;
497b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      default:
49852a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee        LOG(FATAL) << "Bad case in OpRegRegReg " << op;
499e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee    }
5001fd3346740dfb7f47be9922312b68a4227fada96buzbee    return OpRegReg(op, r_dest, r_src1);
501b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  }
502e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee}
503e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
5042700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpRegRegImm(OpKind op, RegStorage r_dest, RegStorage r_src, int value) {
505dd64450b37776f68b9bfc47f8d9a88bc72c95727Elena Sayapina  if (op == kOpMul && !cu_->target64) {
506b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    X86OpCode opcode = IS_SIMM8(value) ? kX86Imul32RRI8 : kX86Imul32RRI;
5072700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    return NewLIR3(opcode, r_dest.GetReg(), r_src.GetReg(), value);
508dd64450b37776f68b9bfc47f8d9a88bc72c95727Elena Sayapina  } else if (op == kOpAnd && !cu_->target64) {
509091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee    if (value == 0xFF && r_src.Low4()) {
5102700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      return NewLIR2(kX86Movzx8RR, r_dest.GetReg(), r_src.GetReg());
511b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers    } else if (value == 0xFFFF) {
5122700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      return NewLIR2(kX86Movzx16RR, r_dest.GetReg(), r_src.GetReg());
513b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers    }
514b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  }
515fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (r_dest != r_src) {
5160b9203e7996ee1856f620f95d95d8a273c43a3dfAndreas Gampe    if ((false) && op == kOpLsl && value >= 0 && value <= 3) {  // lea shift special case
5177caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers      // TODO: fix bug in LEA encoding when disp == 0
5182700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      return NewLIR5(kX86Lea32RA, r_dest.GetReg(),  r5sib_no_base /* base */,
5192700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee                     r_src.GetReg() /* index */, value /* scale */, 0 /* disp */);
5207934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom    } else if (op == kOpAdd) {  // lea add special case
5217e399fd3a99ba9c9dbfafdf14f75dd318fa7d454Chao-ying Fu      return NewLIR5(r_dest.Is64Bit() ? kX86Lea64RA : kX86Lea32RA, r_dest.GetReg(),
522b28c1c06236751aa5c9e64dcb68b3c940341e496Ian Rogers                     r_src.GetReg() /* base */, rs_rX86_SP_32.GetReg()/*r4sib_no_index*/ /* index */,
523e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu                     0 /* scale */, value /* disp */);
524e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee    }
5251fd3346740dfb7f47be9922312b68a4227fada96buzbee    OpRegCopy(r_dest, r_src);
526b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  }
5271fd3346740dfb7f47be9922312b68a4227fada96buzbee  return OpRegImm(op, r_dest, value);
528e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee}
529e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
530dd7624d2b9e599d57762d12031b10b89defc9807Ian RogersLIR* X86Mir2Lir::OpThreadMem(OpKind op, ThreadOffset<4> thread_offset) {
5312f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe  DCHECK_EQ(kX86, cu_->instruction_set);
5322f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe  X86OpCode opcode = kX86Bkpt;
5332f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe  switch (op) {
5342f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe    case kOpBlx: opcode = kX86CallT;  break;
5352f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe    case kOpBx: opcode = kX86JmpT;  break;
5362f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe    default:
5372f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe      LOG(FATAL) << "Bad opcode: " << op;
5382f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe      break;
5392f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe  }
5402f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe  return NewLIR1(opcode, thread_offset.Int32Value());
5412f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe}
5422f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe
5432f244e9faccfcca68af3c5484c397a01a1c3a342Andreas GampeLIR* X86Mir2Lir::OpThreadMem(OpKind op, ThreadOffset<8> thread_offset) {
5442f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe  DCHECK_EQ(kX86_64, cu_->instruction_set);
5456cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers  X86OpCode opcode = kX86Bkpt;
5466cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers  switch (op) {
5476cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers    case kOpBlx: opcode = kX86CallT;  break;
54860d7a65f7fb60f502160a2e479e86014c7787553Brian Carlstrom    case kOpBx: opcode = kX86JmpT;  break;
5496cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers    default:
5506cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers      LOG(FATAL) << "Bad opcode: " << op;
5516cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers      break;
5526cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers  }
553468532ea115657709bc32ee498e701a4c71762d4Ian Rogers  return NewLIR1(opcode, thread_offset.Int32Value());
5546cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers}
5556cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers
5562700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpMem(OpKind op, RegStorage r_base, int disp) {
5576cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers  X86OpCode opcode = kX86Bkpt;
5586cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers  switch (op) {
5596cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers    case kOpBlx: opcode = kX86CallM;  break;
5606cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers    default:
5616cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers      LOG(FATAL) << "Bad opcode: " << op;
5626cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers      break;
5636cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers  }
5642700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  return NewLIR2(opcode, r_base.GetReg(), disp);
5656cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers}
5666cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers
5672700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::LoadConstantWide(RegStorage r_dest, int64_t value) {
5684ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee    int32_t val_lo = Low32Bits(value);
5694ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee    int32_t val_hi = High32Bits(value);
5702700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    int32_t low_reg_val = r_dest.IsPair() ? r_dest.GetLowReg() : r_dest.GetReg();
571e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee    LIR *res;
572e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell    bool is_fp = r_dest.IsFloat();
5732700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    // TODO: clean this up once we fully recognize 64-bit storage containers.
5742700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    if (is_fp) {
5750e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov      DCHECK(r_dest.IsDouble());
5764ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      if (value == 0) {
57727dee8bcd7b4a53840b60818da8d2c819ef199bdMark Mendell        return NewLIR2(kX86XorpdRR, low_reg_val, low_reg_val);
5781961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko      } else if (pc_rel_base_reg_.Valid() || cu_->target64) {
57967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell        // We will load the value from the literal area.
58067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell        LIR* data_target = ScanLiteralPoolWide(literal_list_, val_lo, val_hi);
5812cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier        if (data_target == nullptr) {
58267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell          data_target = AddWideData(&literal_list_, val_lo, val_hi);
58367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell        }
58467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell
58567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell        // Load the proper value from the literal area.
58627dee8bcd7b4a53840b60818da8d2c819ef199bdMark Mendell        // We don't know the proper offset for the value, so pick one that
58727dee8bcd7b4a53840b60818da8d2c819ef199bdMark Mendell        // will force 4 byte offset.  We will fix this up in the assembler
58827dee8bcd7b4a53840b60818da8d2c819ef199bdMark Mendell        // later to have the right value.
5898dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko        ScopedMemRefType mem_ref_type(this, ResourceMask::kLiteral);
59027dee8bcd7b4a53840b60818da8d2c819ef199bdMark Mendell        if (cu_->target64) {
59127dee8bcd7b4a53840b60818da8d2c819ef199bdMark Mendell          res = NewLIR3(kX86MovsdRM, low_reg_val, kRIPReg, 256 /* bogus */);
59227dee8bcd7b4a53840b60818da8d2c819ef199bdMark Mendell        } else {
5931961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko          // Get the PC to a register and get the anchor.
5941961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko          LIR* anchor;
5951961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko          RegStorage r_pc = GetPcAndAnchor(&anchor);
59627dee8bcd7b4a53840b60818da8d2c819ef199bdMark Mendell
5971961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko          res = LoadBaseDisp(r_pc, kDummy32BitOffset, RegStorage::FloatSolo64(low_reg_val),
59827dee8bcd7b4a53840b60818da8d2c819ef199bdMark Mendell                             kDouble, kNotVolatile);
5991961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko          res->operands[4] = WrapPointer(anchor);
6001961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko          if (IsTemp(r_pc)) {
6011961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko            FreeTemp(r_pc);
6021961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko          }
60327dee8bcd7b4a53840b60818da8d2c819ef199bdMark Mendell        }
60467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell        res->target = data_target;
60567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell        res->flags.fixup = kFixupLoad;
606b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers      } else {
6070e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov        if (r_dest.IsPair()) {
6080e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov          if (val_lo == 0) {
6090e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov            res = NewLIR2(kX86XorpsRR, low_reg_val, low_reg_val);
6100e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov          } else {
6110e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov            res = LoadConstantNoClobber(RegStorage::FloatSolo32(low_reg_val), val_lo);
6120e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov          }
6130e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov          if (val_hi != 0) {
6140e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov            RegStorage r_dest_hi = AllocTempDouble();
6150e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov            LoadConstantNoClobber(r_dest_hi, val_hi);
6160e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov            NewLIR2(kX86PunpckldqRR, low_reg_val, r_dest_hi.GetReg());
6170e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov            FreeTemp(r_dest_hi);
6180e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov          }
619b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers        } else {
6200e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov          RegStorage r_temp = AllocTypedTempWide(false, kCoreReg);
6210e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov          res = LoadConstantWide(r_temp, value);
6220e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov          OpRegCopyWide(r_dest, r_temp);
6230e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov          FreeTemp(r_temp);
624b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers        }
625b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers      }
626b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers    } else {
627e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      if (r_dest.IsPair()) {
628e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu        res = LoadConstantNoClobber(r_dest.GetLow(), val_lo);
629e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu        LoadConstantNoClobber(r_dest.GetHigh(), val_hi);
630e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      } else {
6315192cbb12856b12620dc346758605baaa1469cedYixin Shou        if (value == 0) {
6321c55703526827b5fc63f5d4b8477f36574649342Serguei Katkov          res = NewLIR2(kX86Xor64RR, r_dest.GetReg(), r_dest.GetReg());
6335192cbb12856b12620dc346758605baaa1469cedYixin Shou        } else if (value >= INT_MIN && value <= INT_MAX) {
6345192cbb12856b12620dc346758605baaa1469cedYixin Shou          res = NewLIR2(kX86Mov64RI32, r_dest.GetReg(), val_lo);
6355192cbb12856b12620dc346758605baaa1469cedYixin Shou        } else {
6365192cbb12856b12620dc346758605baaa1469cedYixin Shou          res = NewLIR3(kX86Mov64RI64, r_dest.GetReg(), val_hi, val_lo);
637e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu        }
638e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      }
639b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers    }
640e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee    return res;
641e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee}
642e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
6432700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::LoadBaseIndexedDisp(RegStorage r_base, RegStorage r_index, int scale,
6443bf7c60a86d49bf8c05c5d2ac5ca8e9f80bd9824Vladimir Marko                                     int displacement, RegStorage r_dest, OpSize size) {
6452cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  LIR *load = nullptr;
6462cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  LIR *load2 = nullptr;
6472700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  bool is_array = r_index.Valid();
648091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  bool pair = r_dest.IsPair();
649091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  bool is64bit = ((size == k64) || (size == kDouble));
650b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  X86OpCode opcode = kX86Nop;
651b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  switch (size) {
652695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee    case k64:
653b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kDouble:
654091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      if (r_dest.IsFloat()) {
655fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee        opcode = is_array ? kX86MovsdRA : kX86MovsdRM;
656e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      } else if (!pair) {
657e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu        opcode = is_array ? kX86Mov64RA  : kX86Mov64RM;
658b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      } else {
659fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee        opcode = is_array ? kX86Mov32RA  : kX86Mov32RM;
660b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      }
661b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      // TODO: double store is to unaligned address
662b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      DCHECK_EQ((displacement & 0x3), 0);
663b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      break;
6649ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko    case kWord:
665dd64450b37776f68b9bfc47f8d9a88bc72c95727Elena Sayapina      if (cu_->target64) {
6669ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko        opcode = is_array ? kX86Mov64RA  : kX86Mov64RM;
6679ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko        CHECK_EQ(is_array, false);
6689ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko        CHECK_EQ(r_dest.IsFloat(), false);
6699ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko        break;
670fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers      }
671fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers      FALLTHROUGH_INTENDED;  // else fall-through to k32 case
672695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee    case k32:
673b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kSingle:
674695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee    case kReference:  // TODO: update for reference decompression on 64-bit targets.
675fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      opcode = is_array ? kX86Mov32RA : kX86Mov32RM;
676091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      if (r_dest.IsFloat()) {
677fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee        opcode = is_array ? kX86MovssRA : kX86MovssRM;
678091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee        DCHECK(r_dest.IsFloat());
679b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      }
680b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      DCHECK_EQ((displacement & 0x3), 0);
681b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      break;
682b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kUnsignedHalf:
683fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      opcode = is_array ? kX86Movzx16RA : kX86Movzx16RM;
684b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      DCHECK_EQ((displacement & 0x1), 0);
685b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      break;
686b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kSignedHalf:
687fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      opcode = is_array ? kX86Movsx16RA : kX86Movsx16RM;
688b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      DCHECK_EQ((displacement & 0x1), 0);
689b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      break;
690b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kUnsignedByte:
691fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      opcode = is_array ? kX86Movzx8RA : kX86Movzx8RM;
692b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      break;
693b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kSignedByte:
694fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      opcode = is_array ? kX86Movsx8RA : kX86Movsx8RM;
695b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      break;
696b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    default:
69752a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee      LOG(FATAL) << "Bad case in LoadBaseIndexedDispBody";
698b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  }
699b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers
700fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (!is_array) {
701b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    if (!pair) {
7022700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      load = NewLIR3(opcode, r_dest.GetReg(), r_base.GetReg(), displacement + LOWORD_OFFSET);
703e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee    } else {
704091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      DCHECK(!r_dest.IsFloat());  // Make sure we're not still using a pair here.
705091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      if (r_base == r_dest.GetLow()) {
70669dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison        load = NewLIR3(opcode, r_dest.GetHighReg(), r_base.GetReg(),
707fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao                        displacement + HIWORD_OFFSET);
70869dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison        load2 = NewLIR3(opcode, r_dest.GetLowReg(), r_base.GetReg(), displacement + LOWORD_OFFSET);
709fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao      } else {
710091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee        load = NewLIR3(opcode, r_dest.GetLowReg(), r_base.GetReg(), displacement + LOWORD_OFFSET);
711091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee        load2 = NewLIR3(opcode, r_dest.GetHighReg(), r_base.GetReg(),
712fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao                        displacement + HIWORD_OFFSET);
713fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao      }
714e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee    }
7158dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko    if (mem_ref_type_ == ResourceMask::kDalvikReg) {
716b28c1c06236751aa5c9e64dcb68b3c940341e496Ian Rogers      DCHECK_EQ(r_base, cu_->target64 ? rs_rX86_SP_64 : rs_rX86_SP_32);
7171fd3346740dfb7f47be9922312b68a4227fada96buzbee      AnnotateDalvikRegAccess(load, (displacement + (pair ? LOWORD_OFFSET : 0)) >> 2,
71802031b185b4653e6c72e21f7a51238b903f6d638buzbee                              true /* is_load */, is64bit);
719f7d9ad39541dd09030e26d54d3b73a076f90cc74Ian Rogers      if (pair) {
7201fd3346740dfb7f47be9922312b68a4227fada96buzbee        AnnotateDalvikRegAccess(load2, (displacement + HIWORD_OFFSET) >> 2,
721fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                                true /* is_load */, is64bit);
722b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      }
723e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee    }
724b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  } else {
725b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    if (!pair) {
7262700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      load = NewLIR5(opcode, r_dest.GetReg(), r_base.GetReg(), r_index.GetReg(), scale,
727a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                     displacement + LOWORD_OFFSET);
728b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    } else {
729091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      DCHECK(!r_dest.IsFloat());  // Make sure we're not still using a pair here.
730091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      if (r_base == r_dest.GetLow()) {
731091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee        if (r_dest.GetHigh() == r_index) {
732ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell          // We can't use either register for the first load.
7332700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee          RegStorage temp = AllocTemp();
73469dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison          load = NewLIR5(opcode, temp.GetReg(), r_base.GetReg(), r_index.GetReg(), scale,
735ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell                          displacement + HIWORD_OFFSET);
73669dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison          load2 = NewLIR5(opcode, r_dest.GetLowReg(), r_base.GetReg(), r_index.GetReg(), scale,
737ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell                         displacement + LOWORD_OFFSET);
738091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee          OpRegCopy(r_dest.GetHigh(), temp);
739ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell          FreeTemp(temp);
740ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell        } else {
74169dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison          load = NewLIR5(opcode, r_dest.GetHighReg(), r_base.GetReg(), r_index.GetReg(), scale,
742ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell                          displacement + HIWORD_OFFSET);
74369dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison          load2 = NewLIR5(opcode, r_dest.GetLowReg(), r_base.GetReg(), r_index.GetReg(), scale,
744ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell                         displacement + LOWORD_OFFSET);
745ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell        }
746fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao      } else {
747091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee        if (r_dest.GetLow() == r_index) {
748ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell          // We can't use either register for the first load.
7492700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee          RegStorage temp = AllocTemp();
7502700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee          load = NewLIR5(opcode, temp.GetReg(), r_base.GetReg(), r_index.GetReg(), scale,
751ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell                         displacement + LOWORD_OFFSET);
752091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee          load2 = NewLIR5(opcode, r_dest.GetHighReg(), r_base.GetReg(), r_index.GetReg(), scale,
753ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell                          displacement + HIWORD_OFFSET);
754091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee          OpRegCopy(r_dest.GetLow(), temp);
755ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell          FreeTemp(temp);
756ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell        } else {
757091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee          load = NewLIR5(opcode, r_dest.GetLowReg(), r_base.GetReg(), r_index.GetReg(), scale,
758ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell                         displacement + LOWORD_OFFSET);
759091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee          load2 = NewLIR5(opcode, r_dest.GetHighReg(), r_base.GetReg(), r_index.GetReg(), scale,
760ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell                          displacement + HIWORD_OFFSET);
761ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell        }
762fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao      }
763b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    }
764b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  }
765b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers
7662cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  // Always return first load generated as this might cause a fault if base is null.
767b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  return load;
768e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee}
769e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
7705772babbe824494ef9fe90a1b07a926d124bb7c7jeffhao/* Load value from base + scaled index. */
7712700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::LoadBaseIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_dest,
7722700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee                                 int scale, OpSize size) {
7733bf7c60a86d49bf8c05c5d2ac5ca8e9f80bd9824Vladimir Marko  return LoadBaseIndexedDisp(r_base, r_index, scale, 0, r_dest, size);
7745772babbe824494ef9fe90a1b07a926d124bb7c7jeffhao}
7755772babbe824494ef9fe90a1b07a926d124bb7c7jeffhao
7763c12c512faf6837844d5465b23b9410889e5eb11Andreas GampeLIR* X86Mir2Lir::LoadBaseDisp(RegStorage r_base, int displacement, RegStorage r_dest,
7773c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe                              OpSize size, VolatileKind is_volatile) {
778674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko  // LoadBaseDisp() will emit correct insn for atomic load on x86
779674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko  // assuming r_dest is correctly prepared using RegClassForFieldLoadStore().
780674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko
7813c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe  LIR* load = LoadBaseIndexedDisp(r_base, RegStorage::InvalidReg(), 0, displacement, r_dest,
7823c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe                                  size);
7833c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe
7843c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe  if (UNLIKELY(is_volatile == kVolatile)) {
78548f5c47907654350ce30a8dfdda0e977f5d3d39fHans Boehm    GenMemBarrier(kLoadAny);  // Only a scheduling barrier.
7863c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe  }
7873c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe
7883c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe  return load;
789e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee}
790e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
7912700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::StoreBaseIndexedDisp(RegStorage r_base, RegStorage r_index, int scale,
792b5bce7cc9f1130ab4932ba8e6917c362bf871f24Jean Christophe Beyler                                      int displacement, RegStorage r_src, OpSize size,
793b5bce7cc9f1130ab4932ba8e6917c362bf871f24Jean Christophe Beyler                                      int opt_flags) {
7942cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  LIR *store = nullptr;
7952cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  LIR *store2 = nullptr;
7962700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  bool is_array = r_index.Valid();
797091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  bool pair = r_src.IsPair();
798091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  bool is64bit = (size == k64) || (size == kDouble);
799b5bce7cc9f1130ab4932ba8e6917c362bf871f24Jean Christophe Beyler  bool consider_non_temporal = false;
800b5bce7cc9f1130ab4932ba8e6917c362bf871f24Jean Christophe Beyler
801b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers  X86OpCode opcode = kX86Nop;
802b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  switch (size) {
803695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee    case k64:
804b5bce7cc9f1130ab4932ba8e6917c362bf871f24Jean Christophe Beyler      consider_non_temporal = true;
805fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers      FALLTHROUGH_INTENDED;
806b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kDouble:
807091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      if (r_src.IsFloat()) {
808fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee        opcode = is_array ? kX86MovsdAR : kX86MovsdMR;
809e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu      } else if (!pair) {
810e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu        opcode = is_array ? kX86Mov64AR  : kX86Mov64MR;
811b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      } else {
812e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu        opcode = is_array ? kX86Mov32AR  : kX86Mov32MR;
813b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      }
814b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      // TODO: double store is to unaligned address
815b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      DCHECK_EQ((displacement & 0x3), 0);
816b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      break;
8179ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko    case kWord:
818dd64450b37776f68b9bfc47f8d9a88bc72c95727Elena Sayapina      if (cu_->target64) {
8199ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko        opcode = is_array ? kX86Mov64AR  : kX86Mov64MR;
8209ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko        CHECK_EQ(is_array, false);
8219ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko        CHECK_EQ(r_src.IsFloat(), false);
822b5bce7cc9f1130ab4932ba8e6917c362bf871f24Jean Christophe Beyler        consider_non_temporal = true;
8239ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko        break;
824fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers      }
825fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers      FALLTHROUGH_INTENDED;  // else fall-through to k32 case
826695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee    case k32:
827b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kSingle:
828695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee    case kReference:
829fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      opcode = is_array ? kX86Mov32AR : kX86Mov32MR;
830091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      if (r_src.IsFloat()) {
831fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee        opcode = is_array ? kX86MovssAR : kX86MovssMR;
832091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee        DCHECK(r_src.IsSingle());
833b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      }
834b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      DCHECK_EQ((displacement & 0x3), 0);
835b5bce7cc9f1130ab4932ba8e6917c362bf871f24Jean Christophe Beyler      consider_non_temporal = true;
836b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      break;
837b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kUnsignedHalf:
838b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kSignedHalf:
839fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      opcode = is_array ? kX86Mov16AR : kX86Mov16MR;
840b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      DCHECK_EQ((displacement & 0x1), 0);
841b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      break;
842b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kUnsignedByte:
843b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kSignedByte:
844fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      opcode = is_array ? kX86Mov8AR : kX86Mov8MR;
845b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      break;
846b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    default:
84700e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee      LOG(FATAL) << "Bad case in StoreBaseIndexedDispBody";
848b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  }
849b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers
850b5bce7cc9f1130ab4932ba8e6917c362bf871f24Jean Christophe Beyler  // Handle non temporal hint here.
851b5bce7cc9f1130ab4932ba8e6917c362bf871f24Jean Christophe Beyler  if (consider_non_temporal && ((opt_flags & MIR_STORE_NON_TEMPORAL) != 0)) {
852b5bce7cc9f1130ab4932ba8e6917c362bf871f24Jean Christophe Beyler    switch (opcode) {
853b5bce7cc9f1130ab4932ba8e6917c362bf871f24Jean Christophe Beyler      // We currently only handle 32/64 bit moves here.
854b5bce7cc9f1130ab4932ba8e6917c362bf871f24Jean Christophe Beyler      case kX86Mov64AR:
855b5bce7cc9f1130ab4932ba8e6917c362bf871f24Jean Christophe Beyler        opcode = kX86Movnti64AR;
856b5bce7cc9f1130ab4932ba8e6917c362bf871f24Jean Christophe Beyler        break;
857b5bce7cc9f1130ab4932ba8e6917c362bf871f24Jean Christophe Beyler      case kX86Mov64MR:
858b5bce7cc9f1130ab4932ba8e6917c362bf871f24Jean Christophe Beyler        opcode = kX86Movnti64MR;
859b5bce7cc9f1130ab4932ba8e6917c362bf871f24Jean Christophe Beyler        break;
860b5bce7cc9f1130ab4932ba8e6917c362bf871f24Jean Christophe Beyler      case kX86Mov32AR:
861b5bce7cc9f1130ab4932ba8e6917c362bf871f24Jean Christophe Beyler        opcode = kX86Movnti32AR;
862b5bce7cc9f1130ab4932ba8e6917c362bf871f24Jean Christophe Beyler        break;
863b5bce7cc9f1130ab4932ba8e6917c362bf871f24Jean Christophe Beyler      case kX86Mov32MR:
864b5bce7cc9f1130ab4932ba8e6917c362bf871f24Jean Christophe Beyler        opcode = kX86Movnti32MR;
865b5bce7cc9f1130ab4932ba8e6917c362bf871f24Jean Christophe Beyler        break;
866b5bce7cc9f1130ab4932ba8e6917c362bf871f24Jean Christophe Beyler      default:
867b5bce7cc9f1130ab4932ba8e6917c362bf871f24Jean Christophe Beyler        // Do nothing here.
868b5bce7cc9f1130ab4932ba8e6917c362bf871f24Jean Christophe Beyler        break;
869b5bce7cc9f1130ab4932ba8e6917c362bf871f24Jean Christophe Beyler    }
870b5bce7cc9f1130ab4932ba8e6917c362bf871f24Jean Christophe Beyler  }
871b5bce7cc9f1130ab4932ba8e6917c362bf871f24Jean Christophe Beyler
872fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (!is_array) {
873b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers    if (!pair) {
8742700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      store = NewLIR3(opcode, r_base.GetReg(), displacement + LOWORD_OFFSET, r_src.GetReg());
875b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers    } else {
876091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      DCHECK(!r_src.IsFloat());  // Make sure we're not still using a pair here.
877091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      store = NewLIR3(opcode, r_base.GetReg(), displacement + LOWORD_OFFSET, r_src.GetLowReg());
878091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      store2 = NewLIR3(opcode, r_base.GetReg(), displacement + HIWORD_OFFSET, r_src.GetHighReg());
879e296248a124ed8287b38a9225463696c18d84cd6jeffhao    }
8808dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko    if (mem_ref_type_ == ResourceMask::kDalvikReg) {
881b28c1c06236751aa5c9e64dcb68b3c940341e496Ian Rogers      DCHECK_EQ(r_base, cu_->target64 ? rs_rX86_SP_64 : rs_rX86_SP_32);
8821fd3346740dfb7f47be9922312b68a4227fada96buzbee      AnnotateDalvikRegAccess(store, (displacement + (pair ? LOWORD_OFFSET : 0)) >> 2,
88302031b185b4653e6c72e21f7a51238b903f6d638buzbee                              false /* is_load */, is64bit);
884e296248a124ed8287b38a9225463696c18d84cd6jeffhao      if (pair) {
8851fd3346740dfb7f47be9922312b68a4227fada96buzbee        AnnotateDalvikRegAccess(store2, (displacement + HIWORD_OFFSET) >> 2,
886fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                                false /* is_load */, is64bit);
887e296248a124ed8287b38a9225463696c18d84cd6jeffhao      }
888b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers    }
889b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  } else {
890b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers    if (!pair) {
8912700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      store = NewLIR5(opcode, r_base.GetReg(), r_index.GetReg(), scale,
8922700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee                      displacement + LOWORD_OFFSET, r_src.GetReg());
893b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers    } else {
894091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      DCHECK(!r_src.IsFloat());  // Make sure we're not still using a pair here.
8952700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      store = NewLIR5(opcode, r_base.GetReg(), r_index.GetReg(), scale,
896091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee                      displacement + LOWORD_OFFSET, r_src.GetLowReg());
8972700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      store2 = NewLIR5(opcode, r_base.GetReg(), r_index.GetReg(), scale,
898091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee                       displacement + HIWORD_OFFSET, r_src.GetHighReg());
899e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee    }
900b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  }
901b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers  return store;
902e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee}
903e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
904c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers/* store value base base + scaled index. */
9052700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::StoreBaseIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_src,
9063c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe                                  int scale, OpSize size) {
9073bf7c60a86d49bf8c05c5d2ac5ca8e9f80bd9824Vladimir Marko  return StoreBaseIndexedDisp(r_base, r_index, scale, 0, r_src, size);
908c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers}
909c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers
9103c12c512faf6837844d5465b23b9410889e5eb11Andreas GampeLIR* X86Mir2Lir::StoreBaseDisp(RegStorage r_base, int displacement, RegStorage r_src, OpSize size,
9113c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe                               VolatileKind is_volatile) {
9123c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe  if (UNLIKELY(is_volatile == kVolatile)) {
91348f5c47907654350ce30a8dfdda0e977f5d3d39fHans Boehm    GenMemBarrier(kAnyStore);  // Only a scheduling barrier.
9143c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe  }
9153c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe
916674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko  // StoreBaseDisp() will emit correct insn for atomic store on x86
917674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko  // assuming r_dest is correctly prepared using RegClassForFieldLoadStore().
91837f05ef45e0393de812d51261dc293240c17294dFred Shih  // x86 only allows registers EAX-EDX to be used as byte registers, if the input src is not
91937f05ef45e0393de812d51261dc293240c17294dFred Shih  // valid, allocate a temp.
92037f05ef45e0393de812d51261dc293240c17294dFred Shih  bool allocated_temp = false;
92137f05ef45e0393de812d51261dc293240c17294dFred Shih  if (size == kUnsignedByte || size == kSignedByte) {
92237f05ef45e0393de812d51261dc293240c17294dFred Shih    if (!cu_->target64 && !r_src.Low4()) {
92337f05ef45e0393de812d51261dc293240c17294dFred Shih      RegStorage r_input = r_src;
92437f05ef45e0393de812d51261dc293240c17294dFred Shih      r_src = AllocateByteRegister();
92537f05ef45e0393de812d51261dc293240c17294dFred Shih      OpRegCopy(r_src, r_input);
92637f05ef45e0393de812d51261dc293240c17294dFred Shih      allocated_temp = true;
92737f05ef45e0393de812d51261dc293240c17294dFred Shih    }
92837f05ef45e0393de812d51261dc293240c17294dFred Shih  }
929674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko
9303c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe  LIR* store = StoreBaseIndexedDisp(r_base, RegStorage::InvalidReg(), 0, displacement, r_src, size);
9313c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe
9323c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe  if (UNLIKELY(is_volatile == kVolatile)) {
93348f5c47907654350ce30a8dfdda0e977f5d3d39fHans Boehm    // A volatile load might follow the volatile store so insert a StoreLoad barrier.
93448f5c47907654350ce30a8dfdda0e977f5d3d39fHans Boehm    // This does require a fence, even on x86.
93548f5c47907654350ce30a8dfdda0e977f5d3d39fHans Boehm    GenMemBarrier(kAnyAny);
9363c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe  }
9373c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe
93837f05ef45e0393de812d51261dc293240c17294dFred Shih  if (allocated_temp) {
93937f05ef45e0393de812d51261dc293240c17294dFred Shih    FreeTemp(r_src);
94037f05ef45e0393de812d51261dc293240c17294dFred Shih  }
94137f05ef45e0393de812d51261dc293240c17294dFred Shih
9423c12c512faf6837844d5465b23b9410889e5eb11Andreas Gampe  return store;
943e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee}
944e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
9452700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpCmpMemImmBranch(ConditionCode cond, RegStorage temp_reg, RegStorage base_reg,
94669dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison                                   int offset, int check_value, LIR* target, LIR** compare) {
9476a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  UNUSED(temp_reg);  // Comparison performed directly with memory.
9486a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  LIR* inst = NewLIR3(IS_SIMM8(check_value) ? kX86Cmp32MI8 : kX86Cmp32MI, base_reg.GetReg(),
9496a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers      offset, check_value);
9506a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  if (compare != nullptr) {
9516a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers    *compare = inst;
9526a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  }
9536a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  LIR* branch = OpCondBranch(cond, target);
9546a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  return branch;
955766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell}
956766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell
9571961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Markovoid X86Mir2Lir::AnalyzeMIR(RefCounts* core_counts, MIR* mir, uint32_t weight) {
9581961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko  if (cu_->target64) {
9591961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko    Mir2Lir::AnalyzeMIR(core_counts, mir, weight);
96067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    return;
96167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  }
96267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell
9631961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko  int opcode = mir->dalvikInsn.opcode;
9641961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko  bool uses_pc_rel_load = false;
96567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  switch (opcode) {
96667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    // Instructions referencing doubles.
96767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    case Instruction::CMPL_DOUBLE:
96867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    case Instruction::CMPG_DOUBLE:
96967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    case Instruction::NEG_DOUBLE:
97067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    case Instruction::ADD_DOUBLE:
97167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    case Instruction::SUB_DOUBLE:
97267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    case Instruction::MUL_DOUBLE:
97367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    case Instruction::DIV_DOUBLE:
97467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    case Instruction::REM_DOUBLE:
97567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    case Instruction::ADD_DOUBLE_2ADDR:
97667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    case Instruction::SUB_DOUBLE_2ADDR:
97767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    case Instruction::MUL_DOUBLE_2ADDR:
97867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    case Instruction::DIV_DOUBLE_2ADDR:
97967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    case Instruction::REM_DOUBLE_2ADDR:
9801961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko    case kMirOpFusedCmplDouble:
9811961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko    case kMirOpFusedCmpgDouble:
9821961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko      uses_pc_rel_load = AnalyzeFPInstruction(opcode, mir);
98367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell      break;
98455d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell
9851961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko    // Packed switch needs the PC-relative pointer if it's large.
98667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    case Instruction::PACKED_SWITCH:
9871961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko      if (mir_graph_->GetTable(mir, mir->dalvikInsn.vB)[1] > kSmallSwitchThreshold) {
9881961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko        uses_pc_rel_load = true;
98927dee8bcd7b4a53840b60818da8d2c819ef199bdMark Mendell      }
99067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell      break;
9911961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko
9921961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko    case kMirOpConstVector:
9931961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko      uses_pc_rel_load = true;
9941961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko      break;
9951961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko    case kMirOpPackedMultiply:
9961961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko    case kMirOpPackedShiftLeft:
9971961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko    case kMirOpPackedSignedShiftRight:
9981961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko    case kMirOpPackedUnsignedShiftRight:
9991961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko      {
10001961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko        // Byte emulation requires constants from the literal pool.
10011961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko        OpSize opsize = static_cast<OpSize>(mir->dalvikInsn.vC >> 16);
10021961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko        if (opsize == kSignedByte || opsize == kUnsignedByte) {
10031961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko          uses_pc_rel_load = true;
10041961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko        }
10051961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko      }
10061961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko      break;
10071961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko
10087071c8d5885175a746723a3b38a347855965be08Yixin Shou    case Instruction::INVOKE_STATIC:
1009e5beb18ca08962ed271f4c1f703e0c52bc8805f3Razvan A Lupusoru    case Instruction::INVOKE_STATIC_RANGE:
10101961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko      if (mir_graph_->GetMethodLoweringInfo(mir).IsIntrinsic()) {
10111961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko        uses_pc_rel_load = AnalyzeInvokeStaticIntrinsic(mir);
10121961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko        break;
10131961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko      }
10141961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko      FALLTHROUGH_INTENDED;
101567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    default:
10161961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko      Mir2Lir::AnalyzeMIR(core_counts, mir, weight);
101767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell      break;
101867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  }
10191961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko
10201961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko  if (uses_pc_rel_load) {
10211961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko    DCHECK(pc_rel_temp_ != nullptr);
10221961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko    core_counts[SRegToPMap(pc_rel_temp_->s_reg_low)].count += weight;
10231961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko  }
102467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell}
102567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell
10261961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Markobool X86Mir2Lir::AnalyzeFPInstruction(int opcode, MIR* mir) {
10271961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko  DCHECK(!cu_->target64);
102867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  // Look at all the uses, and see if they are double constants.
1029cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyler  uint64_t attrs = MIRGraph::GetDataFlowAttributes(static_cast<Instruction::Code>(opcode));
103067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  int next_sreg = 0;
103167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  if (attrs & DF_UA) {
103267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    if (attrs & DF_A_WIDE) {
10331961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko      if (AnalyzeDoubleUse(mir_graph_->GetSrcWide(mir, next_sreg))) {
10341961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko        return true;
10351961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko      }
103667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell      next_sreg += 2;
103767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    } else {
103867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell      next_sreg++;
103967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    }
104067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  }
104167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  if (attrs & DF_UB) {
104267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    if (attrs & DF_B_WIDE) {
10431961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko      if (AnalyzeDoubleUse(mir_graph_->GetSrcWide(mir, next_sreg))) {
10441961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko        return true;
10451961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko      }
104667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell      next_sreg += 2;
104767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    } else {
104867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell      next_sreg++;
104967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    }
105067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  }
105167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  if (attrs & DF_UC) {
105267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    if (attrs & DF_C_WIDE) {
10531961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko      if (AnalyzeDoubleUse(mir_graph_->GetSrcWide(mir, next_sreg))) {
10541961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko        return true;
10551961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko      }
105667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    }
105767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  }
10581961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko  return false;
105967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell}
106067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell
10611961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Markoinline bool X86Mir2Lir::AnalyzeDoubleUse(RegLocation use) {
10620e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov  // If this is a double literal, we will want it in the literal pool on 32b platforms.
10631961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko  DCHECK(!cu_->target64);
10641961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko  return use.is_const;
10651961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko}
10661961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko
10671961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Markobool X86Mir2Lir::AnalyzeInvokeStaticIntrinsic(MIR* mir) {
10681961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko  // 64 bit RIP addressing doesn't need this analysis.
10691961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko  DCHECK(!cu_->target64);
10701961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko
10711961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko  // Retrieve the type of the intrinsic.
10721961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko  MethodReference method_ref = mir_graph_->GetMethodLoweringInfo(mir).GetTargetMethod();
10731961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko  DCHECK(cu_->compiler_driver->GetMethodInlinerMap() != nullptr);
10741961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko  DexFileMethodInliner* method_inliner =
10751961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko    cu_->compiler_driver->GetMethodInlinerMap()->GetMethodInliner(method_ref.dex_file);
10761961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko  InlineMethod method;
10771961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko  bool is_intrinsic = method_inliner->IsIntrinsic(method_ref.dex_method_index, &method);
10781961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko  DCHECK(is_intrinsic);
10791961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko
10801961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko  switch (method.opcode) {
10811961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko    case kIntrinsicAbsDouble:
10821961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko    case kIntrinsicMinMaxDouble:
10831961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko      return true;
10841961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko    default:
10851961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko      return false;
108667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  }
108767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell}
108867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell
10896a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan RogersRegLocation X86Mir2Lir::UpdateLocTyped(RegLocation loc) {
109030adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee  loc = UpdateLoc(loc);
109130adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee  if ((loc.location == kLocPhysReg) && (loc.fp != loc.reg.IsFloat())) {
109230adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee    if (GetRegInfo(loc.reg)->IsTemp()) {
109330adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee      Clobber(loc.reg);
109430adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee      FreeTemp(loc.reg);
109530adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee      loc.reg = RegStorage::InvalidReg();
109630adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee      loc.location = kLocDalvikFrame;
109730adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee    }
109830adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee  }
1099e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu  DCHECK(CheckCorePoolSanity());
110030adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee  return loc;
110130adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee}
110230adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee
11036a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan RogersRegLocation X86Mir2Lir::UpdateLocWideTyped(RegLocation loc) {
110430adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee  loc = UpdateLocWide(loc);
110530adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee  if ((loc.location == kLocPhysReg) && (loc.fp != loc.reg.IsFloat())) {
110630adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee    if (GetRegInfo(loc.reg)->IsTemp()) {
110730adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee      Clobber(loc.reg);
110830adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee      FreeTemp(loc.reg);
110930adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee      loc.reg = RegStorage::InvalidReg();
111030adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee      loc.location = kLocDalvikFrame;
111130adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee    }
111230adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee  }
1113e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu  DCHECK(CheckCorePoolSanity());
111430adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee  return loc;
111530adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee}
11167071c8d5885175a746723a3b38a347855965be08Yixin Shou
11171961b609bfefaedb71cee3651c4f931cc3e7393dVladimir MarkoLIR* X86Mir2Lir::InvokeTrampoline(OpKind op, RegStorage r_tgt, QuickEntrypointEnum trampoline) {
11181961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko  UNUSED(r_tgt);  // Call to absolute memory location doesn't need a temporary target register.
11190e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov  if (cu_->target64) {
11201961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko    return OpThreadMem(op, GetThreadOffset<8>(trampoline));
11211961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko  } else {
11221961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko    return OpThreadMem(op, GetThreadOffset<4>(trampoline));
11230e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov  }
11241961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko}
11250e63ce19bdb04d31180d7eb4a8bf6605333ade5aAlexei Zavjalov
11261961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Markovoid X86Mir2Lir::CountRefs(RefCounts* core_counts, RefCounts* fp_counts, size_t num_regs) {
11271961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko  // Start with the default counts.
11281961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko  Mir2Lir::CountRefs(core_counts, fp_counts, num_regs);
11291961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko
11301961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko  if (pc_rel_temp_ != nullptr) {
11311961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko    // Now, if the dex cache array base temp is used only once outside any loops (weight = 1),
11321961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko    // avoid the promotion, otherwise boost the weight by factor 2 because the full PC-relative
11331961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko    // load sequence is 3 instructions long and by promoting the PC base we save 2 instructions
11341961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko    // per use.
11351961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko    int p_map_idx = SRegToPMap(pc_rel_temp_->s_reg_low);
11361961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko    if (core_counts[p_map_idx].count == 1) {
11371961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko      core_counts[p_map_idx].count = 0;
11381961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko    } else {
11391961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko      core_counts[p_map_idx].count *= 2;
11407071c8d5885175a746723a3b38a347855965be08Yixin Shou    }
11417071c8d5885175a746723a3b38a347855965be08Yixin Shou  }
11427071c8d5885175a746723a3b38a347855965be08Yixin Shou}
1143984305917bf57b3f8d92965e4715a0370cc5bcfbAndreas Gampe
11441961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Markovoid X86Mir2Lir::DoPromotion() {
11451961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko  if (!cu_->target64) {
11461961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko    pc_rel_temp_ = mir_graph_->GetNewCompilerTemp(kCompilerTempBackend, false);
11471961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko  }
11481961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko
11491961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko  Mir2Lir::DoPromotion();
11501961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko
11511961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko  if (pc_rel_temp_ != nullptr) {
11521961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko    // Now, if the dex cache array base temp is promoted, remember the register but
11531961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko    // always remove the temp's stack location to avoid unnecessarily bloating the stack.
11541961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko    pc_rel_base_reg_ = mir_graph_->reg_location_[pc_rel_temp_->s_reg_low].reg;
11551961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko    DCHECK(!pc_rel_base_reg_.Valid() || !pc_rel_base_reg_.IsFloat());
11561961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko    mir_graph_->RemoveLastCompilerTemp(kCompilerTempBackend, false, pc_rel_temp_);
11571961b609bfefaedb71cee3651c4f931cc3e7393dVladimir Marko    pc_rel_temp_ = nullptr;
1158984305917bf57b3f8d92965e4715a0370cc5bcfbAndreas Gampe  }
1159984305917bf57b3f8d92965e4715a0370cc5bcfbAndreas Gampe}
1160984305917bf57b3f8d92965e4715a0370cc5bcfbAndreas Gampe
1161e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee}  // namespace art
1162