utility_x86.cc revision 02031b185b4653e6c72e21f7a51238b903f6d638
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 171bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee#include "x86_lir.h" 1802031b185b4653e6c72e21f7a51238b903f6d638buzbee#include "codegen_x86.h" 191bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee#include "../codegen_util.h" 201bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee#include "../ralloc_util.h" 211bc37c60da71c923ea9a2e99d31ba1b3d76d79a8buzbee 22e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbeenamespace art { 23e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 24b046e16d8b8da318d6055f9308950131f1255e08buzbee/* This file contains codegen for the X86 ISA */ 25e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 2602031b185b4653e6c72e21f7a51238b903f6d638buzbeeLIR* X86Codegen::OpFpRegCopy(CompilationUnit *cu, int r_dest, int r_src) 27e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee{ 28a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int opcode; 29a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee /* must be both DOUBLE or both not DOUBLE */ 30fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK_EQ(X86_DOUBLEREG(r_dest), X86_DOUBLEREG(r_src)); 31fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (X86_DOUBLEREG(r_dest)) { 32a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kX86MovsdRR; 33a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { 34fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (X86_SINGLEREG(r_dest)) { 35fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (X86_SINGLEREG(r_src)) { 36a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kX86MovssRR; 37a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { // Fpr <- Gpr 38a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kX86MovdxrRR; 39a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 40a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } else { // Gpr <- Fpr 41fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(X86_SINGLEREG(r_src)); 42a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee opcode = kX86MovdrxRR; 43e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 44a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 45ec13743da80a80c1817cf6660c28917fc28846bcbuzbee DCHECK_NE((EncodingMap[opcode].flags & IS_BINARY_OP), 0ULL); 46fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LIR* res = RawLIR(cu, cu->current_dalvik_offset, opcode, r_dest, r_src); 47fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (r_dest == r_src) { 48fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee res->flags.is_nop = true; 49a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee } 50a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee return res; 51e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 52e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 53e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee/* 54e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * Load a immediate using a shortcut if possible; otherwise 55e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * grab from the per-translation literal pool. If target is 56e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * a high register, build constant into a low register and copy. 57e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * 58e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * No additional register clobbering operation performed. Use this version when 59fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee * 1) r_dest is freshly returned from AllocTemp or 60e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * 2) The codegen is under fixed register usage 61e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee */ 6202031b185b4653e6c72e21f7a51238b903f6d638buzbeeLIR* X86Codegen::LoadConstantNoClobber(CompilationUnit *cu, int r_dest, int value) 63a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee{ 64fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int r_dest_save = r_dest; 65fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (X86_FPREG(r_dest)) { 66b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers if (value == 0) { 67fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return NewLIR2(cu, kX86XorpsRR, r_dest, r_dest); 68b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 69fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(X86_SINGLEREG(r_dest)); 70fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_dest = AllocTemp(cu); 716cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers } 72e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 73b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers LIR *res; 746cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers if (value == 0) { 75fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee res = NewLIR2(cu, kX86Xor32RR, r_dest, r_dest); 766cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers } else { 772e9f7ed8d00271cb1cf082d68b4f4bc60702d6ecIan Rogers // Note, there is no byte immediate form of a 32 bit immediate move. 78fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee res = NewLIR2(cu, kX86Mov32RI, r_dest, value); 796cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers } 80e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 81fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (X86_FPREG(r_dest_save)) { 82fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee NewLIR2(cu, kX86MovdxrRR, r_dest_save, r_dest); 83fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee FreeTemp(cu, r_dest); 846cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers } 85e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 866cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers return res; 87e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 88e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 8902031b185b4653e6c72e21f7a51238b903f6d638buzbeeLIR* X86Codegen::OpUnconditionalBranch(CompilationUnit* cu, LIR* target) 90a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee{ 9102031b185b4653e6c72e21f7a51238b903f6d638buzbee LIR* res = NewLIR1(cu, kX86Jmp8, 0 /* offset to be patched during assembly*/ ); 9202031b185b4653e6c72e21f7a51238b903f6d638buzbee res->target = target; 9302031b185b4653e6c72e21f7a51238b903f6d638buzbee return res; 94e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 95e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 9602031b185b4653e6c72e21f7a51238b903f6d638buzbeeLIR* X86Codegen::OpCondBranch(CompilationUnit* cu, ConditionCode cc, LIR* target) 97a7678db092ac6bb79f7cad490099a1015fbbc714buzbee{ 98fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LIR* branch = NewLIR2(cu, kX86Jcc8, 0 /* offset to be patched */, 9952a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee X86ConditionEncoding(cc)); 100b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers branch->target = target; 101b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers return branch; 102a7678db092ac6bb79f7cad490099a1015fbbc714buzbee} 103a7678db092ac6bb79f7cad490099a1015fbbc714buzbee 10402031b185b4653e6c72e21f7a51238b903f6d638buzbeeLIR* X86Codegen::OpReg(CompilationUnit *cu, OpKind op, int r_dest_src) 105a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee{ 106b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers X86OpCode opcode = kX86Bkpt; 107b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers switch (op) { 108b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpNeg: opcode = kX86Neg32R; break; 1091395b1e06c1d0ff5155b0c5d113ad3bd6f163c07jeffhao case kOpNot: opcode = kX86Not32R; break; 110b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpBlx: opcode = kX86CallR; break; 111b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers default: 11252a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee LOG(FATAL) << "Bad case in OpReg " << op; 113b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 114fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return NewLIR1(cu, opcode, r_dest_src); 115e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 116e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 11702031b185b4653e6c72e21f7a51238b903f6d638buzbeeLIR* X86Codegen::OpRegImm(CompilationUnit *cu, OpKind op, int r_dest_src1, int value) 118a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee{ 119b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers X86OpCode opcode = kX86Bkpt; 120fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bool byte_imm = IS_SIMM8(value); 121fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(!X86_FPREG(r_dest_src1)); 122b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers switch (op) { 123b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpLsl: opcode = kX86Sal32RI; break; 124b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpLsr: opcode = kX86Shr32RI; break; 125b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpAsr: opcode = kX86Sar32RI; break; 126fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee case kOpAdd: opcode = byte_imm ? kX86Add32RI8 : kX86Add32RI; break; 127fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee case kOpOr: opcode = byte_imm ? kX86Or32RI8 : kX86Or32RI; break; 128fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee case kOpAdc: opcode = byte_imm ? kX86Adc32RI8 : kX86Adc32RI; break; 129b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers //case kOpSbb: opcode = kX86Sbb32RI; break; 130fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee case kOpAnd: opcode = byte_imm ? kX86And32RI8 : kX86And32RI; break; 131fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee case kOpSub: opcode = byte_imm ? kX86Sub32RI8 : kX86Sub32RI; break; 132fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee case kOpXor: opcode = byte_imm ? kX86Xor32RI8 : kX86Xor32RI; break; 133fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee case kOpCmp: opcode = byte_imm ? kX86Cmp32RI8 : kX86Cmp32RI; break; 134fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee case kOpMov: return LoadConstantNoClobber(cu, r_dest_src1, value); 135b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpMul: 136fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = byte_imm ? kX86Imul32RRI8 : kX86Imul32RRI; 137fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return NewLIR3(cu, opcode, r_dest_src1, r_dest_src1, value); 138b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers default: 13952a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee LOG(FATAL) << "Bad case in OpRegImm " << op; 140b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 141fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return NewLIR2(cu, opcode, r_dest_src1, value); 142e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 143e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 14402031b185b4653e6c72e21f7a51238b903f6d638buzbeeLIR* X86Codegen::OpRegReg(CompilationUnit *cu, OpKind op, int r_dest_src1, int r_src2) 145e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee{ 146a7678db092ac6bb79f7cad490099a1015fbbc714buzbee X86OpCode opcode = kX86Nop; 147d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers bool src2_must_be_cx = false; 148e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee switch (op) { 149b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers // X86 unary opcodes 150b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpMvn: 151fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee OpRegCopy(cu, r_dest_src1, r_src2); 152fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return OpReg(cu, kOpNot, r_dest_src1); 153b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpNeg: 154fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee OpRegCopy(cu, r_dest_src1, r_src2); 155fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return OpReg(cu, kOpNeg, r_dest_src1); 156b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers // X86 binary opcodes 157b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpSub: opcode = kX86Sub32RR; break; 158b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpSbc: opcode = kX86Sbb32RR; break; 159d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers case kOpLsl: opcode = kX86Sal32RC; src2_must_be_cx = true; break; 160d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers case kOpLsr: opcode = kX86Shr32RC; src2_must_be_cx = true; break; 161d36c52ea6bc22883ef381f6da1ac05ef7524f63aIan Rogers case kOpAsr: opcode = kX86Sar32RC; src2_must_be_cx = true; break; 162b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpMov: opcode = kX86Mov32RR; break; 163b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpCmp: opcode = kX86Cmp32RR; break; 164b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpAdd: opcode = kX86Add32RR; break; 165b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpAdc: opcode = kX86Adc32RR; break; 166b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpAnd: opcode = kX86And32RR; break; 167b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpOr: opcode = kX86Or32RR; break; 168b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpXor: opcode = kX86Xor32RR; break; 169703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao case kOp2Byte: 170703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao // Use shifts instead of a byte operand if the source can't be byte accessed. 171fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (r_src2 >= 4) { 172fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee NewLIR2(cu, kX86Mov32RR, r_dest_src1, r_src2); 173fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee NewLIR2(cu, kX86Sal32RI, r_dest_src1, 24); 174fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return NewLIR2(cu, kX86Sar32RI, r_dest_src1, 24); 175703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao } else { 176703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao opcode = kX86Movsx8RR; 177703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao } 178703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao break; 179b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOp2Short: opcode = kX86Movsx16RR; break; 180b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOp2Char: opcode = kX86Movzx16RR; break; 181b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpMul: opcode = kX86Imul32RR; break; 182b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers default: 18352a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee LOG(FATAL) << "Bad case in OpRegReg " << op; 184b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 185e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 186fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee CHECK(!src2_must_be_cx || r_src2 == rCX); 187fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return NewLIR2(cu, opcode, r_dest_src1, r_src2); 188e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 189e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 19002031b185b4653e6c72e21f7a51238b903f6d638buzbeeLIR* X86Codegen::OpRegMem(CompilationUnit *cu, OpKind op, int r_dest, int rBase, 191a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int offset) 192a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee{ 193b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers X86OpCode opcode = kX86Nop; 194b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers switch (op) { 195b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers // X86 binary opcodes 196b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpSub: opcode = kX86Sub32RM; break; 197b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpMov: opcode = kX86Mov32RM; break; 198b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpCmp: opcode = kX86Cmp32RM; break; 199b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpAdd: opcode = kX86Add32RM; break; 200b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpAnd: opcode = kX86And32RM; break; 201b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpOr: opcode = kX86Or32RM; break; 202b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpXor: opcode = kX86Xor32RM; break; 203b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOp2Byte: opcode = kX86Movsx8RM; break; 204b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOp2Short: opcode = kX86Movsx16RM; break; 205b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOp2Char: opcode = kX86Movzx16RM; break; 206b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpMul: 207b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers default: 20852a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee LOG(FATAL) << "Bad case in OpRegMem " << op; 209b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 210b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 211fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return NewLIR3(cu, opcode, r_dest, rBase, offset); 212b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers} 213e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 21402031b185b4653e6c72e21f7a51238b903f6d638buzbeeLIR* X86Codegen::OpRegRegReg(CompilationUnit *cu, OpKind op, int r_dest, int r_src1, 215fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int r_src2) 216a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee{ 217fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (r_dest != r_src1 && r_dest != r_src2) { 218b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers if (op == kOpAdd) { // lea special case, except can't encode rbp as base 219fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (r_src1 == r_src2) { 220fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee OpRegCopy(cu, r_dest, r_src1); 221fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return OpRegImm(cu, kOpLsl, r_dest, 1); 222fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee } else if (r_src1 != rBP) { 223fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return NewLIR5(cu, kX86Lea32RA, r_dest, r_src1 /* base */, 224fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_src2 /* index */, 0 /* scale */, 0 /* disp */); 225b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 226fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return NewLIR5(cu, kX86Lea32RA, r_dest, r_src2 /* base */, 227fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_src1 /* index */, 0 /* scale */, 0 /* disp */); 228b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 229b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 230fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee OpRegCopy(cu, r_dest, r_src1); 231fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return OpRegReg(cu, op, r_dest, r_src2); 232e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 233fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee } else if (r_dest == r_src1) { 234fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return OpRegReg(cu, op, r_dest, r_src2); 235fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee } else { // r_dest == r_src2 236b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers switch (op) { 237b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpSub: // non-commutative 238fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee OpReg(cu, kOpNeg, r_dest); 239b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers op = kOpAdd; 240b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 241b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpSbc: 242b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpLsl: case kOpLsr: case kOpAsr: case kOpRor: { 243fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int t_reg = AllocTemp(cu); 244fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee OpRegCopy(cu, t_reg, r_src1); 245fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee OpRegReg(cu, op, t_reg, r_src2); 246fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LIR* res = OpRegCopy(cu, r_dest, t_reg); 247fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee FreeTemp(cu, t_reg); 248b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers return res; 249b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 250b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpAdd: // commutative 251b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpOr: 252b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpAdc: 253b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpAnd: 254b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kOpXor: 255b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 256b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers default: 25752a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee LOG(FATAL) << "Bad case in OpRegRegReg " << op; 258e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 259fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return OpRegReg(cu, op, r_dest, r_src1); 260b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 261e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 262e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 26302031b185b4653e6c72e21f7a51238b903f6d638buzbeeLIR* X86Codegen::OpRegRegImm(CompilationUnit *cu, OpKind op, int r_dest, int r_src, 264a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int value) 265a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee{ 266b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers if (op == kOpMul) { 267b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers X86OpCode opcode = IS_SIMM8(value) ? kX86Imul32RRI8 : kX86Imul32RRI; 268fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return NewLIR3(cu, opcode, r_dest, r_src, value); 269b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } else if (op == kOpAnd) { 270fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (value == 0xFF && r_src < 4) { 271fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return NewLIR2(cu, kX86Movzx8RR, r_dest, r_src); 272b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } else if (value == 0xFFFF) { 273fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return NewLIR2(cu, kX86Movzx16RR, r_dest, r_src); 274b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 275b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 276fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (r_dest != r_src) { 2777caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers if (false && op == kOpLsl && value >= 0 && value <= 3) { // lea shift special case 2787caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers // TODO: fix bug in LEA encoding when disp == 0 279fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return NewLIR5(cu, kX86Lea32RA, r_dest, r5sib_no_base /* base */, 280fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_src /* index */, value /* scale */, 0 /* disp */); 281b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } else if (op == kOpAdd) { // lea add special case 282fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return NewLIR5(cu, kX86Lea32RA, r_dest, r_src /* base */, 283b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers r4sib_no_index /* index */, 0 /* scale */, value /* disp */); 284e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 285fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee OpRegCopy(cu, r_dest, r_src); 286b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 287fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return OpRegImm(cu, op, r_dest, value); 288e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 289e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 29002031b185b4653e6c72e21f7a51238b903f6d638buzbeeLIR* X86Codegen::OpThreadMem(CompilationUnit* cu, OpKind op, int thread_offset) 291a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee{ 2926cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers X86OpCode opcode = kX86Bkpt; 2936cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers switch (op) { 2946cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers case kOpBlx: opcode = kX86CallT; break; 2956cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers default: 2966cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers LOG(FATAL) << "Bad opcode: " << op; 2976cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers break; 2986cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers } 299fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return NewLIR1(cu, opcode, thread_offset); 3006cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers} 3016cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers 30202031b185b4653e6c72e21f7a51238b903f6d638buzbeeLIR* X86Codegen::OpMem(CompilationUnit* cu, OpKind op, int rBase, int disp) 303a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee{ 3046cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers X86OpCode opcode = kX86Bkpt; 3056cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers switch (op) { 3066cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers case kOpBlx: opcode = kX86CallM; break; 3076cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers default: 3086cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers LOG(FATAL) << "Bad opcode: " << op; 3096cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers break; 3106cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers } 311fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return NewLIR2(cu, opcode, rBase, disp); 3126cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers} 3136cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers 31402031b185b4653e6c72e21f7a51238b903f6d638buzbeeLIR* X86Codegen::LoadConstantValueWide(CompilationUnit *cu, int r_dest_lo, 31502031b185b4653e6c72e21f7a51238b903f6d638buzbee int r_dest_hi, int val_lo, int val_hi) 316e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee{ 317e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee LIR *res; 318fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (X86_FPREG(r_dest_lo)) { 319fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(X86_FPREG(r_dest_hi)); // ignore r_dest_hi 320fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (val_lo == 0 && val_hi == 0) { 321fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return NewLIR2(cu, kX86XorpsRR, r_dest_lo, r_dest_lo); 322b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } else { 323fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (val_lo == 0) { 324fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee res = NewLIR2(cu, kX86XorpsRR, r_dest_lo, r_dest_lo); 325b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } else { 326fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee res = LoadConstantNoClobber(cu, r_dest_lo, val_lo); 327b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 328fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (val_hi != 0) { 329fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LoadConstantNoClobber(cu, r_dest_hi, val_hi); 330fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee NewLIR2(cu, kX86PsllqRI, r_dest_hi, 32); 331fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee NewLIR2(cu, kX86OrpsRR, r_dest_lo, r_dest_hi); 332b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 333b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 334b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } else { 335fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee res = LoadConstantNoClobber(cu, r_dest_lo, val_lo); 336fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LoadConstantNoClobber(cu, r_dest_hi, val_hi); 337b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 338e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee return res; 339e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 340e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 34102031b185b4653e6c72e21f7a51238b903f6d638buzbeeLIR* X86Codegen::LoadBaseIndexedDisp(CompilationUnit *cu, int rBase, int r_index, int scale, 34202031b185b4653e6c72e21f7a51238b903f6d638buzbee int displacement, int r_dest, int r_dest_hi, OpSize size, 34302031b185b4653e6c72e21f7a51238b903f6d638buzbee int s_reg) { 344b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers LIR *load = NULL; 345b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers LIR *load2 = NULL; 346fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bool is_array = r_index != INVALID_REG; 347b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers bool pair = false; 348b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers bool is64bit = false; 349b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers X86OpCode opcode = kX86Nop; 350b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers switch (size) { 351b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kLong: 352b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kDouble: 353b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers is64bit = true; 354fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (X86_FPREG(r_dest)) { 355fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86MovsdRA : kX86MovsdRM; 356fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (X86_SINGLEREG(r_dest)) { 357fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(X86_FPREG(r_dest_hi)); 358fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK_EQ(r_dest, (r_dest_hi - 1)); 359fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_dest = S2d(r_dest, r_dest_hi); 360e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 361fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_dest_hi = r_dest + 1; 362b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 363b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers pair = true; 364fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Mov32RA : kX86Mov32RM; 365b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 366b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers // TODO: double store is to unaligned address 367b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ((displacement & 0x3), 0); 368b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 369b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kWord: 370b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kSingle: 371fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Mov32RA : kX86Mov32RM; 372fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (X86_FPREG(r_dest)) { 373fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86MovssRA : kX86MovssRM; 374fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(X86_SINGLEREG(r_dest)); 375b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 376b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ((displacement & 0x3), 0); 377b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 378b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kUnsignedHalf: 379fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Movzx16RA : kX86Movzx16RM; 380b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ((displacement & 0x1), 0); 381b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 382b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kSignedHalf: 383fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Movsx16RA : kX86Movsx16RM; 384b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ((displacement & 0x1), 0); 385b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 386b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kUnsignedByte: 387fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Movzx8RA : kX86Movzx8RM; 388b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 389b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kSignedByte: 390fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Movsx8RA : kX86Movsx8RM; 391b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 392b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers default: 39352a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee LOG(FATAL) << "Bad case in LoadBaseIndexedDispBody"; 394b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 395b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 396fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (!is_array) { 397b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers if (!pair) { 398fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee load = NewLIR3(cu, opcode, r_dest, rBase, displacement + LOWORD_OFFSET); 399e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } else { 400fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (rBase == r_dest) { 401fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee load2 = NewLIR3(cu, opcode, r_dest_hi, rBase, 402fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao displacement + HIWORD_OFFSET); 403fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee load = NewLIR3(cu, opcode, r_dest, rBase, displacement + LOWORD_OFFSET); 404fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao } else { 405fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee load = NewLIR3(cu, opcode, r_dest, rBase, displacement + LOWORD_OFFSET); 406fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee load2 = NewLIR3(cu, opcode, r_dest_hi, rBase, 407fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao displacement + HIWORD_OFFSET); 408fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao } 409e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 410f0504cdc5b6400edd4b39eea64ac280465042d5bbuzbee if (rBase == rX86_SP) { 41102031b185b4653e6c72e21f7a51238b903f6d638buzbee AnnotateDalvikRegAccess(cu, load, (displacement + (pair ? LOWORD_OFFSET : 0)) >> 2, 41202031b185b4653e6c72e21f7a51238b903f6d638buzbee true /* is_load */, is64bit); 413f7d9ad39541dd09030e26d54d3b73a076f90cc74Ian Rogers if (pair) { 41402031b185b4653e6c72e21f7a51238b903f6d638buzbee AnnotateDalvikRegAccess(cu, load2, (displacement + HIWORD_OFFSET) >> 2, 415fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee true /* is_load */, is64bit); 416b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 417e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 418b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 419b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers if (!pair) { 420fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee load = NewLIR5(cu, opcode, r_dest, rBase, r_index, scale, 421a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee displacement + LOWORD_OFFSET); 422b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 423fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (rBase == r_dest) { 424fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee load2 = NewLIR5(cu, opcode, r_dest_hi, rBase, r_index, scale, 425fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao displacement + HIWORD_OFFSET); 426fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee load = NewLIR5(cu, opcode, r_dest, rBase, r_index, scale, 427fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao displacement + LOWORD_OFFSET); 428fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao } else { 429fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee load = NewLIR5(cu, opcode, r_dest, rBase, r_index, scale, 430fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao displacement + LOWORD_OFFSET); 431fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee load2 = NewLIR5(cu, opcode, r_dest_hi, rBase, r_index, scale, 432fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao displacement + HIWORD_OFFSET); 433fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao } 434b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 435b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 436b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 437b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers return load; 438e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 439e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 4405772babbe824494ef9fe90a1b07a926d124bb7c7jeffhao/* Load value from base + scaled index. */ 44102031b185b4653e6c72e21f7a51238b903f6d638buzbeeLIR* X86Codegen::LoadBaseIndexed(CompilationUnit *cu, int rBase, 442fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int r_index, int r_dest, int scale, OpSize size) { 443fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return LoadBaseIndexedDisp(cu, rBase, r_index, scale, 0, 444fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_dest, INVALID_REG, size, INVALID_SREG); 4455772babbe824494ef9fe90a1b07a926d124bb7c7jeffhao} 4465772babbe824494ef9fe90a1b07a926d124bb7c7jeffhao 44702031b185b4653e6c72e21f7a51238b903f6d638buzbeeLIR* X86Codegen::LoadBaseDisp(CompilationUnit *cu, int rBase, int displacement, 448fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int r_dest, OpSize size, int s_reg) { 449fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return LoadBaseIndexedDisp(cu, rBase, INVALID_REG, 0, displacement, 450fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_dest, INVALID_REG, size, s_reg); 451e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 452e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 45302031b185b4653e6c72e21f7a51238b903f6d638buzbeeLIR* X86Codegen::LoadBaseDispWide(CompilationUnit *cu, int rBase, int displacement, 454fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee int r_dest_lo, int r_dest_hi, int s_reg) { 455fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return LoadBaseIndexedDisp(cu, rBase, INVALID_REG, 0, displacement, 456fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_dest_lo, r_dest_hi, kLong, s_reg); 457e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 458e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 45902031b185b4653e6c72e21f7a51238b903f6d638buzbeeLIR* X86Codegen::StoreBaseIndexedDisp(CompilationUnit *cu, int rBase, int r_index, int scale, 46002031b185b4653e6c72e21f7a51238b903f6d638buzbee int displacement, int r_src, int r_src_hi, OpSize size, 46102031b185b4653e6c72e21f7a51238b903f6d638buzbee int s_reg) { 462b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers LIR *store = NULL; 463e296248a124ed8287b38a9225463696c18d84cd6jeffhao LIR *store2 = NULL; 464fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee bool is_array = r_index != INVALID_REG; 465b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers bool pair = false; 466e296248a124ed8287b38a9225463696c18d84cd6jeffhao bool is64bit = false; 467b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers X86OpCode opcode = kX86Nop; 468b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers switch (size) { 469b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kLong: 470b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kDouble: 471e296248a124ed8287b38a9225463696c18d84cd6jeffhao is64bit = true; 472fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (X86_FPREG(r_src)) { 473fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86MovsdAR : kX86MovsdMR; 474fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (X86_SINGLEREG(r_src)) { 475fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(X86_FPREG(r_src_hi)); 476fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK_EQ(r_src, (r_src_hi - 1)); 477fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_src = S2d(r_src, r_src_hi); 478e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 479fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_src_hi = r_src + 1; 480b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 481b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers pair = true; 482fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Mov32AR : kX86Mov32MR; 483b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 484b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers // TODO: double store is to unaligned address 485b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ((displacement & 0x3), 0); 486b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 487b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kWord: 488b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kSingle: 489fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Mov32AR : kX86Mov32MR; 490fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (X86_FPREG(r_src)) { 491fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86MovssAR : kX86MovssMR; 492fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(X86_SINGLEREG(r_src)); 493b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 494b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ((displacement & 0x3), 0); 495b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 496b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kUnsignedHalf: 497b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kSignedHalf: 498fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Mov16AR : kX86Mov16MR; 499b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ((displacement & 0x1), 0); 500b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 501b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kUnsignedByte: 502b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kSignedByte: 503fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee opcode = is_array ? kX86Mov8AR : kX86Mov8MR; 504b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 505b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers default: 50652a77fc135f0e0df57ee24641c3f5ae415ff7bd6buzbee LOG(FATAL) << "Bad case in LoadBaseIndexedDispBody"; 507b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 508b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 509fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (!is_array) { 510b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers if (!pair) { 511fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee store = NewLIR3(cu, opcode, rBase, displacement + LOWORD_OFFSET, r_src); 512b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } else { 513fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee store = NewLIR3(cu, opcode, rBase, displacement + LOWORD_OFFSET, r_src); 514fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee store2 = NewLIR3(cu, opcode, rBase, displacement + HIWORD_OFFSET, r_src_hi); 515e296248a124ed8287b38a9225463696c18d84cd6jeffhao } 516f0504cdc5b6400edd4b39eea64ac280465042d5bbuzbee if (rBase == rX86_SP) { 51702031b185b4653e6c72e21f7a51238b903f6d638buzbee AnnotateDalvikRegAccess(cu, store, (displacement + (pair ? LOWORD_OFFSET : 0)) >> 2, 51802031b185b4653e6c72e21f7a51238b903f6d638buzbee false /* is_load */, is64bit); 519e296248a124ed8287b38a9225463696c18d84cd6jeffhao if (pair) { 52002031b185b4653e6c72e21f7a51238b903f6d638buzbee AnnotateDalvikRegAccess(cu, store2, (displacement + HIWORD_OFFSET) >> 2, 521fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee false /* is_load */, is64bit); 522e296248a124ed8287b38a9225463696c18d84cd6jeffhao } 523b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 524b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 525b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers if (!pair) { 526fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee store = NewLIR5(cu, opcode, rBase, r_index, scale, 527fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee displacement + LOWORD_OFFSET, r_src); 528b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } else { 529fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee store = NewLIR5(cu, opcode, rBase, r_index, scale, 530fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee displacement + LOWORD_OFFSET, r_src); 531fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee store2 = NewLIR5(cu, opcode, rBase, r_index, scale, 532fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee displacement + HIWORD_OFFSET, r_src_hi); 533e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 534b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 535b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers 536b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers return store; 537e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 538e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 539c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers/* store value base base + scaled index. */ 54002031b185b4653e6c72e21f7a51238b903f6d638buzbeeLIR* X86Codegen::StoreBaseIndexed(CompilationUnit *cu, int rBase, int r_index, int r_src, 541a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee int scale, OpSize size) 542c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers{ 543fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return StoreBaseIndexedDisp(cu, rBase, r_index, scale, 0, 544fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_src, INVALID_REG, size, INVALID_SREG); 545c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers} 546c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers 54702031b185b4653e6c72e21f7a51238b903f6d638buzbeeLIR* X86Codegen::StoreBaseDisp(CompilationUnit *cu, int rBase, int displacement, 54802031b185b4653e6c72e21f7a51238b903f6d638buzbee int r_src, OpSize size) 549a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee{ 550fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return StoreBaseIndexedDisp(cu, rBase, INVALID_REG, 0, 551fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee displacement, r_src, INVALID_REG, size, 552a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee INVALID_SREG); 553e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 554e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 55502031b185b4653e6c72e21f7a51238b903f6d638buzbeeLIR* X86Codegen::StoreBaseDispWide(CompilationUnit *cu, int rBase, int displacement, 55602031b185b4653e6c72e21f7a51238b903f6d638buzbee int r_src_lo, int r_src_hi) 557a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee{ 558fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee return StoreBaseIndexedDisp(cu, rBase, INVALID_REG, 0, displacement, 559fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee r_src_lo, r_src_hi, kLong, INVALID_SREG); 560e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 561e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 56202031b185b4653e6c72e21f7a51238b903f6d638buzbeevoid X86Codegen::LoadPair(CompilationUnit *cu, int base, int low_reg, int high_reg) 563e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee{ 564fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LoadBaseDispWide(cu, base, 0, low_reg, high_reg, INVALID_SREG); 565e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 566e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 567e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} // namespace art 568