utility_x86.cc revision 1fd3346740dfb7f47be9922312b68a4227fada96
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" 18641ce0371c2f0dc95d26be02d8366124c8b66653Brian Carlstrom#include "x86_lir.h" 191bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee 20e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbeenamespace art { 21e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 22b046e16d8b8da318d6055f9308950131f1255e08buzbee/* This file contains codegen for the X86 ISA */ 23e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 241fd3346740dfb7f47be9922312b68a4227fada96buzbeeLIR* X86Mir2Lir::OpFpRegCopy(int r_dest, int r_src) 25e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee{ 26a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int opcode; 27a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* must be both DOUBLE or both not DOUBLE */ 28fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK_EQ(X86_DOUBLEREG(r_dest), X86_DOUBLEREG(r_src)); 29fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (X86_DOUBLEREG(r_dest)) { 30a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kX86MovsdRR; 31a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 32fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (X86_SINGLEREG(r_dest)) { 33fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (X86_SINGLEREG(r_src)) { 34a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kX86MovssRR; 35a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { // Fpr <- Gpr 36a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kX86MovdxrRR; 37a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 38a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { // Gpr <- Fpr 39fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(X86_SINGLEREG(r_src)); 40a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kX86MovdrxRR; 41e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 42a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 43ec13743da80a80c1817cf6660c28917fc28846bcbuzbee DCHECK_NE((EncodingMap[opcode].flags & IS_BINARY_OP), 0ULL); 441fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* res = RawLIR(current_dalvik_offset_, opcode, r_dest, r_src); 45fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (r_dest == r_src) { 46fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee res->flags.is_nop = true; 47a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 48a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return res; 49e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 50e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 511fd3346740dfb7f47be9922312b68a4227fada96buzbeebool X86Mir2Lir::InexpensiveConstantInt(int32_t value) 52e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee{ 53e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee return true; 54e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee} 55e6285f99a53a344efd6f8409ff5f43a3e80190dbbuzbee 561fd3346740dfb7f47be9922312b68a4227fada96buzbeebool X86Mir2Lir::InexpensiveConstantFloat(int32_t value) 574ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee{ 584ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee return false; 594ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee} 604ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee 611fd3346740dfb7f47be9922312b68a4227fada96buzbeebool X86Mir2Lir::InexpensiveConstantLong(int64_t value) 624ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee{ 634ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee return true; 644ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee} 654ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee 661fd3346740dfb7f47be9922312b68a4227fada96buzbeebool X86Mir2Lir::InexpensiveConstantDouble(int64_t value) 674ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee{ 684ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee return false; // TUNING 694ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee} 704ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee 71e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee/* 72e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * Load a immediate using a shortcut if possible; otherwise 73e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * grab from the per-translation literal pool. If target is 74e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * a high register, build constant into a low register and copy. 75e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * 76e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * No additional register clobbering operation performed. Use this version when 77fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee * 1) r_dest is freshly returned from AllocTemp or 78e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * 2) The codegen is under fixed register usage 79e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee */ 801fd3346740dfb7f47be9922312b68a4227fada96buzbeeLIR* X86Mir2Lir::LoadConstantNoClobber(int r_dest, int value) 81a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee{ 82fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int r_dest_save = r_dest; 83fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (X86_FPREG(r_dest)) { 84b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers if (value == 0) { 851fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR2(kX86XorpsRR, r_dest, r_dest); 86b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 87fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(X86_SINGLEREG(r_dest)); 881fd3346740dfb7f47be9922312b68a4227fada96buzbee r_dest = AllocTemp(); 896cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers } 90e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 91b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers LIR *res; 926cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers if (value == 0) { 931fd3346740dfb7f47be9922312b68a4227fada96buzbee res = NewLIR2(kX86Xor32RR, r_dest, r_dest); 946cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers } else { 952e9f7ed8d00271cb1cf082d68b4f4bc60702d6ecIan Rogers // Note, there is no byte immediate form of a 32 bit immediate move. 961fd3346740dfb7f47be9922312b68a4227fada96buzbee res = NewLIR2(kX86Mov32RI, r_dest, value); 976cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers } 98e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 99fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (X86_FPREG(r_dest_save)) { 1001fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kX86MovdxrRR, r_dest_save, r_dest); 1011fd3346740dfb7f47be9922312b68a4227fada96buzbee FreeTemp(r_dest); 1026cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers } 103e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 1046cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers return res; 105e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 106e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 1071fd3346740dfb7f47be9922312b68a4227fada96buzbeeLIR* X86Mir2Lir::OpUnconditionalBranch(LIR* target) 108a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee{ 1091fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* res = NewLIR1(kX86Jmp8, 0 /* offset to be patched during assembly*/ ); 11002031b185b4653e6c72e21f7a51238b903f6d638buzbee res->target = target; 11102031b185b4653e6c72e21f7a51238b903f6d638buzbee return res; 112e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 113e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 1141fd3346740dfb7f47be9922312b68a4227fada96buzbeeLIR* X86Mir2Lir::OpCondBranch(ConditionCode cc, LIR* target) 115a7678db092ac6bb79f7cad490099a1015fbbc714buzbee{ 1161fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* branch = NewLIR2(kX86Jcc8, 0 /* offset to be patched */, 11752a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee X86ConditionEncoding(cc)); 118b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers branch->target = target; 119b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers return branch; 120a7678db092ac6bb79f7cad490099a1015fbbc714buzbee} 121a7678db092ac6bb79f7cad490099a1015fbbc714buzbee 1221fd3346740dfb7f47be9922312b68a4227fada96buzbeeLIR* X86Mir2Lir::OpReg(OpKind op, int r_dest_src) 123a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee{ 124b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers X86OpCode opcode = kX86Bkpt; 125b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers switch (op) { 126b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpNeg: opcode = kX86Neg32R; break; 1271395b1e06c1d0ff5155b0c5d113ad3bd6f163c07jeffhao case kOpNot: opcode = kX86Not32R; break; 128b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpBlx: opcode = kX86CallR; break; 129b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers default: 13052a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee LOG(FATAL) << "Bad case in OpReg " << op; 131b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 1321fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR1(opcode, r_dest_src); 133e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 134e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 1351fd3346740dfb7f47be9922312b68a4227fada96buzbeeLIR* X86Mir2Lir::OpRegImm(OpKind op, int r_dest_src1, int value) 136a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee{ 137b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers X86OpCode opcode = kX86Bkpt; 138fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bool byte_imm = IS_SIMM8(value); 139fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(!X86_FPREG(r_dest_src1)); 140b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers switch (op) { 141b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpLsl: opcode = kX86Sal32RI; break; 142b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpLsr: opcode = kX86Shr32RI; break; 143b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpAsr: opcode = kX86Sar32RI; break; 144fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee case kOpAdd: opcode = byte_imm ? kX86Add32RI8 : kX86Add32RI; break; 145fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee case kOpOr: opcode = byte_imm ? kX86Or32RI8 : kX86Or32RI; break; 146fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee case kOpAdc: opcode = byte_imm ? kX86Adc32RI8 : kX86Adc32RI; break; 147b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers //case kOpSbb: opcode = kX86Sbb32RI; break; 148fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee case kOpAnd: opcode = byte_imm ? kX86And32RI8 : kX86And32RI; break; 149fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee case kOpSub: opcode = byte_imm ? kX86Sub32RI8 : kX86Sub32RI; break; 150fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee case kOpXor: opcode = byte_imm ? kX86Xor32RI8 : kX86Xor32RI; break; 151fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee case kOpCmp: opcode = byte_imm ? kX86Cmp32RI8 : kX86Cmp32RI; break; 1521fd3346740dfb7f47be9922312b68a4227fada96buzbee case kOpMov: return LoadConstantNoClobber(r_dest_src1, value); 153b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpMul: 154fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = byte_imm ? kX86Imul32RRI8 : kX86Imul32RRI; 1551fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR3(opcode, r_dest_src1, r_dest_src1, value); 156b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers default: 15752a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee LOG(FATAL) << "Bad case in OpRegImm " << op; 158b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 1591fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR2(opcode, r_dest_src1, value); 160e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 161e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 1621fd3346740dfb7f47be9922312b68a4227fada96buzbeeLIR* X86Mir2Lir::OpRegReg(OpKind op, int r_dest_src1, int r_src2) 163e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee{ 164a7678db092ac6bb79f7cad490099a1015fbbc714buzbee X86OpCode opcode = kX86Nop; 165d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers bool src2_must_be_cx = false; 166e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee switch (op) { 167b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers // X86 unary opcodes 168b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpMvn: 1691fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegCopy(r_dest_src1, r_src2); 1701fd3346740dfb7f47be9922312b68a4227fada96buzbee return OpReg(kOpNot, r_dest_src1); 171b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpNeg: 1721fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegCopy(r_dest_src1, r_src2); 1731fd3346740dfb7f47be9922312b68a4227fada96buzbee return OpReg(kOpNeg, r_dest_src1); 174b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers // X86 binary opcodes 175b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpSub: opcode = kX86Sub32RR; break; 176b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpSbc: opcode = kX86Sbb32RR; break; 177d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers case kOpLsl: opcode = kX86Sal32RC; src2_must_be_cx = true; break; 178d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers case kOpLsr: opcode = kX86Shr32RC; src2_must_be_cx = true; break; 179d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers case kOpAsr: opcode = kX86Sar32RC; src2_must_be_cx = true; break; 180b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpMov: opcode = kX86Mov32RR; break; 181b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpCmp: opcode = kX86Cmp32RR; break; 182b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpAdd: opcode = kX86Add32RR; break; 183b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpAdc: opcode = kX86Adc32RR; break; 184b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpAnd: opcode = kX86And32RR; break; 185b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpOr: opcode = kX86Or32RR; break; 186b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpXor: opcode = kX86Xor32RR; break; 187703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao case kOp2Byte: 188703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao // Use shifts instead of a byte operand if the source can't be byte accessed. 189fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (r_src2 >= 4) { 1901fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kX86Mov32RR, r_dest_src1, r_src2); 1911fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kX86Sal32RI, r_dest_src1, 24); 1921fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR2(kX86Sar32RI, r_dest_src1, 24); 193703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao } else { 194703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao opcode = kX86Movsx8RR; 195703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao } 196703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao break; 197b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOp2Short: opcode = kX86Movsx16RR; break; 198b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOp2Char: opcode = kX86Movzx16RR; break; 199b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpMul: opcode = kX86Imul32RR; break; 200b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers default: 20152a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee LOG(FATAL) << "Bad case in OpRegReg " << op; 202b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 203e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 204fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee CHECK(!src2_must_be_cx || r_src2 == rCX); 2051fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR2(opcode, r_dest_src1, r_src2); 206e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 207e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 2081fd3346740dfb7f47be9922312b68a4227fada96buzbeeLIR* X86Mir2Lir::OpRegMem(OpKind op, int r_dest, int rBase, 209a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int offset) 210a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee{ 211b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers X86OpCode opcode = kX86Nop; 212b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers switch (op) { 213b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers // X86 binary opcodes 214b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpSub: opcode = kX86Sub32RM; break; 215b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpMov: opcode = kX86Mov32RM; break; 216b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpCmp: opcode = kX86Cmp32RM; break; 217b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpAdd: opcode = kX86Add32RM; break; 218b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpAnd: opcode = kX86And32RM; break; 219b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpOr: opcode = kX86Or32RM; break; 220b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpXor: opcode = kX86Xor32RM; break; 221b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOp2Byte: opcode = kX86Movsx8RM; break; 222b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOp2Short: opcode = kX86Movsx16RM; break; 223b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOp2Char: opcode = kX86Movzx16RM; break; 224b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpMul: 225b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers default: 22652a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee LOG(FATAL) << "Bad case in OpRegMem " << op; 227b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 228b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 2291fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR3(opcode, r_dest, rBase, offset); 230b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers} 231e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 2321fd3346740dfb7f47be9922312b68a4227fada96buzbeeLIR* X86Mir2Lir::OpRegRegReg(OpKind op, int r_dest, int r_src1, 233fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int r_src2) 234a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee{ 235fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (r_dest != r_src1 && r_dest != r_src2) { 236b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers if (op == kOpAdd) { // lea special case, except can't encode rbp as base 237fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (r_src1 == r_src2) { 2381fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegCopy(r_dest, r_src1); 2391fd3346740dfb7f47be9922312b68a4227fada96buzbee return OpRegImm(kOpLsl, r_dest, 1); 240fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee } else if (r_src1 != rBP) { 2411fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR5(kX86Lea32RA, r_dest, r_src1 /* base */, 242fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_src2 /* index */, 0 /* scale */, 0 /* disp */); 243b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 2441fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR5(kX86Lea32RA, r_dest, r_src2 /* base */, 245fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_src1 /* index */, 0 /* scale */, 0 /* disp */); 246b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 247b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 2481fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegCopy(r_dest, r_src1); 2491fd3346740dfb7f47be9922312b68a4227fada96buzbee return OpRegReg(op, r_dest, r_src2); 250e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 251fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee } else if (r_dest == r_src1) { 2521fd3346740dfb7f47be9922312b68a4227fada96buzbee return OpRegReg(op, r_dest, r_src2); 253fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee } else { // r_dest == r_src2 254b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers switch (op) { 255b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpSub: // non-commutative 2561fd3346740dfb7f47be9922312b68a4227fada96buzbee OpReg(kOpNeg, r_dest); 257b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers op = kOpAdd; 258b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 259b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpSbc: 260b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpLsl: case kOpLsr: case kOpAsr: case kOpRor: { 2611fd3346740dfb7f47be9922312b68a4227fada96buzbee int t_reg = AllocTemp(); 2621fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegCopy(t_reg, r_src1); 2631fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegReg(op, t_reg, r_src2); 2641fd3346740dfb7f47be9922312b68a4227fada96buzbee LIR* res = OpRegCopy(r_dest, t_reg); 2651fd3346740dfb7f47be9922312b68a4227fada96buzbee FreeTemp(t_reg); 266b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers return res; 267b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 268b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpAdd: // commutative 269b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpOr: 270b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpAdc: 271b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpAnd: 272b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpXor: 273b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 274b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers default: 27552a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee LOG(FATAL) << "Bad case in OpRegRegReg " << op; 276e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 2771fd3346740dfb7f47be9922312b68a4227fada96buzbee return OpRegReg(op, r_dest, r_src1); 278b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 279e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 280e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 2811fd3346740dfb7f47be9922312b68a4227fada96buzbeeLIR* X86Mir2Lir::OpRegRegImm(OpKind op, int r_dest, int r_src, 282a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int value) 283a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee{ 284b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers if (op == kOpMul) { 285b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers X86OpCode opcode = IS_SIMM8(value) ? kX86Imul32RRI8 : kX86Imul32RRI; 2861fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR3(opcode, r_dest, r_src, value); 287b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } else if (op == kOpAnd) { 288fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (value == 0xFF && r_src < 4) { 2891fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR2(kX86Movzx8RR, r_dest, r_src); 290b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } else if (value == 0xFFFF) { 2911fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR2(kX86Movzx16RR, r_dest, r_src); 292b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 293b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 294fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (r_dest != r_src) { 2957caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers if (false && op == kOpLsl && value >= 0 && value <= 3) { // lea shift special case 2967caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers // TODO: fix bug in LEA encoding when disp == 0 2971fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR5(kX86Lea32RA, r_dest, r5sib_no_base /* base */, 298fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_src /* index */, value /* scale */, 0 /* disp */); 299b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } else if (op == kOpAdd) { // lea add special case 3001fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR5(kX86Lea32RA, r_dest, r_src /* base */, 301b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers r4sib_no_index /* index */, 0 /* scale */, value /* disp */); 302e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 3031fd3346740dfb7f47be9922312b68a4227fada96buzbee OpRegCopy(r_dest, r_src); 304b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 3051fd3346740dfb7f47be9922312b68a4227fada96buzbee return OpRegImm(op, r_dest, value); 306e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 307e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 3081fd3346740dfb7f47be9922312b68a4227fada96buzbeeLIR* X86Mir2Lir::OpThreadMem(OpKind op, int thread_offset) 309a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee{ 3106cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers X86OpCode opcode = kX86Bkpt; 3116cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers switch (op) { 3126cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers case kOpBlx: opcode = kX86CallT; break; 3136cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers default: 3146cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers LOG(FATAL) << "Bad opcode: " << op; 3156cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers break; 3166cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers } 3171fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR1(opcode, thread_offset); 3186cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers} 3196cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers 3201fd3346740dfb7f47be9922312b68a4227fada96buzbeeLIR* X86Mir2Lir::OpMem(OpKind op, int rBase, int disp) 321a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee{ 3226cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers X86OpCode opcode = kX86Bkpt; 3236cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers switch (op) { 3246cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers case kOpBlx: opcode = kX86CallM; break; 3256cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers default: 3266cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers LOG(FATAL) << "Bad opcode: " << op; 3276cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers break; 3286cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers } 3291fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR2(opcode, rBase, disp); 3306cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers} 3316cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers 3321fd3346740dfb7f47be9922312b68a4227fada96buzbeeLIR* X86Mir2Lir::LoadConstantWide(int r_dest_lo, int r_dest_hi, int64_t value) 333e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee{ 3344ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee int32_t val_lo = Low32Bits(value); 3354ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee int32_t val_hi = High32Bits(value); 336e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee LIR *res; 337fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (X86_FPREG(r_dest_lo)) { 338fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(X86_FPREG(r_dest_hi)); // ignore r_dest_hi 3394ef3e45d7c6ec3c482a1a48f4df470811aa3cf0abuzbee if (value == 0) { 3401fd3346740dfb7f47be9922312b68a4227fada96buzbee return NewLIR2(kX86XorpsRR, r_dest_lo, r_dest_lo); 341b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } else { 342fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (val_lo == 0) { 3431fd3346740dfb7f47be9922312b68a4227fada96buzbee res = NewLIR2(kX86XorpsRR, r_dest_lo, r_dest_lo); 344b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } else { 3451fd3346740dfb7f47be9922312b68a4227fada96buzbee res = LoadConstantNoClobber(r_dest_lo, val_lo); 346b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 347fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (val_hi != 0) { 3481fd3346740dfb7f47be9922312b68a4227fada96buzbee LoadConstantNoClobber(r_dest_hi, val_hi); 3491fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kX86PsllqRI, r_dest_hi, 32); 3501fd3346740dfb7f47be9922312b68a4227fada96buzbee NewLIR2(kX86OrpsRR, r_dest_lo, r_dest_hi); 351b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 352b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 353b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } else { 3541fd3346740dfb7f47be9922312b68a4227fada96buzbee res = LoadConstantNoClobber(r_dest_lo, val_lo); 3551fd3346740dfb7f47be9922312b68a4227fada96buzbee LoadConstantNoClobber(r_dest_hi, val_hi); 356b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 357e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee return res; 358e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 359e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 3601fd3346740dfb7f47be9922312b68a4227fada96buzbeeLIR* X86Mir2Lir::LoadBaseIndexedDisp(int rBase, int r_index, int scale, 36102031b185b4653e6c72e21f7a51238b903f6d638buzbee int displacement, int r_dest, int r_dest_hi, OpSize size, 36202031b185b4653e6c72e21f7a51238b903f6d638buzbee int s_reg) { 363b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers LIR *load = NULL; 364b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers LIR *load2 = NULL; 365fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bool is_array = r_index != INVALID_REG; 366b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers bool pair = false; 367b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers bool is64bit = false; 368b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers X86OpCode opcode = kX86Nop; 369b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers switch (size) { 370b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kLong: 371b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kDouble: 372b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers is64bit = true; 373fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (X86_FPREG(r_dest)) { 374fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86MovsdRA : kX86MovsdRM; 375fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (X86_SINGLEREG(r_dest)) { 376fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(X86_FPREG(r_dest_hi)); 377fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK_EQ(r_dest, (r_dest_hi - 1)); 378fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_dest = S2d(r_dest, r_dest_hi); 379e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 380fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_dest_hi = r_dest + 1; 381b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 382b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers pair = true; 383fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Mov32RA : kX86Mov32RM; 384b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 385b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers // TODO: double store is to unaligned address 386b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ((displacement & 0x3), 0); 387b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 388b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kWord: 389b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kSingle: 390fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Mov32RA : kX86Mov32RM; 391fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (X86_FPREG(r_dest)) { 392fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86MovssRA : kX86MovssRM; 393fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(X86_SINGLEREG(r_dest)); 394b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 395b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ((displacement & 0x3), 0); 396b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 397b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kUnsignedHalf: 398fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Movzx16RA : kX86Movzx16RM; 399b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ((displacement & 0x1), 0); 400b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 401b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kSignedHalf: 402fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Movsx16RA : kX86Movsx16RM; 403b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ((displacement & 0x1), 0); 404b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 405b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kUnsignedByte: 406fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Movzx8RA : kX86Movzx8RM; 407b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 408b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kSignedByte: 409fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Movsx8RA : kX86Movsx8RM; 410b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 411b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers default: 41252a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee LOG(FATAL) << "Bad case in LoadBaseIndexedDispBody"; 413b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 414b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 415fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (!is_array) { 416b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers if (!pair) { 4171fd3346740dfb7f47be9922312b68a4227fada96buzbee load = NewLIR3(opcode, r_dest, rBase, displacement + LOWORD_OFFSET); 418e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } else { 419fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (rBase == r_dest) { 4201fd3346740dfb7f47be9922312b68a4227fada96buzbee load2 = NewLIR3(opcode, r_dest_hi, rBase, 421fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao displacement + HIWORD_OFFSET); 4221fd3346740dfb7f47be9922312b68a4227fada96buzbee load = NewLIR3(opcode, r_dest, rBase, displacement + LOWORD_OFFSET); 423fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao } else { 4241fd3346740dfb7f47be9922312b68a4227fada96buzbee load = NewLIR3(opcode, r_dest, rBase, displacement + LOWORD_OFFSET); 4251fd3346740dfb7f47be9922312b68a4227fada96buzbee load2 = NewLIR3(opcode, r_dest_hi, rBase, 426fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao displacement + HIWORD_OFFSET); 427fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao } 428e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 429f0504cdc5b6400edd4b39eea64ac280465042d5bbuzbee if (rBase == rX86_SP) { 4301fd3346740dfb7f47be9922312b68a4227fada96buzbee AnnotateDalvikRegAccess(load, (displacement + (pair ? LOWORD_OFFSET : 0)) >> 2, 43102031b185b4653e6c72e21f7a51238b903f6d638buzbee true /* is_load */, is64bit); 432f7d9ad39541dd09030e26d54d3b73a076f90cc74Ian Rogers if (pair) { 4331fd3346740dfb7f47be9922312b68a4227fada96buzbee AnnotateDalvikRegAccess(load2, (displacement + HIWORD_OFFSET) >> 2, 434fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee true /* is_load */, is64bit); 435b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 436e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 437b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 438b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers if (!pair) { 4391fd3346740dfb7f47be9922312b68a4227fada96buzbee load = NewLIR5(opcode, r_dest, rBase, r_index, scale, 440a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee displacement + LOWORD_OFFSET); 441b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 442fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (rBase == r_dest) { 4431fd3346740dfb7f47be9922312b68a4227fada96buzbee load2 = NewLIR5(opcode, r_dest_hi, rBase, r_index, scale, 444fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao displacement + HIWORD_OFFSET); 4451fd3346740dfb7f47be9922312b68a4227fada96buzbee load = NewLIR5(opcode, r_dest, rBase, r_index, scale, 446fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao displacement + LOWORD_OFFSET); 447fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao } else { 4481fd3346740dfb7f47be9922312b68a4227fada96buzbee load = NewLIR5(opcode, r_dest, rBase, r_index, scale, 449fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao displacement + LOWORD_OFFSET); 4501fd3346740dfb7f47be9922312b68a4227fada96buzbee load2 = NewLIR5(opcode, r_dest_hi, rBase, r_index, scale, 451fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao displacement + HIWORD_OFFSET); 452fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao } 453b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 454b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 455b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 456b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers return load; 457e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 458e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 4595772babbe824494ef9fe90a1b07a926d124bb7c7jeffhao/* Load value from base + scaled index. */ 4601fd3346740dfb7f47be9922312b68a4227fada96buzbeeLIR* X86Mir2Lir::LoadBaseIndexed(int rBase, 461fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int r_index, int r_dest, int scale, OpSize size) { 4621fd3346740dfb7f47be9922312b68a4227fada96buzbee return LoadBaseIndexedDisp(rBase, r_index, scale, 0, 463fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_dest, INVALID_REG, size, INVALID_SREG); 4645772babbe824494ef9fe90a1b07a926d124bb7c7jeffhao} 4655772babbe824494ef9fe90a1b07a926d124bb7c7jeffhao 4661fd3346740dfb7f47be9922312b68a4227fada96buzbeeLIR* X86Mir2Lir::LoadBaseDisp(int rBase, int displacement, 467fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int r_dest, OpSize size, int s_reg) { 4681fd3346740dfb7f47be9922312b68a4227fada96buzbee return LoadBaseIndexedDisp(rBase, INVALID_REG, 0, displacement, 469fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_dest, INVALID_REG, size, s_reg); 470e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 471e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 4721fd3346740dfb7f47be9922312b68a4227fada96buzbeeLIR* X86Mir2Lir::LoadBaseDispWide(int rBase, int displacement, 473fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int r_dest_lo, int r_dest_hi, int s_reg) { 4741fd3346740dfb7f47be9922312b68a4227fada96buzbee return LoadBaseIndexedDisp(rBase, INVALID_REG, 0, displacement, 475fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_dest_lo, r_dest_hi, kLong, s_reg); 476e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 477e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 4781fd3346740dfb7f47be9922312b68a4227fada96buzbeeLIR* X86Mir2Lir::StoreBaseIndexedDisp(int rBase, int r_index, int scale, 47902031b185b4653e6c72e21f7a51238b903f6d638buzbee int displacement, int r_src, int r_src_hi, OpSize size, 48002031b185b4653e6c72e21f7a51238b903f6d638buzbee int s_reg) { 481b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers LIR *store = NULL; 482e296248a124ed8287b38a9225463696c18d84cd6jeffhao LIR *store2 = NULL; 483fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bool is_array = r_index != INVALID_REG; 484b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers bool pair = false; 485e296248a124ed8287b38a9225463696c18d84cd6jeffhao bool is64bit = false; 486b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers X86OpCode opcode = kX86Nop; 487b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers switch (size) { 488b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kLong: 489b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kDouble: 490e296248a124ed8287b38a9225463696c18d84cd6jeffhao is64bit = true; 491fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (X86_FPREG(r_src)) { 492fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86MovsdAR : kX86MovsdMR; 493fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (X86_SINGLEREG(r_src)) { 494fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(X86_FPREG(r_src_hi)); 495fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK_EQ(r_src, (r_src_hi - 1)); 496fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_src = S2d(r_src, r_src_hi); 497e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 498fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_src_hi = r_src + 1; 499b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 500b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers pair = true; 501fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Mov32AR : kX86Mov32MR; 502b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 503b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers // TODO: double store is to unaligned address 504b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ((displacement & 0x3), 0); 505b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 506b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kWord: 507b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kSingle: 508fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Mov32AR : kX86Mov32MR; 509fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (X86_FPREG(r_src)) { 510fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86MovssAR : kX86MovssMR; 511fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(X86_SINGLEREG(r_src)); 512b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 513b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ((displacement & 0x3), 0); 514b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 515b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kUnsignedHalf: 516b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kSignedHalf: 517fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Mov16AR : kX86Mov16MR; 518b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ((displacement & 0x1), 0); 519b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 520b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kUnsignedByte: 521b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kSignedByte: 522fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Mov8AR : kX86Mov8MR; 523b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 524b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers default: 52552a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee LOG(FATAL) << "Bad case in LoadBaseIndexedDispBody"; 526b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 527b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 528fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (!is_array) { 529b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers if (!pair) { 5301fd3346740dfb7f47be9922312b68a4227fada96buzbee store = NewLIR3(opcode, rBase, displacement + LOWORD_OFFSET, r_src); 531b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } else { 5321fd3346740dfb7f47be9922312b68a4227fada96buzbee store = NewLIR3(opcode, rBase, displacement + LOWORD_OFFSET, r_src); 5331fd3346740dfb7f47be9922312b68a4227fada96buzbee store2 = NewLIR3(opcode, rBase, displacement + HIWORD_OFFSET, r_src_hi); 534e296248a124ed8287b38a9225463696c18d84cd6jeffhao } 535f0504cdc5b6400edd4b39eea64ac280465042d5bbuzbee if (rBase == rX86_SP) { 5361fd3346740dfb7f47be9922312b68a4227fada96buzbee AnnotateDalvikRegAccess(store, (displacement + (pair ? LOWORD_OFFSET : 0)) >> 2, 53702031b185b4653e6c72e21f7a51238b903f6d638buzbee false /* is_load */, is64bit); 538e296248a124ed8287b38a9225463696c18d84cd6jeffhao if (pair) { 5391fd3346740dfb7f47be9922312b68a4227fada96buzbee AnnotateDalvikRegAccess(store2, (displacement + HIWORD_OFFSET) >> 2, 540fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee false /* is_load */, is64bit); 541e296248a124ed8287b38a9225463696c18d84cd6jeffhao } 542b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 543b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 544b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers if (!pair) { 5451fd3346740dfb7f47be9922312b68a4227fada96buzbee store = NewLIR5(opcode, rBase, r_index, scale, 546fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee displacement + LOWORD_OFFSET, r_src); 547b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } else { 5481fd3346740dfb7f47be9922312b68a4227fada96buzbee store = NewLIR5(opcode, rBase, r_index, scale, 549fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee displacement + LOWORD_OFFSET, r_src); 5501fd3346740dfb7f47be9922312b68a4227fada96buzbee store2 = NewLIR5(opcode, rBase, r_index, scale, 551fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee displacement + HIWORD_OFFSET, r_src_hi); 552e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 553b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 554b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers 555b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers return store; 556e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 557e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 558c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers/* store value base base + scaled index. */ 5591fd3346740dfb7f47be9922312b68a4227fada96buzbeeLIR* X86Mir2Lir::StoreBaseIndexed(int rBase, int r_index, int r_src, 560a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int scale, OpSize size) 561c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers{ 5621fd3346740dfb7f47be9922312b68a4227fada96buzbee return StoreBaseIndexedDisp(rBase, r_index, scale, 0, 563fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_src, INVALID_REG, size, INVALID_SREG); 564c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers} 565c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers 5661fd3346740dfb7f47be9922312b68a4227fada96buzbeeLIR* X86Mir2Lir::StoreBaseDisp(int rBase, int displacement, 56702031b185b4653e6c72e21f7a51238b903f6d638buzbee int r_src, OpSize size) 568a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee{ 5691fd3346740dfb7f47be9922312b68a4227fada96buzbee return StoreBaseIndexedDisp(rBase, INVALID_REG, 0, 570fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee displacement, r_src, INVALID_REG, size, 571a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee INVALID_SREG); 572e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 573e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 5741fd3346740dfb7f47be9922312b68a4227fada96buzbeeLIR* X86Mir2Lir::StoreBaseDispWide(int rBase, int displacement, 57502031b185b4653e6c72e21f7a51238b903f6d638buzbee int r_src_lo, int r_src_hi) 576a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee{ 5771fd3346740dfb7f47be9922312b68a4227fada96buzbee return StoreBaseIndexedDisp(rBase, INVALID_REG, 0, displacement, 578fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_src_lo, r_src_hi, kLong, INVALID_SREG); 579e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 580e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 581e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} // namespace art 582