utility_x86.cc revision 35ba7f3a78d38885ec54e61ed060d2771eeceea7
1e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee/*
2e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * Copyright (C) 2012 The Android Open Source Project
3e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee *
4e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * Licensed under the Apache License, Version 2.0 (the "License");
5e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * you may not use this file except in compliance with the License.
6e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * You may obtain a copy of the License at
7e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee *
8e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee *      http://www.apache.org/licenses/LICENSE-2.0
9e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee *
10e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * Unless required by applicable law or agreed to in writing, software
11e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * distributed under the License is distributed on an "AS IS" BASIS,
12e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * See the License for the specific language governing permissions and
14e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * limitations under the License.
15e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee */
16e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
1702031b185b4653e6c72e21f7a51238b903f6d638buzbee#include "codegen_x86.h"
187940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "dex/quick/mir_to_lir-inl.h"
1967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell#include "dex/dataflow_iterator-inl.h"
20641ce0371c2f0dc95d26be02d8366124c8b66653Brian Carlstrom#include "x86_lir.h"
211bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee
22e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbeenamespace art {
23e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
24b046e16d8b8da318d6055f9308950131f1255e08buzbee/* This file contains codegen for the X86 ISA */
25e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
262700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpFpRegCopy(RegStorage r_dest, RegStorage r_src) {
27a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  int opcode;
28a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /* must be both DOUBLE or both not DOUBLE */
29091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  DCHECK(r_dest.IsFloat() || r_src.IsFloat());
30091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  DCHECK_EQ(r_dest.IsDouble(), r_src.IsDouble());
31091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  if (r_dest.IsDouble()) {
32a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    opcode = kX86MovsdRR;
33a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  } else {
34091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee    if (r_dest.IsSingle()) {
35091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      if (r_src.IsSingle()) {
36a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee        opcode = kX86MovssRR;
37a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      } else {  // Fpr <- Gpr
38a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee        opcode = kX86MovdxrRR;
39a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      }
40a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    } else {  // Gpr <- Fpr
41091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      DCHECK(r_src.IsSingle()) << "Raw: 0x" << std::hex << r_src.GetRawBits();
42a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      opcode = kX86MovdrxRR;
43e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee    }
44a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
45ec13743da80a80c1817cf6660c28917fc28846bcbuzbee  DCHECK_NE((EncodingMap[opcode].flags & IS_BINARY_OP), 0ULL);
462700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  LIR* res = RawLIR(current_dalvik_offset_, opcode, r_dest.GetReg(), r_src.GetReg());
47fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (r_dest == r_src) {
48fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee    res->flags.is_nop = true;
49a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
50a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  return res;
51e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee}
52e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
532ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool X86Mir2Lir::InexpensiveConstantInt(int32_t value) {
54e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee  return true;
55e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee}
56e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee
572ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool X86Mir2Lir::InexpensiveConstantFloat(int32_t value) {
584ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee  return false;
594ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee}
604ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee
612ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool X86Mir2Lir::InexpensiveConstantLong(int64_t value) {
624ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee  return true;
634ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee}
644ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee
652ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrombool X86Mir2Lir::InexpensiveConstantDouble(int64_t value) {
6667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  return value == 0;
674ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee}
684ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee
69e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee/*
70e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * Load a immediate using a shortcut if possible; otherwise
71e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * grab from the per-translation literal pool.  If target is
72e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * a high register, build constant into a low register and copy.
73e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee *
74e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * No additional register clobbering operation performed. Use this version when
75fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee * 1) r_dest is freshly returned from AllocTemp or
76e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * 2) The codegen is under fixed register usage
77e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee */
782700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::LoadConstantNoClobber(RegStorage r_dest, int value) {
792700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  RegStorage r_dest_save = r_dest;
80091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  if (r_dest.IsFloat()) {
81b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers    if (value == 0) {
822700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      return NewLIR2(kX86XorpsRR, r_dest.GetReg(), r_dest.GetReg());
83b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers    }
841fd3346740dfb7f47be9922312b68a4227fada96buzbee    r_dest = AllocTemp();
856cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers  }
86e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
87b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers  LIR *res;
886cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers  if (value == 0) {
892700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    res = NewLIR2(kX86Xor32RR, r_dest.GetReg(), r_dest.GetReg());
906cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers  } else {
912e9f7ed8d00271cb1cf082d68b4f4bc60702d6ecIan Rogers    // Note, there is no byte immediate form of a 32 bit immediate move.
9296992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko    if (r_dest.Is64Bit()) {
9396992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko      res = NewLIR2(kX86Mov64RI, r_dest.GetReg(), value);
9496992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko    } else {
9596992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko      res = NewLIR2(kX86Mov32RI, r_dest.GetReg(), value);
9696992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko    }
976cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers  }
98e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
99091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  if (r_dest_save.IsFloat()) {
1002700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    NewLIR2(kX86MovdxrRR, r_dest_save.GetReg(), r_dest.GetReg());
1011fd3346740dfb7f47be9922312b68a4227fada96buzbee    FreeTemp(r_dest);
1026cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers  }
103e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
1046cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers  return res;
105e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee}
106e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
1072ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* X86Mir2Lir::OpUnconditionalBranch(LIR* target) {
108df62950e7a32031b82360c407d46a37b94188fbbBrian Carlstrom  LIR* res = NewLIR1(kX86Jmp8, 0 /* offset to be patched during assembly*/);
10902031b185b4653e6c72e21f7a51238b903f6d638buzbee  res->target = target;
11002031b185b4653e6c72e21f7a51238b903f6d638buzbee  return res;
111e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee}
112e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
1132ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromLIR* X86Mir2Lir::OpCondBranch(ConditionCode cc, LIR* target) {
1141fd3346740dfb7f47be9922312b68a4227fada96buzbee  LIR* branch = NewLIR2(kX86Jcc8, 0 /* offset to be patched */,
11552a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee                        X86ConditionEncoding(cc));
116b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  branch->target = target;
117b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  return branch;
118a7678db092ac6bb79f7cad490099a1015fbbc714buzbee}
119a7678db092ac6bb79f7cad490099a1015fbbc714buzbee
1202700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpReg(OpKind op, RegStorage r_dest_src) {
121b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  X86OpCode opcode = kX86Bkpt;
122b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  switch (op) {
123b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kOpNeg: opcode = kX86Neg32R; break;
1241395b1e06c1d0ff5155b0c5d113ad3bd6f163c07jeffhao    case kOpNot: opcode = kX86Not32R; break;
125a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko    case kOpRev: opcode = kX86Bswap32R; break;
126b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kOpBlx: opcode = kX86CallR; break;
127b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    default:
12852a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee      LOG(FATAL) << "Bad case in OpReg " << op;
129b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  }
1302700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  return NewLIR1(opcode, r_dest_src.GetReg());
131e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee}
132e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
1332700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpRegImm(OpKind op, RegStorage r_dest_src1, int value) {
134b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  X86OpCode opcode = kX86Bkpt;
135fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  bool byte_imm = IS_SIMM8(value);
136091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  DCHECK(!r_dest_src1.IsFloat());
1379ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko  if (r_dest_src1.Is64Bit()) {
1389ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko    switch (op) {
1399ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      case kOpAdd: opcode = byte_imm ? kX86Add64RI8 : kX86Add64RI; break;
1409ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      case kOpSub: opcode = byte_imm ? kX86Sub64RI8 : kX86Sub64RI; break;
1419ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      default:
1429ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko        LOG(FATAL) << "Bad case in OpRegImm (64-bit) " << op;
1439ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko    }
1449ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko  } else {
1459ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko    switch (op) {
1469ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      case kOpLsl: opcode = kX86Sal32RI; break;
1479ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      case kOpLsr: opcode = kX86Shr32RI; break;
1489ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      case kOpAsr: opcode = kX86Sar32RI; break;
1499ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      case kOpAdd: opcode = byte_imm ? kX86Add32RI8 : kX86Add32RI; break;
1509ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      case kOpOr:  opcode = byte_imm ? kX86Or32RI8  : kX86Or32RI;  break;
1519ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      case kOpAdc: opcode = byte_imm ? kX86Adc32RI8 : kX86Adc32RI; break;
1529ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      // case kOpSbb: opcode = kX86Sbb32RI; break;
1539ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      case kOpAnd: opcode = byte_imm ? kX86And32RI8 : kX86And32RI; break;
1549ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      case kOpSub: opcode = byte_imm ? kX86Sub32RI8 : kX86Sub32RI; break;
1559ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      case kOpXor: opcode = byte_imm ? kX86Xor32RI8 : kX86Xor32RI; break;
1569ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      case kOpCmp: opcode = byte_imm ? kX86Cmp32RI8 : kX86Cmp32RI; break;
1579ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      case kOpMov:
1589ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko        /*
1599ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko         * Moving the constant zero into register can be specialized as an xor of the register.
1609ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko         * However, that sets eflags while the move does not. For that reason here, always do
1619ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko         * the move and if caller is flexible, they should be calling LoadConstantNoClobber instead.
1629ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko         */
1639ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko        opcode = kX86Mov32RI;
1649ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko        break;
1659ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      case kOpMul:
1669ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko        opcode = byte_imm ? kX86Imul32RRI8 : kX86Imul32RRI;
1679ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko        return NewLIR3(opcode, r_dest_src1.GetReg(), r_dest_src1.GetReg(), value);
168e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell      case kOp2Byte:
169e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell        opcode = kX86Mov32RI;
170e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell        value = static_cast<int8_t>(value);
171e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell        break;
172e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell      case kOp2Short:
173e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell        opcode = kX86Mov32RI;
174e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell        value = static_cast<int16_t>(value);
175e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell        break;
176e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell      case kOp2Char:
177e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell        opcode = kX86Mov32RI;
178e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell        value = static_cast<uint16_t>(value);
179e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell        break;
180e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell      case kOpNeg:
181e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell        opcode = kX86Mov32RI;
182e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell        value = -value;
183e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell        break;
1849ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      default:
1859ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko        LOG(FATAL) << "Bad case in OpRegImm " << op;
1869ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko    }
187b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  }
1882700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  return NewLIR2(opcode, r_dest_src1.GetReg(), value);
189e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee}
190e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
1912700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpRegReg(OpKind op, RegStorage r_dest_src1, RegStorage r_src2) {
192a7678db092ac6bb79f7cad490099a1015fbbc714buzbee    X86OpCode opcode = kX86Nop;
193d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers    bool src2_must_be_cx = false;
194e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee    switch (op) {
195b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers        // X86 unary opcodes
196b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      case kOpMvn:
1971fd3346740dfb7f47be9922312b68a4227fada96buzbee        OpRegCopy(r_dest_src1, r_src2);
1981fd3346740dfb7f47be9922312b68a4227fada96buzbee        return OpReg(kOpNot, r_dest_src1);
199b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      case kOpNeg:
2001fd3346740dfb7f47be9922312b68a4227fada96buzbee        OpRegCopy(r_dest_src1, r_src2);
2011fd3346740dfb7f47be9922312b68a4227fada96buzbee        return OpReg(kOpNeg, r_dest_src1);
202a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko      case kOpRev:
203a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko        OpRegCopy(r_dest_src1, r_src2);
204a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko        return OpReg(kOpRev, r_dest_src1);
205a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko      case kOpRevsh:
206a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko        OpRegCopy(r_dest_src1, r_src2);
207a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko        OpReg(kOpRev, r_dest_src1);
208a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko        return OpRegImm(kOpAsr, r_dest_src1, 16);
209b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers        // X86 binary opcodes
210b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      case kOpSub: opcode = kX86Sub32RR; break;
211b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      case kOpSbc: opcode = kX86Sbb32RR; break;
212d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers      case kOpLsl: opcode = kX86Sal32RC; src2_must_be_cx = true; break;
213d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers      case kOpLsr: opcode = kX86Shr32RC; src2_must_be_cx = true; break;
214d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers      case kOpAsr: opcode = kX86Sar32RC; src2_must_be_cx = true; break;
215b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      case kOpMov: opcode = kX86Mov32RR; break;
216b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      case kOpCmp: opcode = kX86Cmp32RR; break;
217b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      case kOpAdd: opcode = kX86Add32RR; break;
218b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      case kOpAdc: opcode = kX86Adc32RR; break;
219b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      case kOpAnd: opcode = kX86And32RR; break;
220b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      case kOpOr:  opcode = kX86Or32RR; break;
221b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      case kOpXor: opcode = kX86Xor32RR; break;
222703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao      case kOp2Byte:
223091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee        // TODO: there are several instances of this check.  A utility function perhaps?
224091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee        // TODO: Similar to Arm's reg < 8 check.  Perhaps add attribute checks to RegStorage?
225703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao        // Use shifts instead of a byte operand if the source can't be byte accessed.
226091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee        if (r_src2.GetRegNum() >= rs_rX86_SP.GetRegNum()) {
2272700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee          NewLIR2(kX86Mov32RR, r_dest_src1.GetReg(), r_src2.GetReg());
2282700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee          NewLIR2(kX86Sal32RI, r_dest_src1.GetReg(), 24);
2292700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee          return NewLIR2(kX86Sar32RI, r_dest_src1.GetReg(), 24);
230703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao        } else {
231703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao          opcode = kX86Movsx8RR;
232703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao        }
233703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao        break;
234b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      case kOp2Short: opcode = kX86Movsx16RR; break;
235b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      case kOp2Char: opcode = kX86Movzx16RR; break;
236b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      case kOpMul: opcode = kX86Imul32RR; break;
237b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      default:
23852a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee        LOG(FATAL) << "Bad case in OpRegReg " << op;
239b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers        break;
240e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee    }
241091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee    CHECK(!src2_must_be_cx || r_src2.GetReg() == rs_rCX.GetReg());
2422700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    return NewLIR2(opcode, r_dest_src1.GetReg(), r_src2.GetReg());
243e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee}
244e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
2452700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpMovRegMem(RegStorage r_dest, RegStorage r_base, int offset, MoveType move_type) {
246091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  DCHECK(!r_base.IsFloat());
2472c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru  X86OpCode opcode = kX86Nop;
2482700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  int dest = r_dest.IsPair() ? r_dest.GetLowReg() : r_dest.GetReg();
2492c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru  switch (move_type) {
2502c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMov8GP:
251091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(!r_dest.IsFloat());
2522c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86Mov8RM;
2532c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
2542c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMov16GP:
255091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(!r_dest.IsFloat());
2562c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86Mov16RM;
2572c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
2582c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMov32GP:
259091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(!r_dest.IsFloat());
2602c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86Mov32RM;
2612c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
2622c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMov32FP:
263091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(r_dest.IsFloat());
2642c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86MovssRM;
2652c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
2662c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMov64FP:
267091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(r_dest.IsFloat());
2682c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86MovsdRM;
2692c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
2702c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMovU128FP:
271091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(r_dest.IsFloat());
2722c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86MovupsRM;
2732c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
2742c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMovA128FP:
275091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(r_dest.IsFloat());
2762c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86MovapsRM;
2772c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
2782c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMovLo128FP:
279091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(r_dest.IsFloat());
2802c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86MovlpsRM;
2812c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
2822c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMovHi128FP:
283091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(r_dest.IsFloat());
2842c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86MovhpsRM;
2852c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
2862c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMov64GP:
2872c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMovLo64FP:
2882c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMovHi64FP:
2892c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    default:
2902c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      LOG(FATAL) << "Bad case in OpMovRegMem";
2912c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
2922c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru  }
2932c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru
2942700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  return NewLIR3(opcode, dest, r_base.GetReg(), offset);
2952c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru}
2962c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru
2972700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpMovMemReg(RegStorage r_base, int offset, RegStorage r_src, MoveType move_type) {
298091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  DCHECK(!r_base.IsFloat());
2992700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  int src = r_src.IsPair() ? r_src.GetLowReg() : r_src.GetReg();
3002c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru
3012c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru  X86OpCode opcode = kX86Nop;
3022c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru  switch (move_type) {
3032c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMov8GP:
304091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(!r_src.IsFloat());
3052c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86Mov8MR;
3062c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
3072c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMov16GP:
308091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(!r_src.IsFloat());
3092c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86Mov16MR;
3102c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
3112c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMov32GP:
312091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(!r_src.IsFloat());
3132c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86Mov32MR;
3142c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
3152c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMov32FP:
316091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(r_src.IsFloat());
3172c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86MovssMR;
3182c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
3192c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMov64FP:
320091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(r_src.IsFloat());
3212c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86MovsdMR;
3222c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
3232c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMovU128FP:
324091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(r_src.IsFloat());
3252c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86MovupsMR;
3262c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
3272c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMovA128FP:
328091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(r_src.IsFloat());
3292c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86MovapsMR;
3302c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
3312c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMovLo128FP:
332091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(r_src.IsFloat());
3332c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86MovlpsMR;
3342c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
3352c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMovHi128FP:
336091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      CHECK(r_src.IsFloat());
3372c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      opcode = kX86MovhpsMR;
3382c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
3392c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMov64GP:
3402c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMovLo64FP:
3412c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    case kMovHi64FP:
3422c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru    default:
3432c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      LOG(FATAL) << "Bad case in OpMovMemReg";
3442c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru      break;
3452c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru  }
3462c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru
3472700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  return NewLIR3(opcode, r_base.GetReg(), offset, src);
3482c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru}
3492c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru
3502700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpCondRegReg(OpKind op, ConditionCode cc, RegStorage r_dest, RegStorage r_src) {
351bd288c2c1206bc99fafebfb9120a83f13cf9723bRazvan A Lupusoru  // The only conditional reg to reg operation supported is Cmov
352bd288c2c1206bc99fafebfb9120a83f13cf9723bRazvan A Lupusoru  DCHECK_EQ(op, kOpCmov);
3532700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  return NewLIR3(kX86Cmov32RRC, r_dest.GetReg(), r_src.GetReg(), X86ConditionEncoding(cc));
354bd288c2c1206bc99fafebfb9120a83f13cf9723bRazvan A Lupusoru}
355bd288c2c1206bc99fafebfb9120a83f13cf9723bRazvan A Lupusoru
3562700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpRegMem(OpKind op, RegStorage r_dest, RegStorage r_base, int offset) {
357b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  X86OpCode opcode = kX86Nop;
358b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  switch (op) {
359b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      // X86 binary opcodes
360b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kOpSub: opcode = kX86Sub32RM; break;
361b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kOpMov: opcode = kX86Mov32RM; break;
362b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kOpCmp: opcode = kX86Cmp32RM; break;
363b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kOpAdd: opcode = kX86Add32RM; break;
364b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kOpAnd: opcode = kX86And32RM; break;
365b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kOpOr:  opcode = kX86Or32RM; break;
366b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kOpXor: opcode = kX86Xor32RM; break;
367b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kOp2Byte: opcode = kX86Movsx8RM; break;
368b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kOp2Short: opcode = kX86Movsx16RM; break;
369b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kOp2Char: opcode = kX86Movzx16RM; break;
370b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kOpMul:
371b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    default:
37252a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee      LOG(FATAL) << "Bad case in OpRegMem " << op;
373b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      break;
374b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  }
3752700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  LIR *l = NewLIR3(opcode, r_dest.GetReg(), r_base.GetReg(), offset);
3762700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  if (r_base == rs_rX86_SP) {
377feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    AnnotateDalvikRegAccess(l, offset >> 2, true /* is_load */, false /* is_64bit */);
378feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  }
379feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  return l;
380feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell}
381feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell
382feb2b4e2d1c6538777bb80b60f3a247537b6221dMark MendellLIR* X86Mir2Lir::OpMemReg(OpKind op, RegLocation rl_dest, int r_value) {
383feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  DCHECK_NE(rl_dest.location, kLocPhysReg);
384feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  int displacement = SRegOffset(rl_dest.s_reg_low);
385feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  X86OpCode opcode = kX86Nop;
386feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  switch (op) {
387feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    case kOpSub: opcode = kX86Sub32MR; break;
388feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    case kOpMov: opcode = kX86Mov32MR; break;
389feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    case kOpCmp: opcode = kX86Cmp32MR; break;
390feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    case kOpAdd: opcode = kX86Add32MR; break;
391feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    case kOpAnd: opcode = kX86And32MR; break;
392feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    case kOpOr:  opcode = kX86Or32MR; break;
393feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    case kOpXor: opcode = kX86Xor32MR; break;
394feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    case kOpLsl: opcode = kX86Sal32MC; break;
395feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    case kOpLsr: opcode = kX86Shr32MC; break;
396feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    case kOpAsr: opcode = kX86Sar32MC; break;
397feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    default:
398feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell      LOG(FATAL) << "Bad case in OpMemReg " << op;
399feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell      break;
400feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  }
401091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  LIR *l = NewLIR3(opcode, rs_rX86_SP.GetReg(), displacement, r_value);
402217fe73a6c2f3ec44dc52c85c8a101313d048f04Serguei Katkov  AnnotateDalvikRegAccess(l, displacement >> 2, true /* is_load */, false /* is_64bit */);
403feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  AnnotateDalvikRegAccess(l, displacement >> 2, false /* is_load */, false /* is_64bit */);
404feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  return l;
405feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell}
406feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell
4072700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpRegMem(OpKind op, RegStorage r_dest, RegLocation rl_value) {
408feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  DCHECK_NE(rl_value.location, kLocPhysReg);
409feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  int displacement = SRegOffset(rl_value.s_reg_low);
410feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  X86OpCode opcode = kX86Nop;
411feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  switch (op) {
412feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    case kOpSub: opcode = kX86Sub32RM; break;
413feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    case kOpMov: opcode = kX86Mov32RM; break;
414feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    case kOpCmp: opcode = kX86Cmp32RM; break;
415feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    case kOpAdd: opcode = kX86Add32RM; break;
416feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    case kOpAnd: opcode = kX86And32RM; break;
417feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    case kOpOr:  opcode = kX86Or32RM; break;
418feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    case kOpXor: opcode = kX86Xor32RM; break;
419feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    case kOpMul: opcode = kX86Imul32RM; break;
420feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell    default:
421feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell      LOG(FATAL) << "Bad case in OpRegMem " << op;
422feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell      break;
423feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  }
424091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  LIR *l = NewLIR3(opcode, r_dest.GetReg(), rs_rX86_SP.GetReg(), displacement);
425feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  AnnotateDalvikRegAccess(l, displacement >> 2, true /* is_load */, false /* is_64bit */);
426feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell  return l;
427b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers}
428e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
4292700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpRegRegReg(OpKind op, RegStorage r_dest, RegStorage r_src1,
4302700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee                             RegStorage r_src2) {
431fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (r_dest != r_src1 && r_dest != r_src2) {
4327934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom    if (op == kOpAdd) {  // lea special case, except can't encode rbp as base
433fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      if (r_src1 == r_src2) {
4341fd3346740dfb7f47be9922312b68a4227fada96buzbee        OpRegCopy(r_dest, r_src1);
4351fd3346740dfb7f47be9922312b68a4227fada96buzbee        return OpRegImm(kOpLsl, r_dest, 1);
4362700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      } else if (r_src1 != rs_rBP) {
4372700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee        return NewLIR5(kX86Lea32RA, r_dest.GetReg(), r_src1.GetReg() /* base */,
4382700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee                       r_src2.GetReg() /* index */, 0 /* scale */, 0 /* disp */);
439b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      } else {
4402700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee        return NewLIR5(kX86Lea32RA, r_dest.GetReg(), r_src2.GetReg() /* base */,
4412700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee                       r_src1.GetReg() /* index */, 0 /* scale */, 0 /* disp */);
442b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      }
443b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    } else {
4441fd3346740dfb7f47be9922312b68a4227fada96buzbee      OpRegCopy(r_dest, r_src1);
4451fd3346740dfb7f47be9922312b68a4227fada96buzbee      return OpRegReg(op, r_dest, r_src2);
446e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee    }
447fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  } else if (r_dest == r_src1) {
4481fd3346740dfb7f47be9922312b68a4227fada96buzbee    return OpRegReg(op, r_dest, r_src2);
449fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  } else {  // r_dest == r_src2
450b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    switch (op) {
451b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      case kOpSub:  // non-commutative
4521fd3346740dfb7f47be9922312b68a4227fada96buzbee        OpReg(kOpNeg, r_dest);
453b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers        op = kOpAdd;
454b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers        break;
455b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      case kOpSbc:
456b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      case kOpLsl: case kOpLsr: case kOpAsr: case kOpRor: {
4572700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee        RegStorage t_reg = AllocTemp();
4581fd3346740dfb7f47be9922312b68a4227fada96buzbee        OpRegCopy(t_reg, r_src1);
4591fd3346740dfb7f47be9922312b68a4227fada96buzbee        OpRegReg(op, t_reg, r_src2);
4607a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee        LIR* res = OpRegCopyNoInsert(r_dest, t_reg);
4617a11ab09f93f54b1c07c0bf38dd65ed322e86bc6buzbee        AppendLIR(res);
4621fd3346740dfb7f47be9922312b68a4227fada96buzbee        FreeTemp(t_reg);
463b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers        return res;
464b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      }
465b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      case kOpAdd:  // commutative
466b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      case kOpOr:
467b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      case kOpAdc:
468b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      case kOpAnd:
469b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      case kOpXor:
470b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers        break;
471b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      default:
47252a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee        LOG(FATAL) << "Bad case in OpRegRegReg " << op;
473e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee    }
4741fd3346740dfb7f47be9922312b68a4227fada96buzbee    return OpRegReg(op, r_dest, r_src1);
475b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  }
476e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee}
477e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
4782700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpRegRegImm(OpKind op, RegStorage r_dest, RegStorage r_src, int value) {
479b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  if (op == kOpMul) {
480b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    X86OpCode opcode = IS_SIMM8(value) ? kX86Imul32RRI8 : kX86Imul32RRI;
4812700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    return NewLIR3(opcode, r_dest.GetReg(), r_src.GetReg(), value);
482b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers  } else if (op == kOpAnd) {
483091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee    if (value == 0xFF && r_src.Low4()) {
4842700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      return NewLIR2(kX86Movzx8RR, r_dest.GetReg(), r_src.GetReg());
485b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers    } else if (value == 0xFFFF) {
4862700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      return NewLIR2(kX86Movzx16RR, r_dest.GetReg(), r_src.GetReg());
487b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers    }
488b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  }
489fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (r_dest != r_src) {
4907934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom    if (false && op == kOpLsl && value >= 0 && value <= 3) {  // lea shift special case
4917caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers      // TODO: fix bug in LEA encoding when disp == 0
4922700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      return NewLIR5(kX86Lea32RA, r_dest.GetReg(),  r5sib_no_base /* base */,
4932700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee                     r_src.GetReg() /* index */, value /* scale */, 0 /* disp */);
4947934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom    } else if (op == kOpAdd) {  // lea add special case
4952700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      return NewLIR5(kX86Lea32RA, r_dest.GetReg(), r_src.GetReg() /* base */,
4969ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko                     rs_rX86_SP.GetReg()/*r4sib_no_index*/ /* index */, 0 /* scale */, value /* disp */);
497e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee    }
4981fd3346740dfb7f47be9922312b68a4227fada96buzbee    OpRegCopy(r_dest, r_src);
499b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  }
5001fd3346740dfb7f47be9922312b68a4227fada96buzbee  return OpRegImm(op, r_dest, value);
501e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee}
502e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
503dd7624d2b9e599d57762d12031b10b89defc9807Ian RogersLIR* X86Mir2Lir::OpThreadMem(OpKind op, ThreadOffset<4> thread_offset) {
5042f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe  DCHECK_EQ(kX86, cu_->instruction_set);
5052f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe  X86OpCode opcode = kX86Bkpt;
5062f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe  switch (op) {
5072f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe    case kOpBlx: opcode = kX86CallT;  break;
5082f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe    case kOpBx: opcode = kX86JmpT;  break;
5092f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe    default:
5102f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe      LOG(FATAL) << "Bad opcode: " << op;
5112f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe      break;
5122f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe  }
5132f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe  return NewLIR1(opcode, thread_offset.Int32Value());
5142f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe}
5152f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe
5162f244e9faccfcca68af3c5484c397a01a1c3a342Andreas GampeLIR* X86Mir2Lir::OpThreadMem(OpKind op, ThreadOffset<8> thread_offset) {
5172f244e9faccfcca68af3c5484c397a01a1c3a342Andreas Gampe  DCHECK_EQ(kX86_64, cu_->instruction_set);
5186cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers  X86OpCode opcode = kX86Bkpt;
5196cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers  switch (op) {
5206cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers    case kOpBlx: opcode = kX86CallT;  break;
52160d7a65f7fb60f502160a2e479e86014c7787553Brian Carlstrom    case kOpBx: opcode = kX86JmpT;  break;
5226cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers    default:
5236cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers      LOG(FATAL) << "Bad opcode: " << op;
5246cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers      break;
5256cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers  }
526468532ea115657709bc32ee498e701a4c71762d4Ian Rogers  return NewLIR1(opcode, thread_offset.Int32Value());
5276cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers}
5286cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers
5292700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpMem(OpKind op, RegStorage r_base, int disp) {
5306cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers  X86OpCode opcode = kX86Bkpt;
5316cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers  switch (op) {
5326cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers    case kOpBlx: opcode = kX86CallM;  break;
5336cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers    default:
5346cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers      LOG(FATAL) << "Bad opcode: " << op;
5356cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers      break;
5366cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers  }
5372700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  return NewLIR2(opcode, r_base.GetReg(), disp);
5386cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers}
5396cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers
5402700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::LoadConstantWide(RegStorage r_dest, int64_t value) {
5414ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee    int32_t val_lo = Low32Bits(value);
5424ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee    int32_t val_hi = High32Bits(value);
5432700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    int32_t low_reg_val = r_dest.IsPair() ? r_dest.GetLowReg() : r_dest.GetReg();
544e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee    LIR *res;
545e87f9b5185379c8cf8392d65a63e7bf7e51b97e7Mark Mendell    bool is_fp = r_dest.IsFloat();
5462700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    // TODO: clean this up once we fully recognize 64-bit storage containers.
5472700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    if (is_fp) {
5484ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee      if (value == 0) {
5492700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee        return NewLIR2(kX86XorpsRR, low_reg_val, low_reg_val);
55067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell      } else if (base_of_code_ != nullptr) {
55167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell        // We will load the value from the literal area.
55267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell        LIR* data_target = ScanLiteralPoolWide(literal_list_, val_lo, val_hi);
55367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell        if (data_target == NULL) {
55467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell          data_target = AddWideData(&literal_list_, val_lo, val_hi);
55567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell        }
55667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell
55767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell        // Address the start of the method
55867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell        RegLocation rl_method = mir_graph_->GetRegLocation(base_of_code_->s_reg_low);
55967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell        rl_method = LoadValue(rl_method, kCoreReg);
56067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell
56167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell        // Load the proper value from the literal area.
56267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell        // We don't know the proper offset for the value, so pick one that will force
56367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell        // 4 byte offset.  We will fix this up in the assembler later to have the right
56467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell        // value.
5650c52451e9be14a6bff9ffefce89ff1d60691af60Mark Mendell        res = LoadBaseDisp(rl_method.reg, 256 /* bogus */, RegStorage::FloatSolo64(low_reg_val),
5663bf7c60a86d49bf8c05c5d2ac5ca8e9f80bd9824Vladimir Marko                           kDouble);
56767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell        res->target = data_target;
56867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell        res->flags.fixup = kFixupLoad;
56967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell        SetMemRefType(res, true, kLiteral);
57055d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell        store_method_addr_used_ = true;
571b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers      } else {
572fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee        if (val_lo == 0) {
5732700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee          res = NewLIR2(kX86XorpsRR, low_reg_val, low_reg_val);
574b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers        } else {
5752700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee          res = LoadConstantNoClobber(RegStorage::Solo32(low_reg_val), val_lo);
576b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers        }
577fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee        if (val_hi != 0) {
5782700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee          RegStorage r_dest_hi = AllocTempDouble();
579091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee          LoadConstantNoClobber(r_dest_hi, val_hi);
580091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee          NewLIR2(kX86PunpckldqRR, low_reg_val, r_dest_hi.GetReg());
581d61ba4ba6fcde666adb5d5c81b1c32f0534fb2c8Bill Buzbee          FreeTemp(r_dest_hi);
582b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers        }
583b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers      }
584b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers    } else {
5852700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      res = LoadConstantNoClobber(r_dest.GetLow(), val_lo);
5862700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      LoadConstantNoClobber(r_dest.GetHigh(), val_hi);
587b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers    }
588e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee    return res;
589e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee}
590e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
5912700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::LoadBaseIndexedDisp(RegStorage r_base, RegStorage r_index, int scale,
5923bf7c60a86d49bf8c05c5d2ac5ca8e9f80bd9824Vladimir Marko                                     int displacement, RegStorage r_dest, OpSize size) {
593b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  LIR *load = NULL;
594b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  LIR *load2 = NULL;
5952700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  bool is_array = r_index.Valid();
596091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  bool pair = r_dest.IsPair();
597091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  bool is64bit = ((size == k64) || (size == kDouble));
598b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  X86OpCode opcode = kX86Nop;
599b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  switch (size) {
600695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee    case k64:
601b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kDouble:
602091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      if (r_dest.IsFloat()) {
603fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee        opcode = is_array ? kX86MovsdRA : kX86MovsdRM;
604b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      } else {
605fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee        opcode = is_array ? kX86Mov32RA  : kX86Mov32RM;
606b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      }
607b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      // TODO: double store is to unaligned address
608b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      DCHECK_EQ((displacement & 0x3), 0);
609b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      break;
6109ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko    case kWord:
6119ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      if (Gen64Bit()) {
6129ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko        opcode = is_array ? kX86Mov64RA  : kX86Mov64RM;
6139ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko        CHECK_EQ(is_array, false);
6149ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko        CHECK_EQ(r_dest.IsFloat(), false);
6159ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko        break;
6169ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      }  // else fall-through to k32 case
617695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee    case k32:
618b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kSingle:
619695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee    case kReference:  // TODO: update for reference decompression on 64-bit targets.
620fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      opcode = is_array ? kX86Mov32RA : kX86Mov32RM;
621091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      if (r_dest.IsFloat()) {
622fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee        opcode = is_array ? kX86MovssRA : kX86MovssRM;
623091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee        DCHECK(r_dest.IsFloat());
624b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      }
625b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      DCHECK_EQ((displacement & 0x3), 0);
626b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      break;
627b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kUnsignedHalf:
628fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      opcode = is_array ? kX86Movzx16RA : kX86Movzx16RM;
629b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      DCHECK_EQ((displacement & 0x1), 0);
630b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      break;
631b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kSignedHalf:
632fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      opcode = is_array ? kX86Movsx16RA : kX86Movsx16RM;
633b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      DCHECK_EQ((displacement & 0x1), 0);
634b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      break;
635b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kUnsignedByte:
636fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      opcode = is_array ? kX86Movzx8RA : kX86Movzx8RM;
637b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      break;
638b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kSignedByte:
639fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      opcode = is_array ? kX86Movsx8RA : kX86Movsx8RM;
640b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      break;
641b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    default:
64252a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee      LOG(FATAL) << "Bad case in LoadBaseIndexedDispBody";
643b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  }
644b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers
645fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (!is_array) {
646b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    if (!pair) {
6472700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      load = NewLIR3(opcode, r_dest.GetReg(), r_base.GetReg(), displacement + LOWORD_OFFSET);
648e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee    } else {
649091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      DCHECK(!r_dest.IsFloat());  // Make sure we're not still using a pair here.
650091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      if (r_base == r_dest.GetLow()) {
651091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee        load2 = NewLIR3(opcode, r_dest.GetHighReg(), r_base.GetReg(),
652fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao                        displacement + HIWORD_OFFSET);
653091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee        load = NewLIR3(opcode, r_dest.GetLowReg(), r_base.GetReg(), displacement + LOWORD_OFFSET);
654fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao      } else {
655091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee        load = NewLIR3(opcode, r_dest.GetLowReg(), r_base.GetReg(), displacement + LOWORD_OFFSET);
656091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee        load2 = NewLIR3(opcode, r_dest.GetHighReg(), r_base.GetReg(),
657fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao                        displacement + HIWORD_OFFSET);
658fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao      }
659e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee    }
6602700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    if (r_base == rs_rX86_SP) {
6611fd3346740dfb7f47be9922312b68a4227fada96buzbee      AnnotateDalvikRegAccess(load, (displacement + (pair ? LOWORD_OFFSET : 0)) >> 2,
66202031b185b4653e6c72e21f7a51238b903f6d638buzbee                              true /* is_load */, is64bit);
663f7d9ad39541dd09030e26d54d3b73a076f90cc74Ian Rogers      if (pair) {
6641fd3346740dfb7f47be9922312b68a4227fada96buzbee        AnnotateDalvikRegAccess(load2, (displacement + HIWORD_OFFSET) >> 2,
665fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                                true /* is_load */, is64bit);
666b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      }
667e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee    }
668b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  } else {
669b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    if (!pair) {
6702700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      load = NewLIR5(opcode, r_dest.GetReg(), r_base.GetReg(), r_index.GetReg(), scale,
671a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                     displacement + LOWORD_OFFSET);
672b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    } else {
673091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      DCHECK(!r_dest.IsFloat());  // Make sure we're not still using a pair here.
674091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      if (r_base == r_dest.GetLow()) {
675091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee        if (r_dest.GetHigh() == r_index) {
676ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell          // We can't use either register for the first load.
6772700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee          RegStorage temp = AllocTemp();
6782700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee          load2 = NewLIR5(opcode, temp.GetReg(), r_base.GetReg(), r_index.GetReg(), scale,
679ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell                          displacement + HIWORD_OFFSET);
680091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee          load = NewLIR5(opcode, r_dest.GetLowReg(), r_base.GetReg(), r_index.GetReg(), scale,
681ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell                         displacement + LOWORD_OFFSET);
682091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee          OpRegCopy(r_dest.GetHigh(), temp);
683ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell          FreeTemp(temp);
684ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell        } else {
685091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee          load2 = NewLIR5(opcode, r_dest.GetHighReg(), r_base.GetReg(), r_index.GetReg(), scale,
686ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell                          displacement + HIWORD_OFFSET);
687091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee          load = NewLIR5(opcode, r_dest.GetLowReg(), r_base.GetReg(), r_index.GetReg(), scale,
688ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell                         displacement + LOWORD_OFFSET);
689ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell        }
690fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao      } else {
691091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee        if (r_dest.GetLow() == r_index) {
692ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell          // We can't use either register for the first load.
6932700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee          RegStorage temp = AllocTemp();
6942700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee          load = NewLIR5(opcode, temp.GetReg(), r_base.GetReg(), r_index.GetReg(), scale,
695ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell                         displacement + LOWORD_OFFSET);
696091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee          load2 = NewLIR5(opcode, r_dest.GetHighReg(), r_base.GetReg(), r_index.GetReg(), scale,
697ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell                          displacement + HIWORD_OFFSET);
698091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee          OpRegCopy(r_dest.GetLow(), temp);
699ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell          FreeTemp(temp);
700ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell        } else {
701091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee          load = NewLIR5(opcode, r_dest.GetLowReg(), r_base.GetReg(), r_index.GetReg(), scale,
702ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell                         displacement + LOWORD_OFFSET);
703091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee          load2 = NewLIR5(opcode, r_dest.GetHighReg(), r_base.GetReg(), r_index.GetReg(), scale,
704ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell                          displacement + HIWORD_OFFSET);
705ae427c3ba8d05599919c16f0c7c8983919cf7da3Mark Mendell        }
706fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao      }
707b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    }
708b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  }
709b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers
710b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  return load;
711e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee}
712e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
7135772babbe824494ef9fe90a1b07a926d124bb7c7jeffhao/* Load value from base + scaled index. */
7142700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::LoadBaseIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_dest,
7152700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee                                 int scale, OpSize size) {
7163bf7c60a86d49bf8c05c5d2ac5ca8e9f80bd9824Vladimir Marko  return LoadBaseIndexedDisp(r_base, r_index, scale, 0, r_dest, size);
7175772babbe824494ef9fe90a1b07a926d124bb7c7jeffhao}
7185772babbe824494ef9fe90a1b07a926d124bb7c7jeffhao
719674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir MarkoLIR* X86Mir2Lir::LoadBaseDispVolatile(RegStorage r_base, int displacement, RegStorage r_dest,
720674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko                                      OpSize size) {
721674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko  // LoadBaseDisp() will emit correct insn for atomic load on x86
722674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko  // assuming r_dest is correctly prepared using RegClassForFieldLoadStore().
723674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko  return LoadBaseDisp(r_base, displacement, r_dest, size);
724674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko}
725674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko
726091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbeeLIR* X86Mir2Lir::LoadBaseDisp(RegStorage r_base, int displacement, RegStorage r_dest,
7273bf7c60a86d49bf8c05c5d2ac5ca8e9f80bd9824Vladimir Marko                              OpSize size) {
728091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  return LoadBaseIndexedDisp(r_base, RegStorage::InvalidReg(), 0, displacement, r_dest,
7293bf7c60a86d49bf8c05c5d2ac5ca8e9f80bd9824Vladimir Marko                             size);
730e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee}
731e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
7322700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::StoreBaseIndexedDisp(RegStorage r_base, RegStorage r_index, int scale,
7333bf7c60a86d49bf8c05c5d2ac5ca8e9f80bd9824Vladimir Marko                                      int displacement, RegStorage r_src, OpSize size) {
734b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  LIR *store = NULL;
735e296248a124ed8287b38a9225463696c18d84cd6jeffhao  LIR *store2 = NULL;
7362700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee  bool is_array = r_index.Valid();
737091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  bool pair = r_src.IsPair();
738091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee  bool is64bit = (size == k64) || (size == kDouble);
739b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers  X86OpCode opcode = kX86Nop;
740b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  switch (size) {
741695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee    case k64:
742b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kDouble:
743091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      if (r_src.IsFloat()) {
744fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee        opcode = is_array ? kX86MovsdAR : kX86MovsdMR;
745b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      } else {
7469ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko        if (Gen64Bit()) {
7479ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko          opcode = is_array ? kX86Mov64AR  : kX86Mov64MR;
7489ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko        } else {
7499ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko          // TODO(64): pair = true;
7509ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko          opcode = is_array ? kX86Mov32AR  : kX86Mov32MR;
7519ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko        }
752b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      }
753b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      // TODO: double store is to unaligned address
754b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      DCHECK_EQ((displacement & 0x3), 0);
755b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      break;
7569ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko    case kWord:
7579ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      if (Gen64Bit()) {
7589ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko        opcode = is_array ? kX86Mov64AR  : kX86Mov64MR;
7599ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko        CHECK_EQ(is_array, false);
7609ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko        CHECK_EQ(r_src.IsFloat(), false);
7619ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko        break;
7629ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko      }  // else fall-through to k32 case
763695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee    case k32:
764b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kSingle:
765695d13a82d6dd801aaa57a22a9d4b3f6db0d0fdbbuzbee    case kReference:
766fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      opcode = is_array ? kX86Mov32AR : kX86Mov32MR;
767091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      if (r_src.IsFloat()) {
768fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee        opcode = is_array ? kX86MovssAR : kX86MovssMR;
769091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee        DCHECK(r_src.IsSingle());
770b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      }
771b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      DCHECK_EQ((displacement & 0x3), 0);
772b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      break;
773b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kUnsignedHalf:
774b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kSignedHalf:
775fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      opcode = is_array ? kX86Mov16AR : kX86Mov16MR;
776b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      DCHECK_EQ((displacement & 0x1), 0);
777b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      break;
778b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kUnsignedByte:
779b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    case kSignedByte:
780fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee      opcode = is_array ? kX86Mov8AR : kX86Mov8MR;
781b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers      break;
782b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers    default:
78300e1ec6581b5b7b46ca4c314c2854e9caa647dd2Bill Buzbee      LOG(FATAL) << "Bad case in StoreBaseIndexedDispBody";
784b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  }
785b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers
786fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee  if (!is_array) {
787b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers    if (!pair) {
7882700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      store = NewLIR3(opcode, r_base.GetReg(), displacement + LOWORD_OFFSET, r_src.GetReg());
789b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers    } else {
790091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      DCHECK(!r_src.IsFloat());  // Make sure we're not still using a pair here.
791091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      store = NewLIR3(opcode, r_base.GetReg(), displacement + LOWORD_OFFSET, r_src.GetLowReg());
792091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      store2 = NewLIR3(opcode, r_base.GetReg(), displacement + HIWORD_OFFSET, r_src.GetHighReg());
793e296248a124ed8287b38a9225463696c18d84cd6jeffhao    }
7942700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    if (r_base == rs_rX86_SP) {
7951fd3346740dfb7f47be9922312b68a4227fada96buzbee      AnnotateDalvikRegAccess(store, (displacement + (pair ? LOWORD_OFFSET : 0)) >> 2,
79602031b185b4653e6c72e21f7a51238b903f6d638buzbee                              false /* is_load */, is64bit);
797e296248a124ed8287b38a9225463696c18d84cd6jeffhao      if (pair) {
7981fd3346740dfb7f47be9922312b68a4227fada96buzbee        AnnotateDalvikRegAccess(store2, (displacement + HIWORD_OFFSET) >> 2,
799fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee                                false /* is_load */, is64bit);
800e296248a124ed8287b38a9225463696c18d84cd6jeffhao      }
801b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers    }
802b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  } else {
803b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers    if (!pair) {
8042700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      store = NewLIR5(opcode, r_base.GetReg(), r_index.GetReg(), scale,
8052700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee                      displacement + LOWORD_OFFSET, r_src.GetReg());
806b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers    } else {
807091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee      DCHECK(!r_src.IsFloat());  // Make sure we're not still using a pair here.
8082700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      store = NewLIR5(opcode, r_base.GetReg(), r_index.GetReg(), scale,
809091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee                      displacement + LOWORD_OFFSET, r_src.GetLowReg());
8102700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee      store2 = NewLIR5(opcode, r_base.GetReg(), r_index.GetReg(), scale,
811091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee                       displacement + HIWORD_OFFSET, r_src.GetHighReg());
812e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee    }
813b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers  }
814b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers  return store;
815e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee}
816e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
817c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers/* store value base base + scaled index. */
8182700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::StoreBaseIndexed(RegStorage r_base, RegStorage r_index, RegStorage r_src,
8192ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom                      int scale, OpSize size) {
8203bf7c60a86d49bf8c05c5d2ac5ca8e9f80bd9824Vladimir Marko  return StoreBaseIndexedDisp(r_base, r_index, scale, 0, r_src, size);
821c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers}
822c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers
823674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir MarkoLIR* X86Mir2Lir::StoreBaseDispVolatile(RegStorage r_base, int displacement,
824674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko                                       RegStorage r_src, OpSize size) {
825674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko  // StoreBaseDisp() will emit correct insn for atomic store on x86
826674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko  // assuming r_dest is correctly prepared using RegClassForFieldLoadStore().
827674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko  return StoreBaseDisp(r_base, displacement, r_src, size);
828674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko}
829674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko
8302700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::StoreBaseDisp(RegStorage r_base, int displacement,
8312700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee                               RegStorage r_src, OpSize size) {
8323bf7c60a86d49bf8c05c5d2ac5ca8e9f80bd9824Vladimir Marko  return StoreBaseIndexedDisp(r_base, RegStorage::InvalidReg(), 0, displacement, r_src, size);
833e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee}
834e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee
8352700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbeeLIR* X86Mir2Lir::OpCmpMemImmBranch(ConditionCode cond, RegStorage temp_reg, RegStorage base_reg,
836766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell                                   int offset, int check_value, LIR* target) {
8372700f7e1edbcd2518f4978e4cd0e05a4149f91b6buzbee    NewLIR3(IS_SIMM8(check_value) ? kX86Cmp32MI8 : kX86Cmp32MI, base_reg.GetReg(), offset,
838766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell            check_value);
839766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell    LIR* branch = OpCondBranch(cond, target);
840766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell    return branch;
841766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell}
842766e9295d2c34cd1846d81610c9045b5d5093dddMark Mendell
84367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendellvoid X86Mir2Lir::AnalyzeMIR() {
84467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  // Assume we don't need a pointer to the base of the code.
84567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  cu_->NewTimingSplit("X86 MIR Analysis");
84667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  store_method_addr_ = false;
84767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell
84867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  // Walk the MIR looking for interesting items.
84967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  PreOrderDfsIterator iter(mir_graph_);
85067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  BasicBlock* curr_bb = iter.Next();
85167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  while (curr_bb != NULL) {
85267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    AnalyzeBB(curr_bb);
85367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    curr_bb = iter.Next();
85467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  }
85567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell
85667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  // Did we need a pointer to the method code?
85767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  if (store_method_addr_) {
85867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    base_of_code_ = mir_graph_->GetNewCompilerTemp(kCompilerTempVR, false);
85967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  } else {
86067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    base_of_code_ = nullptr;
86167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  }
86267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell}
86367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell
86467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendellvoid X86Mir2Lir::AnalyzeBB(BasicBlock * bb) {
86567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  if (bb->block_type == kDead) {
86667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    // Ignore dead blocks
86767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    return;
86867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  }
86967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell
87067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  for (MIR *mir = bb->first_mir_insn; mir != NULL; mir = mir->next) {
87167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    int opcode = mir->dalvikInsn.opcode;
87235ba7f3a78d38885ec54e61ed060d2771eeceea7buzbee    if (MIRGraph::IsPseudoMirOp(opcode)) {
87367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell      AnalyzeExtendedMIR(opcode, bb, mir);
87467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    } else {
87567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell      AnalyzeMIR(opcode, bb, mir);
87667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    }
87767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  }
87867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell}
87967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell
88067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell
88167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendellvoid X86Mir2Lir::AnalyzeExtendedMIR(int opcode, BasicBlock * bb, MIR *mir) {
88267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  switch (opcode) {
88367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    // Instructions referencing doubles.
88467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    case kMirOpFusedCmplDouble:
88567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    case kMirOpFusedCmpgDouble:
88667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell      AnalyzeFPInstruction(opcode, bb, mir);
88767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell      break;
888d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell    case kMirOpConstVector:
889d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell      store_method_addr_ = true;
890d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell      break;
89167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    default:
89267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell      // Ignore the rest.
89367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell      break;
89467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  }
89567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell}
89667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell
89767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendellvoid X86Mir2Lir::AnalyzeMIR(int opcode, BasicBlock * bb, MIR *mir) {
89867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  // Looking for
89967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  // - Do we need a pointer to the code (used for packed switches and double lits)?
90067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell
90167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  switch (opcode) {
90267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    // Instructions referencing doubles.
90367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    case Instruction::CMPL_DOUBLE:
90467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    case Instruction::CMPG_DOUBLE:
90567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    case Instruction::NEG_DOUBLE:
90667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    case Instruction::ADD_DOUBLE:
90767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    case Instruction::SUB_DOUBLE:
90867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    case Instruction::MUL_DOUBLE:
90967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    case Instruction::DIV_DOUBLE:
91067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    case Instruction::REM_DOUBLE:
91167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    case Instruction::ADD_DOUBLE_2ADDR:
91267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    case Instruction::SUB_DOUBLE_2ADDR:
91367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    case Instruction::MUL_DOUBLE_2ADDR:
91467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    case Instruction::DIV_DOUBLE_2ADDR:
91567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    case Instruction::REM_DOUBLE_2ADDR:
91667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell      AnalyzeFPInstruction(opcode, bb, mir);
91767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell      break;
91855d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell
91967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    // Packed switches and array fills need a pointer to the base of the method.
92067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    case Instruction::FILL_ARRAY_DATA:
92167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    case Instruction::PACKED_SWITCH:
92267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell      store_method_addr_ = true;
92367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell      break;
92467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    default:
92567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell      // Other instructions are not interesting yet.
92667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell      break;
92767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  }
92867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell}
92967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell
93067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendellvoid X86Mir2Lir::AnalyzeFPInstruction(int opcode, BasicBlock * bb, MIR *mir) {
93167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  // Look at all the uses, and see if they are double constants.
932cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyler  uint64_t attrs = MIRGraph::GetDataFlowAttributes(static_cast<Instruction::Code>(opcode));
93367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  int next_sreg = 0;
93467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  if (attrs & DF_UA) {
93567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    if (attrs & DF_A_WIDE) {
93667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell      AnalyzeDoubleUse(mir_graph_->GetSrcWide(mir, next_sreg));
93767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell      next_sreg += 2;
93867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    } else {
93967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell      next_sreg++;
94067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    }
94167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  }
94267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  if (attrs & DF_UB) {
94367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    if (attrs & DF_B_WIDE) {
94467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell      AnalyzeDoubleUse(mir_graph_->GetSrcWide(mir, next_sreg));
94567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell      next_sreg += 2;
94667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    } else {
94767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell      next_sreg++;
94867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    }
94967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  }
95067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  if (attrs & DF_UC) {
95167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    if (attrs & DF_C_WIDE) {
95267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell      AnalyzeDoubleUse(mir_graph_->GetSrcWide(mir, next_sreg));
95367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    }
95467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  }
95567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell}
95667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell
95767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendellvoid X86Mir2Lir::AnalyzeDoubleUse(RegLocation use) {
95867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  // If this is a double literal, we will want it in the literal pool.
95967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  if (use.is_const) {
96067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell    store_method_addr_ = true;
96167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell  }
96267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell}
96367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell
96430adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbeeRegLocation X86Mir2Lir::UpdateLocTyped(RegLocation loc, int reg_class) {
96530adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee  loc = UpdateLoc(loc);
96630adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee  if ((loc.location == kLocPhysReg) && (loc.fp != loc.reg.IsFloat())) {
96730adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee    if (GetRegInfo(loc.reg)->IsTemp()) {
96830adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee      Clobber(loc.reg);
96930adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee      FreeTemp(loc.reg);
97030adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee      loc.reg = RegStorage::InvalidReg();
97130adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee      loc.location = kLocDalvikFrame;
97230adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee    }
97330adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee  }
97430adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee  return loc;
97530adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee}
97630adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee
97730adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbeeRegLocation X86Mir2Lir::UpdateLocWideTyped(RegLocation loc, int reg_class) {
97830adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee  loc = UpdateLocWide(loc);
97930adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee  if ((loc.location == kLocPhysReg) && (loc.fp != loc.reg.IsFloat())) {
98030adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee    if (GetRegInfo(loc.reg)->IsTemp()) {
98130adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee      Clobber(loc.reg);
98230adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee      FreeTemp(loc.reg);
98330adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee      loc.reg = RegStorage::InvalidReg();
98430adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee      loc.location = kLocDalvikFrame;
98530adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee    }
98630adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee  }
98730adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee  return loc;
98830adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee}
98930adc7383a74eb3cb6db3bf42cea3a5595055ce1buzbee
990e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee}  // namespace art
991