blob: b0641359b78addff2f82be17a48b63c90e0fbbf5 [file] [log] [blame]
buzbee67bf8852011-08-17 17:51:35 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
buzbee1bc37c62012-11-20 13:35:41 -080017#include "arm_lir.h"
18#include "../codegen_util.h"
19#include "../ralloc_util.h"
20
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080021namespace art {
22
buzbeeb046e162012-10-30 15:48:42 -070023/* This file contains codegen for the Thumb ISA. */
buzbee67bf8852011-08-17 17:51:35 -070024
buzbeeaad94382012-11-21 07:40:50 -080025static int EncodeImmSingle(int value)
buzbee67bf8852011-08-17 17:51:35 -070026{
Bill Buzbeea114add2012-05-03 15:00:40 -070027 int res;
buzbeefa57c472012-11-21 12:06:18 -080028 int bit_a = (value & 0x80000000) >> 31;
29 int not_bit_b = (value & 0x40000000) >> 30;
30 int bit_b = (value & 0x20000000) >> 29;
31 int b_smear = (value & 0x3e000000) >> 25;
Bill Buzbeea114add2012-05-03 15:00:40 -070032 int slice = (value & 0x01f80000) >> 19;
33 int zeroes = (value & 0x0007ffff);
34 if (zeroes != 0)
35 return -1;
buzbeefa57c472012-11-21 12:06:18 -080036 if (bit_b) {
37 if ((not_bit_b != 0) || (b_smear != 0x1f))
Bill Buzbeea114add2012-05-03 15:00:40 -070038 return -1;
39 } else {
buzbeefa57c472012-11-21 12:06:18 -080040 if ((not_bit_b != 1) || (b_smear != 0x0))
Bill Buzbeea114add2012-05-03 15:00:40 -070041 return -1;
42 }
buzbeefa57c472012-11-21 12:06:18 -080043 res = (bit_a << 7) | (bit_b << 6) | slice;
Bill Buzbeea114add2012-05-03 15:00:40 -070044 return res;
buzbee67bf8852011-08-17 17:51:35 -070045}
46
buzbeefa57c472012-11-21 12:06:18 -080047static LIR* LoadFPConstantValue(CompilationUnit* cu, int r_dest, int value)
buzbee67bf8852011-08-17 17:51:35 -070048{
buzbeefa57c472012-11-21 12:06:18 -080049 int encoded_imm = EncodeImmSingle(value);
50 DCHECK(ARM_SINGLEREG(r_dest));
51 if (encoded_imm >= 0) {
52 return NewLIR2(cu, kThumb2Vmovs_IMM8, r_dest, encoded_imm);
Bill Buzbeea114add2012-05-03 15:00:40 -070053 }
buzbeefa57c472012-11-21 12:06:18 -080054 LIR* data_target = ScanLiteralPool(cu->literal_list, value, 0);
55 if (data_target == NULL) {
56 data_target = AddWordData(cu, &cu->literal_list, value);
Bill Buzbeea114add2012-05-03 15:00:40 -070057 }
buzbeefa57c472012-11-21 12:06:18 -080058 LIR* load_pc_rel = RawLIR(cu, cu->current_dalvik_offset, kThumb2Vldrs,
59 r_dest, r15pc, 0, 0, 0, data_target);
60 SetMemRefType(load_pc_rel, true, kLiteral);
61 load_pc_rel->alias_info = reinterpret_cast<uintptr_t>(data_target);
62 AppendLIR(cu, load_pc_rel);
63 return load_pc_rel;
buzbee67bf8852011-08-17 17:51:35 -070064}
65
buzbeeaad94382012-11-21 07:40:50 -080066static int LeadingZeros(uint32_t val)
buzbee67bf8852011-08-17 17:51:35 -070067{
buzbeeeaf09bc2012-11-15 14:51:41 -080068 uint32_t alt;
Bill Buzbeea114add2012-05-03 15:00:40 -070069 int n;
70 int count;
buzbee67bf8852011-08-17 17:51:35 -070071
Bill Buzbeea114add2012-05-03 15:00:40 -070072 count = 16;
73 n = 32;
74 do {
75 alt = val >> count;
76 if (alt != 0) {
77 n = n - count;
78 val = alt;
79 }
80 count >>= 1;
81 } while (count);
82 return n - val;
buzbee67bf8852011-08-17 17:51:35 -070083}
84
85/*
86 * Determine whether value can be encoded as a Thumb2 modified
87 * immediate. If not, return -1. If so, return i:imm3:a:bcdefgh form.
88 */
buzbee52a77fc2012-11-20 19:50:46 -080089int ModifiedImmediate(uint32_t value)
buzbee67bf8852011-08-17 17:51:35 -070090{
buzbeefa57c472012-11-21 12:06:18 -080091 int z_leading;
92 int z_trailing;
buzbeeeaf09bc2012-11-15 14:51:41 -080093 uint32_t b0 = value & 0xff;
buzbee67bf8852011-08-17 17:51:35 -070094
95 /* Note: case of value==0 must use 0:000:0:0000000 encoding */
96 if (value <= 0xFF)
Bill Buzbeea114add2012-05-03 15:00:40 -070097 return b0; // 0:000:a:bcdefgh
buzbee67bf8852011-08-17 17:51:35 -070098 if (value == ((b0 << 16) | b0))
Bill Buzbeea114add2012-05-03 15:00:40 -070099 return (0x1 << 8) | b0; /* 0:001:a:bcdefgh */
buzbee67bf8852011-08-17 17:51:35 -0700100 if (value == ((b0 << 24) | (b0 << 16) | (b0 << 8) | b0))
Bill Buzbeea114add2012-05-03 15:00:40 -0700101 return (0x3 << 8) | b0; /* 0:011:a:bcdefgh */
buzbee67bf8852011-08-17 17:51:35 -0700102 b0 = (value >> 8) & 0xff;
103 if (value == ((b0 << 24) | (b0 << 8)))
Bill Buzbeea114add2012-05-03 15:00:40 -0700104 return (0x2 << 8) | b0; /* 0:010:a:bcdefgh */
buzbee67bf8852011-08-17 17:51:35 -0700105 /* Can we do it with rotation? */
buzbeefa57c472012-11-21 12:06:18 -0800106 z_leading = LeadingZeros(value);
107 z_trailing = 32 - LeadingZeros(~value & (value - 1));
buzbee67bf8852011-08-17 17:51:35 -0700108 /* A run of eight or fewer active bits? */
buzbeefa57c472012-11-21 12:06:18 -0800109 if ((z_leading + z_trailing) < 24)
Bill Buzbeea114add2012-05-03 15:00:40 -0700110 return -1; /* No - bail */
buzbee67bf8852011-08-17 17:51:35 -0700111 /* left-justify the constant, discarding msb (known to be 1) */
buzbeefa57c472012-11-21 12:06:18 -0800112 value <<= z_leading + 1;
buzbee67bf8852011-08-17 17:51:35 -0700113 /* Create bcdefgh */
114 value >>= 25;
115 /* Put it all together */
buzbeefa57c472012-11-21 12:06:18 -0800116 return value | ((0x8 + z_leading) << 7); /* [01000..11111]:bcdefgh */
buzbee67bf8852011-08-17 17:51:35 -0700117}
118
119/*
120 * Load a immediate using a shortcut if possible; otherwise
121 * grab from the per-translation literal pool.
122 *
123 * No additional register clobbering operation performed. Use this version when
buzbeefa57c472012-11-21 12:06:18 -0800124 * 1) r_dest is freshly returned from AllocTemp or
buzbee67bf8852011-08-17 17:51:35 -0700125 * 2) The codegen is under fixed register usage
126 */
buzbeefa57c472012-11-21 12:06:18 -0800127LIR* LoadConstantNoClobber(CompilationUnit* cu, int r_dest, int value)
buzbee67bf8852011-08-17 17:51:35 -0700128{
Bill Buzbeea114add2012-05-03 15:00:40 -0700129 LIR* res;
buzbeefa57c472012-11-21 12:06:18 -0800130 int mod_imm;
buzbee67bf8852011-08-17 17:51:35 -0700131
buzbeefa57c472012-11-21 12:06:18 -0800132 if (ARM_FPREG(r_dest)) {
133 return LoadFPConstantValue(cu, r_dest, value);
Bill Buzbeea114add2012-05-03 15:00:40 -0700134 }
buzbee67bf8852011-08-17 17:51:35 -0700135
Bill Buzbeea114add2012-05-03 15:00:40 -0700136 /* See if the value can be constructed cheaply */
buzbeefa57c472012-11-21 12:06:18 -0800137 if (ARM_LOWREG(r_dest) && (value >= 0) && (value <= 255)) {
138 return NewLIR2(cu, kThumbMovImm, r_dest, value);
Bill Buzbeea114add2012-05-03 15:00:40 -0700139 }
140 /* Check Modified immediate special cases */
buzbeefa57c472012-11-21 12:06:18 -0800141 mod_imm = ModifiedImmediate(value);
142 if (mod_imm >= 0) {
143 res = NewLIR2(cu, kThumb2MovImmShift, r_dest, mod_imm);
buzbee67bf8852011-08-17 17:51:35 -0700144 return res;
Bill Buzbeea114add2012-05-03 15:00:40 -0700145 }
buzbeefa57c472012-11-21 12:06:18 -0800146 mod_imm = ModifiedImmediate(~value);
147 if (mod_imm >= 0) {
148 res = NewLIR2(cu, kThumb2MvnImm12, r_dest, mod_imm);
Bill Buzbeea114add2012-05-03 15:00:40 -0700149 return res;
150 }
151 /* 16-bit immediate? */
152 if ((value & 0xffff) == value) {
buzbeefa57c472012-11-21 12:06:18 -0800153 res = NewLIR2(cu, kThumb2MovImm16, r_dest, value);
Bill Buzbeea114add2012-05-03 15:00:40 -0700154 return res;
155 }
156 /* No shortcut - go ahead and use literal pool */
buzbeefa57c472012-11-21 12:06:18 -0800157 LIR* data_target = ScanLiteralPool(cu->literal_list, value, 0);
158 if (data_target == NULL) {
159 data_target = AddWordData(cu, &cu->literal_list, value);
Bill Buzbeea114add2012-05-03 15:00:40 -0700160 }
buzbeefa57c472012-11-21 12:06:18 -0800161 LIR* load_pc_rel = RawLIR(cu, cu->current_dalvik_offset,
162 kThumb2LdrPcRel12, r_dest, 0, 0, 0, 0, data_target);
163 SetMemRefType(load_pc_rel, true, kLiteral);
164 load_pc_rel->alias_info = reinterpret_cast<uintptr_t>(data_target);
165 res = load_pc_rel;
166 AppendLIR(cu, load_pc_rel);
Bill Buzbeea114add2012-05-03 15:00:40 -0700167
168 /*
169 * To save space in the constant pool, we use the ADD_RRI8 instruction to
170 * add up to 255 to an existing constant value.
171 */
buzbeefa57c472012-11-21 12:06:18 -0800172 if (data_target->operands[0] != value) {
173 OpRegImm(cu, kOpAdd, r_dest, value - data_target->operands[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700174 }
175 return res;
buzbee67bf8852011-08-17 17:51:35 -0700176}
177
buzbeefa57c472012-11-21 12:06:18 -0800178LIR* OpBranchUnconditional(CompilationUnit* cu, OpKind op)
buzbee67bf8852011-08-17 17:51:35 -0700179{
Bill Buzbeea114add2012-05-03 15:00:40 -0700180 DCHECK_EQ(op, kOpUncondBr);
buzbeefa57c472012-11-21 12:06:18 -0800181 return NewLIR1(cu, kThumbBUncond, 0 /* offset to be patched */);
buzbee67bf8852011-08-17 17:51:35 -0700182}
183
buzbeefa57c472012-11-21 12:06:18 -0800184LIR* OpCondBranch(CompilationUnit* cu, ConditionCode cc, LIR* target)
buzbee67bf8852011-08-17 17:51:35 -0700185{
buzbeefa57c472012-11-21 12:06:18 -0800186 LIR* branch = NewLIR2(cu, kThumb2BCond, 0 /* offset to be patched */,
buzbee52a77fc2012-11-20 19:50:46 -0800187 ArmConditionEncoding(cc));
Bill Buzbeea114add2012-05-03 15:00:40 -0700188 branch->target = target;
189 return branch;
buzbee67bf8852011-08-17 17:51:35 -0700190}
191
buzbeefa57c472012-11-21 12:06:18 -0800192LIR* OpReg(CompilationUnit* cu, OpKind op, int r_dest_src)
buzbee67bf8852011-08-17 17:51:35 -0700193{
Bill Buzbeea114add2012-05-03 15:00:40 -0700194 ArmOpcode opcode = kThumbBkpt;
195 switch (op) {
196 case kOpBlx:
197 opcode = kThumbBlxR;
198 break;
199 default:
buzbeecbd6d442012-11-17 14:11:25 -0800200 LOG(FATAL) << "Bad opcode " << op;
Bill Buzbeea114add2012-05-03 15:00:40 -0700201 }
buzbeefa57c472012-11-21 12:06:18 -0800202 return NewLIR1(cu, opcode, r_dest_src);
buzbee67bf8852011-08-17 17:51:35 -0700203}
204
buzbeefa57c472012-11-21 12:06:18 -0800205LIR* OpRegRegShift(CompilationUnit* cu, OpKind op, int r_dest_src1,
206 int r_src2, int shift)
buzbee67bf8852011-08-17 17:51:35 -0700207{
buzbeefa57c472012-11-21 12:06:18 -0800208 bool thumb_form = ((shift == 0) && ARM_LOWREG(r_dest_src1) && ARM_LOWREG(r_src2));
Bill Buzbeea114add2012-05-03 15:00:40 -0700209 ArmOpcode opcode = kThumbBkpt;
210 switch (op) {
211 case kOpAdc:
buzbeefa57c472012-11-21 12:06:18 -0800212 opcode = (thumb_form) ? kThumbAdcRR : kThumb2AdcRRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700213 break;
214 case kOpAnd:
buzbeefa57c472012-11-21 12:06:18 -0800215 opcode = (thumb_form) ? kThumbAndRR : kThumb2AndRRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700216 break;
217 case kOpBic:
buzbeefa57c472012-11-21 12:06:18 -0800218 opcode = (thumb_form) ? kThumbBicRR : kThumb2BicRRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700219 break;
220 case kOpCmn:
221 DCHECK_EQ(shift, 0);
buzbeefa57c472012-11-21 12:06:18 -0800222 opcode = (thumb_form) ? kThumbCmnRR : kThumb2CmnRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700223 break;
224 case kOpCmp:
buzbeefa57c472012-11-21 12:06:18 -0800225 if (thumb_form)
Bill Buzbeea114add2012-05-03 15:00:40 -0700226 opcode = kThumbCmpRR;
buzbeefa57c472012-11-21 12:06:18 -0800227 else if ((shift == 0) && !ARM_LOWREG(r_dest_src1) && !ARM_LOWREG(r_src2))
Bill Buzbeea114add2012-05-03 15:00:40 -0700228 opcode = kThumbCmpHH;
buzbeefa57c472012-11-21 12:06:18 -0800229 else if ((shift == 0) && ARM_LOWREG(r_dest_src1))
Bill Buzbeea114add2012-05-03 15:00:40 -0700230 opcode = kThumbCmpLH;
231 else if (shift == 0)
232 opcode = kThumbCmpHL;
233 else
234 opcode = kThumb2CmpRR;
235 break;
236 case kOpXor:
buzbeefa57c472012-11-21 12:06:18 -0800237 opcode = (thumb_form) ? kThumbEorRR : kThumb2EorRRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700238 break;
239 case kOpMov:
240 DCHECK_EQ(shift, 0);
buzbeefa57c472012-11-21 12:06:18 -0800241 if (ARM_LOWREG(r_dest_src1) && ARM_LOWREG(r_src2))
Bill Buzbeea114add2012-05-03 15:00:40 -0700242 opcode = kThumbMovRR;
buzbeefa57c472012-11-21 12:06:18 -0800243 else if (!ARM_LOWREG(r_dest_src1) && !ARM_LOWREG(r_src2))
Bill Buzbeea114add2012-05-03 15:00:40 -0700244 opcode = kThumbMovRR_H2H;
buzbeefa57c472012-11-21 12:06:18 -0800245 else if (ARM_LOWREG(r_dest_src1))
Bill Buzbeea114add2012-05-03 15:00:40 -0700246 opcode = kThumbMovRR_H2L;
247 else
248 opcode = kThumbMovRR_L2H;
249 break;
250 case kOpMul:
251 DCHECK_EQ(shift, 0);
buzbeefa57c472012-11-21 12:06:18 -0800252 opcode = (thumb_form) ? kThumbMul : kThumb2MulRRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700253 break;
254 case kOpMvn:
buzbeefa57c472012-11-21 12:06:18 -0800255 opcode = (thumb_form) ? kThumbMvn : kThumb2MnvRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700256 break;
257 case kOpNeg:
258 DCHECK_EQ(shift, 0);
buzbeefa57c472012-11-21 12:06:18 -0800259 opcode = (thumb_form) ? kThumbNeg : kThumb2NegRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700260 break;
261 case kOpOr:
buzbeefa57c472012-11-21 12:06:18 -0800262 opcode = (thumb_form) ? kThumbOrr : kThumb2OrrRRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700263 break;
264 case kOpSbc:
buzbeefa57c472012-11-21 12:06:18 -0800265 opcode = (thumb_form) ? kThumbSbc : kThumb2SbcRRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700266 break;
267 case kOpTst:
buzbeefa57c472012-11-21 12:06:18 -0800268 opcode = (thumb_form) ? kThumbTst : kThumb2TstRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700269 break;
270 case kOpLsl:
271 DCHECK_EQ(shift, 0);
buzbeefa57c472012-11-21 12:06:18 -0800272 opcode = (thumb_form) ? kThumbLslRR : kThumb2LslRRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700273 break;
274 case kOpLsr:
275 DCHECK_EQ(shift, 0);
buzbeefa57c472012-11-21 12:06:18 -0800276 opcode = (thumb_form) ? kThumbLsrRR : kThumb2LsrRRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700277 break;
278 case kOpAsr:
279 DCHECK_EQ(shift, 0);
buzbeefa57c472012-11-21 12:06:18 -0800280 opcode = (thumb_form) ? kThumbAsrRR : kThumb2AsrRRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700281 break;
282 case kOpRor:
283 DCHECK_EQ(shift, 0);
buzbeefa57c472012-11-21 12:06:18 -0800284 opcode = (thumb_form) ? kThumbRorRR : kThumb2RorRRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700285 break;
286 case kOpAdd:
buzbeefa57c472012-11-21 12:06:18 -0800287 opcode = (thumb_form) ? kThumbAddRRR : kThumb2AddRRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700288 break;
289 case kOpSub:
buzbeefa57c472012-11-21 12:06:18 -0800290 opcode = (thumb_form) ? kThumbSubRRR : kThumb2SubRRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700291 break;
292 case kOp2Byte:
293 DCHECK_EQ(shift, 0);
buzbeefa57c472012-11-21 12:06:18 -0800294 return NewLIR4(cu, kThumb2Sbfx, r_dest_src1, r_src2, 0, 8);
Bill Buzbeea114add2012-05-03 15:00:40 -0700295 case kOp2Short:
296 DCHECK_EQ(shift, 0);
buzbeefa57c472012-11-21 12:06:18 -0800297 return NewLIR4(cu, kThumb2Sbfx, r_dest_src1, r_src2, 0, 16);
Bill Buzbeea114add2012-05-03 15:00:40 -0700298 case kOp2Char:
299 DCHECK_EQ(shift, 0);
buzbeefa57c472012-11-21 12:06:18 -0800300 return NewLIR4(cu, kThumb2Ubfx, r_dest_src1, r_src2, 0, 16);
Bill Buzbeea114add2012-05-03 15:00:40 -0700301 default:
buzbeecbd6d442012-11-17 14:11:25 -0800302 LOG(FATAL) << "Bad opcode: " << op;
Bill Buzbeea114add2012-05-03 15:00:40 -0700303 break;
304 }
305 DCHECK_GE(static_cast<int>(opcode), 0);
306 if (EncodingMap[opcode].flags & IS_BINARY_OP)
buzbeefa57c472012-11-21 12:06:18 -0800307 return NewLIR2(cu, opcode, r_dest_src1, r_src2);
Bill Buzbeea114add2012-05-03 15:00:40 -0700308 else if (EncodingMap[opcode].flags & IS_TERTIARY_OP) {
buzbeefa57c472012-11-21 12:06:18 -0800309 if (EncodingMap[opcode].field_loc[2].kind == kFmtShift)
310 return NewLIR3(cu, opcode, r_dest_src1, r_src2, shift);
Bill Buzbeea114add2012-05-03 15:00:40 -0700311 else
buzbeefa57c472012-11-21 12:06:18 -0800312 return NewLIR3(cu, opcode, r_dest_src1, r_dest_src1, r_src2);
Bill Buzbeea114add2012-05-03 15:00:40 -0700313 } else if (EncodingMap[opcode].flags & IS_QUAD_OP)
buzbeefa57c472012-11-21 12:06:18 -0800314 return NewLIR4(cu, opcode, r_dest_src1, r_dest_src1, r_src2, shift);
Bill Buzbeea114add2012-05-03 15:00:40 -0700315 else {
316 LOG(FATAL) << "Unexpected encoding operand count";
317 return NULL;
318 }
buzbee67bf8852011-08-17 17:51:35 -0700319}
320
buzbeefa57c472012-11-21 12:06:18 -0800321LIR* OpRegReg(CompilationUnit* cu, OpKind op, int r_dest_src1, int r_src2)
buzbee67bf8852011-08-17 17:51:35 -0700322{
buzbeefa57c472012-11-21 12:06:18 -0800323 return OpRegRegShift(cu, op, r_dest_src1, r_src2, 0);
buzbee67bf8852011-08-17 17:51:35 -0700324}
325
buzbeefa57c472012-11-21 12:06:18 -0800326LIR* OpRegRegRegShift(CompilationUnit* cu, OpKind op, int r_dest, int r_src1,
327 int r_src2, int shift)
buzbee67bf8852011-08-17 17:51:35 -0700328{
Bill Buzbeea114add2012-05-03 15:00:40 -0700329 ArmOpcode opcode = kThumbBkpt;
buzbeefa57c472012-11-21 12:06:18 -0800330 bool thumb_form = (shift == 0) && ARM_LOWREG(r_dest) && ARM_LOWREG(r_src1) &&
331 ARM_LOWREG(r_src2);
Bill Buzbeea114add2012-05-03 15:00:40 -0700332 switch (op) {
333 case kOpAdd:
buzbeefa57c472012-11-21 12:06:18 -0800334 opcode = (thumb_form) ? kThumbAddRRR : kThumb2AddRRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700335 break;
336 case kOpSub:
buzbeefa57c472012-11-21 12:06:18 -0800337 opcode = (thumb_form) ? kThumbSubRRR : kThumb2SubRRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700338 break;
339 case kOpRsub:
340 opcode = kThumb2RsubRRR;
341 break;
342 case kOpAdc:
343 opcode = kThumb2AdcRRR;
344 break;
345 case kOpAnd:
346 opcode = kThumb2AndRRR;
347 break;
348 case kOpBic:
349 opcode = kThumb2BicRRR;
350 break;
351 case kOpXor:
352 opcode = kThumb2EorRRR;
353 break;
354 case kOpMul:
355 DCHECK_EQ(shift, 0);
356 opcode = kThumb2MulRRR;
357 break;
358 case kOpOr:
359 opcode = kThumb2OrrRRR;
360 break;
361 case kOpSbc:
362 opcode = kThumb2SbcRRR;
363 break;
364 case kOpLsl:
365 DCHECK_EQ(shift, 0);
366 opcode = kThumb2LslRRR;
367 break;
368 case kOpLsr:
369 DCHECK_EQ(shift, 0);
370 opcode = kThumb2LsrRRR;
371 break;
372 case kOpAsr:
373 DCHECK_EQ(shift, 0);
374 opcode = kThumb2AsrRRR;
375 break;
376 case kOpRor:
377 DCHECK_EQ(shift, 0);
378 opcode = kThumb2RorRRR;
379 break;
380 default:
buzbeecbd6d442012-11-17 14:11:25 -0800381 LOG(FATAL) << "Bad opcode: " << op;
Bill Buzbeea114add2012-05-03 15:00:40 -0700382 break;
383 }
384 DCHECK_GE(static_cast<int>(opcode), 0);
385 if (EncodingMap[opcode].flags & IS_QUAD_OP)
buzbeefa57c472012-11-21 12:06:18 -0800386 return NewLIR4(cu, opcode, r_dest, r_src1, r_src2, shift);
Bill Buzbeea114add2012-05-03 15:00:40 -0700387 else {
388 DCHECK(EncodingMap[opcode].flags & IS_TERTIARY_OP);
buzbeefa57c472012-11-21 12:06:18 -0800389 return NewLIR3(cu, opcode, r_dest, r_src1, r_src2);
Bill Buzbeea114add2012-05-03 15:00:40 -0700390 }
buzbee67bf8852011-08-17 17:51:35 -0700391}
392
buzbeefa57c472012-11-21 12:06:18 -0800393LIR* OpRegRegReg(CompilationUnit* cu, OpKind op, int r_dest, int r_src1,
394 int r_src2)
buzbee67bf8852011-08-17 17:51:35 -0700395{
buzbeefa57c472012-11-21 12:06:18 -0800396 return OpRegRegRegShift(cu, op, r_dest, r_src1, r_src2, 0);
buzbee67bf8852011-08-17 17:51:35 -0700397}
398
buzbeefa57c472012-11-21 12:06:18 -0800399LIR* OpRegRegImm(CompilationUnit* cu, OpKind op, int r_dest, int r_src1,
buzbee31a4a6f2012-02-28 15:36:15 -0800400 int value)
buzbee67bf8852011-08-17 17:51:35 -0700401{
Bill Buzbeea114add2012-05-03 15:00:40 -0700402 LIR* res;
403 bool neg = (value < 0);
buzbeefa57c472012-11-21 12:06:18 -0800404 int abs_value = (neg) ? -value : value;
Bill Buzbeea114add2012-05-03 15:00:40 -0700405 ArmOpcode opcode = kThumbBkpt;
buzbeefa57c472012-11-21 12:06:18 -0800406 ArmOpcode alt_opcode = kThumbBkpt;
407 bool all_low_regs = (ARM_LOWREG(r_dest) && ARM_LOWREG(r_src1));
408 int mod_imm = ModifiedImmediate(value);
409 int mod_imm_neg = ModifiedImmediate(-value);
buzbee67bf8852011-08-17 17:51:35 -0700410
Bill Buzbeea114add2012-05-03 15:00:40 -0700411 switch (op) {
412 case kOpLsl:
buzbeefa57c472012-11-21 12:06:18 -0800413 if (all_low_regs)
414 return NewLIR3(cu, kThumbLslRRI5, r_dest, r_src1, value);
Bill Buzbeea114add2012-05-03 15:00:40 -0700415 else
buzbeefa57c472012-11-21 12:06:18 -0800416 return NewLIR3(cu, kThumb2LslRRI5, r_dest, r_src1, value);
Bill Buzbeea114add2012-05-03 15:00:40 -0700417 case kOpLsr:
buzbeefa57c472012-11-21 12:06:18 -0800418 if (all_low_regs)
419 return NewLIR3(cu, kThumbLsrRRI5, r_dest, r_src1, value);
Bill Buzbeea114add2012-05-03 15:00:40 -0700420 else
buzbeefa57c472012-11-21 12:06:18 -0800421 return NewLIR3(cu, kThumb2LsrRRI5, r_dest, r_src1, value);
Bill Buzbeea114add2012-05-03 15:00:40 -0700422 case kOpAsr:
buzbeefa57c472012-11-21 12:06:18 -0800423 if (all_low_regs)
424 return NewLIR3(cu, kThumbAsrRRI5, r_dest, r_src1, value);
Bill Buzbeea114add2012-05-03 15:00:40 -0700425 else
buzbeefa57c472012-11-21 12:06:18 -0800426 return NewLIR3(cu, kThumb2AsrRRI5, r_dest, r_src1, value);
Bill Buzbeea114add2012-05-03 15:00:40 -0700427 case kOpRor:
buzbeefa57c472012-11-21 12:06:18 -0800428 return NewLIR3(cu, kThumb2RorRRI5, r_dest, r_src1, value);
Bill Buzbeea114add2012-05-03 15:00:40 -0700429 case kOpAdd:
buzbeefa57c472012-11-21 12:06:18 -0800430 if (ARM_LOWREG(r_dest) && (r_src1 == r13sp) &&
Bill Buzbeea114add2012-05-03 15:00:40 -0700431 (value <= 1020) && ((value & 0x3)==0)) {
buzbeefa57c472012-11-21 12:06:18 -0800432 return NewLIR3(cu, kThumbAddSpRel, r_dest, r_src1, value >> 2);
433 } else if (ARM_LOWREG(r_dest) && (r_src1 == r15pc) &&
Bill Buzbeea114add2012-05-03 15:00:40 -0700434 (value <= 1020) && ((value & 0x3)==0)) {
buzbeefa57c472012-11-21 12:06:18 -0800435 return NewLIR3(cu, kThumbAddPcRel, r_dest, r_src1, value >> 2);
Bill Buzbeea114add2012-05-03 15:00:40 -0700436 }
437 // Note: intentional fallthrough
438 case kOpSub:
buzbeefa57c472012-11-21 12:06:18 -0800439 if (all_low_regs && ((abs_value & 0x7) == abs_value)) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700440 if (op == kOpAdd)
441 opcode = (neg) ? kThumbSubRRI3 : kThumbAddRRI3;
buzbee67bf8852011-08-17 17:51:35 -0700442 else
Bill Buzbeea114add2012-05-03 15:00:40 -0700443 opcode = (neg) ? kThumbAddRRI3 : kThumbSubRRI3;
buzbeefa57c472012-11-21 12:06:18 -0800444 return NewLIR3(cu, opcode, r_dest, r_src1, abs_value);
445 } else if ((abs_value & 0xff) == abs_value) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700446 if (op == kOpAdd)
447 opcode = (neg) ? kThumb2SubRRI12 : kThumb2AddRRI12;
448 else
449 opcode = (neg) ? kThumb2AddRRI12 : kThumb2SubRRI12;
buzbeefa57c472012-11-21 12:06:18 -0800450 return NewLIR3(cu, opcode, r_dest, r_src1, abs_value);
Bill Buzbeea114add2012-05-03 15:00:40 -0700451 }
buzbeefa57c472012-11-21 12:06:18 -0800452 if (mod_imm_neg >= 0) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700453 op = (op == kOpAdd) ? kOpSub : kOpAdd;
buzbeefa57c472012-11-21 12:06:18 -0800454 mod_imm = mod_imm_neg;
Bill Buzbeea114add2012-05-03 15:00:40 -0700455 }
456 if (op == kOpSub) {
457 opcode = kThumb2SubRRI8;
buzbeefa57c472012-11-21 12:06:18 -0800458 alt_opcode = kThumb2SubRRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700459 } else {
460 opcode = kThumb2AddRRI8;
buzbeefa57c472012-11-21 12:06:18 -0800461 alt_opcode = kThumb2AddRRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700462 }
463 break;
464 case kOpAdc:
465 opcode = kThumb2AdcRRI8;
buzbeefa57c472012-11-21 12:06:18 -0800466 alt_opcode = kThumb2AdcRRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700467 break;
468 case kOpSbc:
469 opcode = kThumb2SbcRRI8;
buzbeefa57c472012-11-21 12:06:18 -0800470 alt_opcode = kThumb2SbcRRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700471 break;
472 case kOpOr:
473 opcode = kThumb2OrrRRI8;
buzbeefa57c472012-11-21 12:06:18 -0800474 alt_opcode = kThumb2OrrRRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700475 break;
476 case kOpAnd:
477 opcode = kThumb2AndRRI8;
buzbeefa57c472012-11-21 12:06:18 -0800478 alt_opcode = kThumb2AndRRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700479 break;
480 case kOpXor:
481 opcode = kThumb2EorRRI8;
buzbeefa57c472012-11-21 12:06:18 -0800482 alt_opcode = kThumb2EorRRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700483 break;
484 case kOpMul:
485 //TUNING: power of 2, shift & add
buzbeefa57c472012-11-21 12:06:18 -0800486 mod_imm = -1;
487 alt_opcode = kThumb2MulRRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700488 break;
489 case kOpCmp: {
buzbeefa57c472012-11-21 12:06:18 -0800490 int mod_imm = ModifiedImmediate(value);
Bill Buzbeea114add2012-05-03 15:00:40 -0700491 LIR* res;
buzbeefa57c472012-11-21 12:06:18 -0800492 if (mod_imm >= 0) {
493 res = NewLIR2(cu, kThumb2CmpRI8, r_src1, mod_imm);
Bill Buzbeea114add2012-05-03 15:00:40 -0700494 } else {
buzbeefa57c472012-11-21 12:06:18 -0800495 int r_tmp = AllocTemp(cu);
496 res = LoadConstant(cu, r_tmp, value);
497 OpRegReg(cu, kOpCmp, r_src1, r_tmp);
498 FreeTemp(cu, r_tmp);
Bill Buzbeea114add2012-05-03 15:00:40 -0700499 }
500 return res;
buzbee67bf8852011-08-17 17:51:35 -0700501 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700502 default:
buzbeecbd6d442012-11-17 14:11:25 -0800503 LOG(FATAL) << "Bad opcode: " << op;
Bill Buzbeea114add2012-05-03 15:00:40 -0700504 }
505
buzbeefa57c472012-11-21 12:06:18 -0800506 if (mod_imm >= 0) {
507 return NewLIR3(cu, opcode, r_dest, r_src1, mod_imm);
Bill Buzbeea114add2012-05-03 15:00:40 -0700508 } else {
buzbeefa57c472012-11-21 12:06:18 -0800509 int r_scratch = AllocTemp(cu);
510 LoadConstant(cu, r_scratch, value);
511 if (EncodingMap[alt_opcode].flags & IS_QUAD_OP)
512 res = NewLIR4(cu, alt_opcode, r_dest, r_src1, r_scratch, 0);
Bill Buzbeea114add2012-05-03 15:00:40 -0700513 else
buzbeefa57c472012-11-21 12:06:18 -0800514 res = NewLIR3(cu, alt_opcode, r_dest, r_src1, r_scratch);
515 FreeTemp(cu, r_scratch);
Bill Buzbeea114add2012-05-03 15:00:40 -0700516 return res;
517 }
buzbee67bf8852011-08-17 17:51:35 -0700518}
519
buzbee52a77fc2012-11-20 19:50:46 -0800520/* Handle Thumb-only variants here - otherwise punt to OpRegRegImm */
buzbeefa57c472012-11-21 12:06:18 -0800521LIR* OpRegImm(CompilationUnit* cu, OpKind op, int r_dest_src1, int value)
buzbee67bf8852011-08-17 17:51:35 -0700522{
Bill Buzbeea114add2012-05-03 15:00:40 -0700523 bool neg = (value < 0);
buzbeefa57c472012-11-21 12:06:18 -0800524 int abs_value = (neg) ? -value : value;
525 bool short_form = (((abs_value & 0xff) == abs_value) && ARM_LOWREG(r_dest_src1));
Bill Buzbeea114add2012-05-03 15:00:40 -0700526 ArmOpcode opcode = kThumbBkpt;
527 switch (op) {
528 case kOpAdd:
buzbeefa57c472012-11-21 12:06:18 -0800529 if ( !neg && (r_dest_src1 == r13sp) && (value <= 508)) { /* sp */
Bill Buzbeea114add2012-05-03 15:00:40 -0700530 DCHECK_EQ((value & 0x3), 0);
buzbeefa57c472012-11-21 12:06:18 -0800531 return NewLIR1(cu, kThumbAddSpI7, value >> 2);
532 } else if (short_form) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700533 opcode = (neg) ? kThumbSubRI8 : kThumbAddRI8;
534 }
535 break;
536 case kOpSub:
buzbeefa57c472012-11-21 12:06:18 -0800537 if (!neg && (r_dest_src1 == r13sp) && (value <= 508)) { /* sp */
Bill Buzbeea114add2012-05-03 15:00:40 -0700538 DCHECK_EQ((value & 0x3), 0);
buzbeefa57c472012-11-21 12:06:18 -0800539 return NewLIR1(cu, kThumbSubSpI7, value >> 2);
540 } else if (short_form) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700541 opcode = (neg) ? kThumbAddRI8 : kThumbSubRI8;
542 }
543 break;
544 case kOpCmp:
buzbeefa57c472012-11-21 12:06:18 -0800545 if (ARM_LOWREG(r_dest_src1) && short_form)
546 opcode = (short_form) ? kThumbCmpRI8 : kThumbCmpRR;
547 else if (ARM_LOWREG(r_dest_src1))
Bill Buzbeea114add2012-05-03 15:00:40 -0700548 opcode = kThumbCmpRR;
549 else {
buzbeefa57c472012-11-21 12:06:18 -0800550 short_form = false;
Bill Buzbeea114add2012-05-03 15:00:40 -0700551 opcode = kThumbCmpHL;
552 }
553 break;
554 default:
buzbee52a77fc2012-11-20 19:50:46 -0800555 /* Punt to OpRegRegImm - if bad case catch it there */
buzbeefa57c472012-11-21 12:06:18 -0800556 short_form = false;
Bill Buzbeea114add2012-05-03 15:00:40 -0700557 break;
558 }
buzbeefa57c472012-11-21 12:06:18 -0800559 if (short_form)
560 return NewLIR2(cu, opcode, r_dest_src1, abs_value);
Bill Buzbeea114add2012-05-03 15:00:40 -0700561 else {
buzbeefa57c472012-11-21 12:06:18 -0800562 return OpRegRegImm(cu, op, r_dest_src1, r_dest_src1, value);
Bill Buzbeea114add2012-05-03 15:00:40 -0700563 }
buzbee67bf8852011-08-17 17:51:35 -0700564}
565
566/*
567 * Determine whether value can be encoded as a Thumb2 floating point
568 * immediate. If not, return -1. If so return encoded 8-bit value.
569 */
buzbeeaad94382012-11-21 07:40:50 -0800570static int EncodeImmDoubleHigh(int value)
buzbee67bf8852011-08-17 17:51:35 -0700571{
Bill Buzbeea114add2012-05-03 15:00:40 -0700572 int res;
buzbeefa57c472012-11-21 12:06:18 -0800573 int bit_a = (value & 0x80000000) >> 31;
574 int not_bit_b = (value & 0x40000000) >> 30;
575 int bit_b = (value & 0x20000000) >> 29;
576 int b_smear = (value & 0x3fc00000) >> 22;
Bill Buzbeea114add2012-05-03 15:00:40 -0700577 int slice = (value & 0x003f0000) >> 16;
578 int zeroes = (value & 0x0000ffff);
579 if (zeroes != 0)
580 return -1;
buzbeefa57c472012-11-21 12:06:18 -0800581 if (bit_b) {
582 if ((not_bit_b != 0) || (b_smear != 0xff))
Bill Buzbeea114add2012-05-03 15:00:40 -0700583 return -1;
584 } else {
buzbeefa57c472012-11-21 12:06:18 -0800585 if ((not_bit_b != 1) || (b_smear != 0x0))
Bill Buzbeea114add2012-05-03 15:00:40 -0700586 return -1;
587 }
buzbeefa57c472012-11-21 12:06:18 -0800588 res = (bit_a << 7) | (bit_b << 6) | slice;
Bill Buzbeea114add2012-05-03 15:00:40 -0700589 return res;
buzbee67bf8852011-08-17 17:51:35 -0700590}
591
buzbeefa57c472012-11-21 12:06:18 -0800592static int EncodeImmDouble(int val_lo, int val_hi)
buzbee67bf8852011-08-17 17:51:35 -0700593{
Bill Buzbeea114add2012-05-03 15:00:40 -0700594 int res = -1;
buzbeefa57c472012-11-21 12:06:18 -0800595 if (val_lo == 0)
596 res = EncodeImmDoubleHigh(val_hi);
Bill Buzbeea114add2012-05-03 15:00:40 -0700597 return res;
buzbee67bf8852011-08-17 17:51:35 -0700598}
599
buzbeefa57c472012-11-21 12:06:18 -0800600LIR* LoadConstantValueWide(CompilationUnit* cu, int r_dest_lo, int r_dest_hi,
601 int val_lo, int val_hi)
buzbee67bf8852011-08-17 17:51:35 -0700602{
buzbeefa57c472012-11-21 12:06:18 -0800603 int encoded_imm = EncodeImmDouble(val_lo, val_hi);
Bill Buzbeea114add2012-05-03 15:00:40 -0700604 LIR* res;
buzbeefa57c472012-11-21 12:06:18 -0800605 if (ARM_FPREG(r_dest_lo)) {
606 if (encoded_imm >= 0) {
607 res = NewLIR2(cu, kThumb2Vmovd_IMM8, S2d(r_dest_lo, r_dest_hi),
608 encoded_imm);
buzbee67bf8852011-08-17 17:51:35 -0700609 } else {
buzbeefa57c472012-11-21 12:06:18 -0800610 LIR* data_target = ScanLiteralPoolWide(cu->literal_list, val_lo, val_hi);
611 if (data_target == NULL) {
612 data_target = AddWideData(cu, &cu->literal_list, val_lo, val_hi);
Bill Buzbeea114add2012-05-03 15:00:40 -0700613 }
buzbeefa57c472012-11-21 12:06:18 -0800614 LIR* load_pc_rel =
615 RawLIR(cu, cu->current_dalvik_offset, kThumb2Vldrd,
616 S2d(r_dest_lo, r_dest_hi), r15pc, 0, 0, 0, data_target);
617 SetMemRefType(load_pc_rel, true, kLiteral);
618 load_pc_rel->alias_info = reinterpret_cast<uintptr_t>(data_target);
619 AppendLIR(cu, load_pc_rel);
620 res = load_pc_rel;
buzbee67bf8852011-08-17 17:51:35 -0700621 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700622 } else {
buzbeefa57c472012-11-21 12:06:18 -0800623 res = LoadConstantNoClobber(cu, r_dest_lo, val_lo);
624 LoadConstantNoClobber(cu, r_dest_hi, val_hi);
Bill Buzbeea114add2012-05-03 15:00:40 -0700625 }
626 return res;
buzbee67bf8852011-08-17 17:51:35 -0700627}
628
buzbee52a77fc2012-11-20 19:50:46 -0800629int EncodeShift(int code, int amount) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700630 return ((amount & 0x1f) << 2) | code;
buzbee67bf8852011-08-17 17:51:35 -0700631}
632
buzbeefa57c472012-11-21 12:06:18 -0800633LIR* LoadBaseIndexed(CompilationUnit* cu, int rBase, int r_index, int r_dest,
buzbee31a4a6f2012-02-28 15:36:15 -0800634 int scale, OpSize size)
buzbee67bf8852011-08-17 17:51:35 -0700635{
buzbeefa57c472012-11-21 12:06:18 -0800636 bool all_low_regs = ARM_LOWREG(rBase) && ARM_LOWREG(r_index) && ARM_LOWREG(r_dest);
Bill Buzbeea114add2012-05-03 15:00:40 -0700637 LIR* load;
638 ArmOpcode opcode = kThumbBkpt;
buzbeefa57c472012-11-21 12:06:18 -0800639 bool thumb_form = (all_low_regs && (scale == 0));
640 int reg_ptr;
buzbee67bf8852011-08-17 17:51:35 -0700641
buzbeefa57c472012-11-21 12:06:18 -0800642 if (ARM_FPREG(r_dest)) {
643 if (ARM_SINGLEREG(r_dest)) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700644 DCHECK((size == kWord) || (size == kSingle));
645 opcode = kThumb2Vldrs;
646 size = kSingle;
buzbee67bf8852011-08-17 17:51:35 -0700647 } else {
buzbeefa57c472012-11-21 12:06:18 -0800648 DCHECK(ARM_DOUBLEREG(r_dest));
Bill Buzbeea114add2012-05-03 15:00:40 -0700649 DCHECK((size == kLong) || (size == kDouble));
buzbeefa57c472012-11-21 12:06:18 -0800650 DCHECK_EQ((r_dest & 0x1), 0);
Bill Buzbeea114add2012-05-03 15:00:40 -0700651 opcode = kThumb2Vldrd;
652 size = kDouble;
buzbee67bf8852011-08-17 17:51:35 -0700653 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700654 } else {
655 if (size == kSingle)
656 size = kWord;
657 }
buzbee67bf8852011-08-17 17:51:35 -0700658
Bill Buzbeea114add2012-05-03 15:00:40 -0700659 switch (size) {
660 case kDouble: // fall-through
661 case kSingle:
buzbeefa57c472012-11-21 12:06:18 -0800662 reg_ptr = AllocTemp(cu);
Bill Buzbeea114add2012-05-03 15:00:40 -0700663 if (scale) {
buzbeefa57c472012-11-21 12:06:18 -0800664 NewLIR4(cu, kThumb2AddRRR, reg_ptr, rBase, r_index,
buzbee52a77fc2012-11-20 19:50:46 -0800665 EncodeShift(kArmLsl, scale));
Bill Buzbeea114add2012-05-03 15:00:40 -0700666 } else {
buzbeefa57c472012-11-21 12:06:18 -0800667 OpRegRegReg(cu, kOpAdd, reg_ptr, rBase, r_index);
Bill Buzbeea114add2012-05-03 15:00:40 -0700668 }
buzbeefa57c472012-11-21 12:06:18 -0800669 load = NewLIR3(cu, opcode, r_dest, reg_ptr, 0);
670 FreeTemp(cu, reg_ptr);
Bill Buzbeea114add2012-05-03 15:00:40 -0700671 return load;
672 case kWord:
buzbeefa57c472012-11-21 12:06:18 -0800673 opcode = (thumb_form) ? kThumbLdrRRR : kThumb2LdrRRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700674 break;
675 case kUnsignedHalf:
buzbeefa57c472012-11-21 12:06:18 -0800676 opcode = (thumb_form) ? kThumbLdrhRRR : kThumb2LdrhRRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700677 break;
678 case kSignedHalf:
buzbeefa57c472012-11-21 12:06:18 -0800679 opcode = (thumb_form) ? kThumbLdrshRRR : kThumb2LdrshRRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700680 break;
681 case kUnsignedByte:
buzbeefa57c472012-11-21 12:06:18 -0800682 opcode = (thumb_form) ? kThumbLdrbRRR : kThumb2LdrbRRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700683 break;
684 case kSignedByte:
buzbeefa57c472012-11-21 12:06:18 -0800685 opcode = (thumb_form) ? kThumbLdrsbRRR : kThumb2LdrsbRRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700686 break;
687 default:
buzbeecbd6d442012-11-17 14:11:25 -0800688 LOG(FATAL) << "Bad size: " << size;
Bill Buzbeea114add2012-05-03 15:00:40 -0700689 }
buzbeefa57c472012-11-21 12:06:18 -0800690 if (thumb_form)
691 load = NewLIR3(cu, opcode, r_dest, rBase, r_index);
Bill Buzbeea114add2012-05-03 15:00:40 -0700692 else
buzbeefa57c472012-11-21 12:06:18 -0800693 load = NewLIR4(cu, opcode, r_dest, rBase, r_index, scale);
buzbee67bf8852011-08-17 17:51:35 -0700694
Bill Buzbeea114add2012-05-03 15:00:40 -0700695 return load;
buzbee67bf8852011-08-17 17:51:35 -0700696}
697
buzbeefa57c472012-11-21 12:06:18 -0800698LIR* StoreBaseIndexed(CompilationUnit* cu, int rBase, int r_index, int r_src,
buzbee31a4a6f2012-02-28 15:36:15 -0800699 int scale, OpSize size)
buzbee67bf8852011-08-17 17:51:35 -0700700{
buzbeefa57c472012-11-21 12:06:18 -0800701 bool all_low_regs = ARM_LOWREG(rBase) && ARM_LOWREG(r_index) && ARM_LOWREG(r_src);
Bill Buzbeea114add2012-05-03 15:00:40 -0700702 LIR* store;
703 ArmOpcode opcode = kThumbBkpt;
buzbeefa57c472012-11-21 12:06:18 -0800704 bool thumb_form = (all_low_regs && (scale == 0));
705 int reg_ptr;
buzbee67bf8852011-08-17 17:51:35 -0700706
buzbeefa57c472012-11-21 12:06:18 -0800707 if (ARM_FPREG(r_src)) {
708 if (ARM_SINGLEREG(r_src)) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700709 DCHECK((size == kWord) || (size == kSingle));
710 opcode = kThumb2Vstrs;
711 size = kSingle;
buzbee67bf8852011-08-17 17:51:35 -0700712 } else {
buzbeefa57c472012-11-21 12:06:18 -0800713 DCHECK(ARM_DOUBLEREG(r_src));
Bill Buzbeea114add2012-05-03 15:00:40 -0700714 DCHECK((size == kLong) || (size == kDouble));
buzbeefa57c472012-11-21 12:06:18 -0800715 DCHECK_EQ((r_src & 0x1), 0);
Bill Buzbeea114add2012-05-03 15:00:40 -0700716 opcode = kThumb2Vstrd;
717 size = kDouble;
buzbee67bf8852011-08-17 17:51:35 -0700718 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700719 } else {
720 if (size == kSingle)
721 size = kWord;
722 }
buzbee67bf8852011-08-17 17:51:35 -0700723
Bill Buzbeea114add2012-05-03 15:00:40 -0700724 switch (size) {
725 case kDouble: // fall-through
726 case kSingle:
buzbeefa57c472012-11-21 12:06:18 -0800727 reg_ptr = AllocTemp(cu);
Bill Buzbeea114add2012-05-03 15:00:40 -0700728 if (scale) {
buzbeefa57c472012-11-21 12:06:18 -0800729 NewLIR4(cu, kThumb2AddRRR, reg_ptr, rBase, r_index,
buzbee52a77fc2012-11-20 19:50:46 -0800730 EncodeShift(kArmLsl, scale));
Bill Buzbeea114add2012-05-03 15:00:40 -0700731 } else {
buzbeefa57c472012-11-21 12:06:18 -0800732 OpRegRegReg(cu, kOpAdd, reg_ptr, rBase, r_index);
Bill Buzbeea114add2012-05-03 15:00:40 -0700733 }
buzbeefa57c472012-11-21 12:06:18 -0800734 store = NewLIR3(cu, opcode, r_src, reg_ptr, 0);
735 FreeTemp(cu, reg_ptr);
Bill Buzbeea114add2012-05-03 15:00:40 -0700736 return store;
737 case kWord:
buzbeefa57c472012-11-21 12:06:18 -0800738 opcode = (thumb_form) ? kThumbStrRRR : kThumb2StrRRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700739 break;
740 case kUnsignedHalf:
741 case kSignedHalf:
buzbeefa57c472012-11-21 12:06:18 -0800742 opcode = (thumb_form) ? kThumbStrhRRR : kThumb2StrhRRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700743 break;
744 case kUnsignedByte:
745 case kSignedByte:
buzbeefa57c472012-11-21 12:06:18 -0800746 opcode = (thumb_form) ? kThumbStrbRRR : kThumb2StrbRRR;
Bill Buzbeea114add2012-05-03 15:00:40 -0700747 break;
748 default:
buzbeecbd6d442012-11-17 14:11:25 -0800749 LOG(FATAL) << "Bad size: " << size;
Bill Buzbeea114add2012-05-03 15:00:40 -0700750 }
buzbeefa57c472012-11-21 12:06:18 -0800751 if (thumb_form)
752 store = NewLIR3(cu, opcode, r_src, rBase, r_index);
Bill Buzbeea114add2012-05-03 15:00:40 -0700753 else
buzbeefa57c472012-11-21 12:06:18 -0800754 store = NewLIR4(cu, opcode, r_src, rBase, r_index, scale);
buzbee67bf8852011-08-17 17:51:35 -0700755
Bill Buzbeea114add2012-05-03 15:00:40 -0700756 return store;
buzbee67bf8852011-08-17 17:51:35 -0700757}
758
759/*
760 * Load value from base + displacement. Optionally perform null check
buzbeefa57c472012-11-21 12:06:18 -0800761 * on base (which must have an associated s_reg and MIR). If not
buzbee67bf8852011-08-17 17:51:35 -0700762 * performing null check, incoming MIR can be null.
763 */
buzbeefa57c472012-11-21 12:06:18 -0800764LIR* LoadBaseDispBody(CompilationUnit* cu, int rBase,
765 int displacement, int r_dest, int r_dest_hi, OpSize size,
766 int s_reg)
buzbee67bf8852011-08-17 17:51:35 -0700767{
Bill Buzbeea114add2012-05-03 15:00:40 -0700768 LIR* res;
769 LIR* load;
770 ArmOpcode opcode = kThumbBkpt;
buzbeefa57c472012-11-21 12:06:18 -0800771 bool short_form = false;
Bill Buzbeea114add2012-05-03 15:00:40 -0700772 bool thumb2Form = (displacement < 4092 && displacement >= 0);
buzbeefa57c472012-11-21 12:06:18 -0800773 bool all_low_regs = (ARM_LOWREG(rBase) && ARM_LOWREG(r_dest));
774 int encoded_disp = displacement;
Bill Buzbeea114add2012-05-03 15:00:40 -0700775 bool is64bit = false;
776 switch (size) {
777 case kDouble:
778 case kLong:
779 is64bit = true;
buzbeefa57c472012-11-21 12:06:18 -0800780 if (ARM_FPREG(r_dest)) {
781 if (ARM_SINGLEREG(r_dest)) {
782 DCHECK(ARM_FPREG(r_dest_hi));
783 r_dest = S2d(r_dest, r_dest_hi);
Bill Buzbeea114add2012-05-03 15:00:40 -0700784 }
785 opcode = kThumb2Vldrd;
786 if (displacement <= 1020) {
buzbeefa57c472012-11-21 12:06:18 -0800787 short_form = true;
788 encoded_disp >>= 2;
Bill Buzbeea114add2012-05-03 15:00:40 -0700789 }
790 break;
791 } else {
buzbeefa57c472012-11-21 12:06:18 -0800792 res = LoadBaseDispBody(cu, rBase, displacement, r_dest,
793 -1, kWord, s_reg);
794 LoadBaseDispBody(cu, rBase, displacement + 4, r_dest_hi,
Bill Buzbeea114add2012-05-03 15:00:40 -0700795 -1, kWord, INVALID_SREG);
796 return res;
797 }
798 case kSingle:
799 case kWord:
buzbeefa57c472012-11-21 12:06:18 -0800800 if (ARM_FPREG(r_dest)) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700801 opcode = kThumb2Vldrs;
802 if (displacement <= 1020) {
buzbeefa57c472012-11-21 12:06:18 -0800803 short_form = true;
804 encoded_disp >>= 2;
Bill Buzbeea114add2012-05-03 15:00:40 -0700805 }
806 break;
807 }
buzbeefa57c472012-11-21 12:06:18 -0800808 if (ARM_LOWREG(r_dest) && (rBase == r15pc) &&
Bill Buzbeea114add2012-05-03 15:00:40 -0700809 (displacement <= 1020) && (displacement >= 0)) {
buzbeefa57c472012-11-21 12:06:18 -0800810 short_form = true;
811 encoded_disp >>= 2;
Bill Buzbeea114add2012-05-03 15:00:40 -0700812 opcode = kThumbLdrPcRel;
buzbeefa57c472012-11-21 12:06:18 -0800813 } else if (ARM_LOWREG(r_dest) && (rBase == r13sp) &&
Bill Buzbeea114add2012-05-03 15:00:40 -0700814 (displacement <= 1020) && (displacement >= 0)) {
buzbeefa57c472012-11-21 12:06:18 -0800815 short_form = true;
816 encoded_disp >>= 2;
Bill Buzbeea114add2012-05-03 15:00:40 -0700817 opcode = kThumbLdrSpRel;
buzbeefa57c472012-11-21 12:06:18 -0800818 } else if (all_low_regs && displacement < 128 && displacement >= 0) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700819 DCHECK_EQ((displacement & 0x3), 0);
buzbeefa57c472012-11-21 12:06:18 -0800820 short_form = true;
821 encoded_disp >>= 2;
Bill Buzbeea114add2012-05-03 15:00:40 -0700822 opcode = kThumbLdrRRI5;
823 } else if (thumb2Form) {
buzbeefa57c472012-11-21 12:06:18 -0800824 short_form = true;
Bill Buzbeea114add2012-05-03 15:00:40 -0700825 opcode = kThumb2LdrRRI12;
826 }
827 break;
828 case kUnsignedHalf:
buzbeefa57c472012-11-21 12:06:18 -0800829 if (all_low_regs && displacement < 64 && displacement >= 0) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700830 DCHECK_EQ((displacement & 0x1), 0);
buzbeefa57c472012-11-21 12:06:18 -0800831 short_form = true;
832 encoded_disp >>= 1;
Bill Buzbeea114add2012-05-03 15:00:40 -0700833 opcode = kThumbLdrhRRI5;
834 } else if (displacement < 4092 && displacement >= 0) {
buzbeefa57c472012-11-21 12:06:18 -0800835 short_form = true;
Bill Buzbeea114add2012-05-03 15:00:40 -0700836 opcode = kThumb2LdrhRRI12;
837 }
838 break;
839 case kSignedHalf:
840 if (thumb2Form) {
buzbeefa57c472012-11-21 12:06:18 -0800841 short_form = true;
Bill Buzbeea114add2012-05-03 15:00:40 -0700842 opcode = kThumb2LdrshRRI12;
843 }
844 break;
845 case kUnsignedByte:
buzbeefa57c472012-11-21 12:06:18 -0800846 if (all_low_regs && displacement < 32 && displacement >= 0) {
847 short_form = true;
Bill Buzbeea114add2012-05-03 15:00:40 -0700848 opcode = kThumbLdrbRRI5;
849 } else if (thumb2Form) {
buzbeefa57c472012-11-21 12:06:18 -0800850 short_form = true;
Bill Buzbeea114add2012-05-03 15:00:40 -0700851 opcode = kThumb2LdrbRRI12;
852 }
853 break;
854 case kSignedByte:
855 if (thumb2Form) {
buzbeefa57c472012-11-21 12:06:18 -0800856 short_form = true;
Bill Buzbeea114add2012-05-03 15:00:40 -0700857 opcode = kThumb2LdrsbRRI12;
858 }
859 break;
860 default:
buzbeecbd6d442012-11-17 14:11:25 -0800861 LOG(FATAL) << "Bad size: " << size;
Bill Buzbeea114add2012-05-03 15:00:40 -0700862 }
buzbee67bf8852011-08-17 17:51:35 -0700863
buzbeefa57c472012-11-21 12:06:18 -0800864 if (short_form) {
865 load = res = NewLIR3(cu, opcode, r_dest, rBase, encoded_disp);
Bill Buzbeea114add2012-05-03 15:00:40 -0700866 } else {
buzbeefa57c472012-11-21 12:06:18 -0800867 int reg_offset = AllocTemp(cu);
868 res = LoadConstant(cu, reg_offset, encoded_disp);
869 load = LoadBaseIndexed(cu, rBase, reg_offset, r_dest, 0, size);
870 FreeTemp(cu, reg_offset);
Bill Buzbeea114add2012-05-03 15:00:40 -0700871 }
buzbee67bf8852011-08-17 17:51:35 -0700872
Bill Buzbeea114add2012-05-03 15:00:40 -0700873 // TODO: in future may need to differentiate Dalvik accesses w/ spills
buzbeef0504cd2012-11-13 16:31:10 -0800874 if (rBase == rARM_SP) {
buzbeefa57c472012-11-21 12:06:18 -0800875 AnnotateDalvikRegAccess(load, displacement >> 2, true /* is_load */, is64bit);
Bill Buzbeea114add2012-05-03 15:00:40 -0700876 }
877 return load;
buzbee67bf8852011-08-17 17:51:35 -0700878}
879
buzbeefa57c472012-11-21 12:06:18 -0800880LIR* LoadBaseDisp(CompilationUnit* cu, int rBase,
881 int displacement, int r_dest, OpSize size, int s_reg)
buzbee67bf8852011-08-17 17:51:35 -0700882{
buzbeefa57c472012-11-21 12:06:18 -0800883 return LoadBaseDispBody(cu, rBase, displacement, r_dest, -1, size,
884 s_reg);
buzbee67bf8852011-08-17 17:51:35 -0700885}
886
buzbeefa57c472012-11-21 12:06:18 -0800887 LIR* LoadBaseDispWide(CompilationUnit* cu, int rBase,
888 int displacement, int r_dest_lo, int r_dest_hi, int s_reg)
buzbee67bf8852011-08-17 17:51:35 -0700889{
buzbeefa57c472012-11-21 12:06:18 -0800890 return LoadBaseDispBody(cu, rBase, displacement, r_dest_lo, r_dest_hi,
891 kLong, s_reg);
buzbee67bf8852011-08-17 17:51:35 -0700892}
893
894
buzbeefa57c472012-11-21 12:06:18 -0800895LIR* StoreBaseDispBody(CompilationUnit* cu, int rBase, int displacement,
896 int r_src, int r_src_hi, OpSize size)
buzbee67bf8852011-08-17 17:51:35 -0700897{
Bill Buzbeea114add2012-05-03 15:00:40 -0700898 LIR* res, *store;
899 ArmOpcode opcode = kThumbBkpt;
buzbeefa57c472012-11-21 12:06:18 -0800900 bool short_form = false;
Bill Buzbeea114add2012-05-03 15:00:40 -0700901 bool thumb2Form = (displacement < 4092 && displacement >= 0);
buzbeefa57c472012-11-21 12:06:18 -0800902 bool all_low_regs = (ARM_LOWREG(rBase) && ARM_LOWREG(r_src));
903 int encoded_disp = displacement;
Bill Buzbeea114add2012-05-03 15:00:40 -0700904 bool is64bit = false;
905 switch (size) {
906 case kLong:
907 case kDouble:
908 is64bit = true;
buzbeefa57c472012-11-21 12:06:18 -0800909 if (!ARM_FPREG(r_src)) {
910 res = StoreBaseDispBody(cu, rBase, displacement, r_src, -1, kWord);
911 StoreBaseDispBody(cu, rBase, displacement + 4, r_src_hi, -1, kWord);
Bill Buzbeea114add2012-05-03 15:00:40 -0700912 return res;
913 }
buzbeefa57c472012-11-21 12:06:18 -0800914 if (ARM_SINGLEREG(r_src)) {
915 DCHECK(ARM_FPREG(r_src_hi));
916 r_src = S2d(r_src, r_src_hi);
Bill Buzbeea114add2012-05-03 15:00:40 -0700917 }
918 opcode = kThumb2Vstrd;
919 if (displacement <= 1020) {
buzbeefa57c472012-11-21 12:06:18 -0800920 short_form = true;
921 encoded_disp >>= 2;
Bill Buzbeea114add2012-05-03 15:00:40 -0700922 }
923 break;
924 case kSingle:
925 case kWord:
buzbeefa57c472012-11-21 12:06:18 -0800926 if (ARM_FPREG(r_src)) {
927 DCHECK(ARM_SINGLEREG(r_src));
Bill Buzbeea114add2012-05-03 15:00:40 -0700928 opcode = kThumb2Vstrs;
929 if (displacement <= 1020) {
buzbeefa57c472012-11-21 12:06:18 -0800930 short_form = true;
931 encoded_disp >>= 2;
Bill Buzbeea114add2012-05-03 15:00:40 -0700932 }
933 break;
934 }
buzbeefa57c472012-11-21 12:06:18 -0800935 if (all_low_regs && displacement < 128 && displacement >= 0) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700936 DCHECK_EQ((displacement & 0x3), 0);
buzbeefa57c472012-11-21 12:06:18 -0800937 short_form = true;
938 encoded_disp >>= 2;
Bill Buzbeea114add2012-05-03 15:00:40 -0700939 opcode = kThumbStrRRI5;
940 } else if (thumb2Form) {
buzbeefa57c472012-11-21 12:06:18 -0800941 short_form = true;
Bill Buzbeea114add2012-05-03 15:00:40 -0700942 opcode = kThumb2StrRRI12;
943 }
944 break;
945 case kUnsignedHalf:
946 case kSignedHalf:
buzbeefa57c472012-11-21 12:06:18 -0800947 if (all_low_regs && displacement < 64 && displacement >= 0) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700948 DCHECK_EQ((displacement & 0x1), 0);
buzbeefa57c472012-11-21 12:06:18 -0800949 short_form = true;
950 encoded_disp >>= 1;
Bill Buzbeea114add2012-05-03 15:00:40 -0700951 opcode = kThumbStrhRRI5;
952 } else if (thumb2Form) {
buzbeefa57c472012-11-21 12:06:18 -0800953 short_form = true;
Bill Buzbeea114add2012-05-03 15:00:40 -0700954 opcode = kThumb2StrhRRI12;
955 }
956 break;
957 case kUnsignedByte:
958 case kSignedByte:
buzbeefa57c472012-11-21 12:06:18 -0800959 if (all_low_regs && displacement < 32 && displacement >= 0) {
960 short_form = true;
Bill Buzbeea114add2012-05-03 15:00:40 -0700961 opcode = kThumbStrbRRI5;
962 } else if (thumb2Form) {
buzbeefa57c472012-11-21 12:06:18 -0800963 short_form = true;
Bill Buzbeea114add2012-05-03 15:00:40 -0700964 opcode = kThumb2StrbRRI12;
965 }
966 break;
967 default:
buzbeecbd6d442012-11-17 14:11:25 -0800968 LOG(FATAL) << "Bad size: " << size;
Bill Buzbeea114add2012-05-03 15:00:40 -0700969 }
buzbeefa57c472012-11-21 12:06:18 -0800970 if (short_form) {
971 store = res = NewLIR3(cu, opcode, r_src, rBase, encoded_disp);
Bill Buzbeea114add2012-05-03 15:00:40 -0700972 } else {
buzbeefa57c472012-11-21 12:06:18 -0800973 int r_scratch = AllocTemp(cu);
974 res = LoadConstant(cu, r_scratch, encoded_disp);
975 store = StoreBaseIndexed(cu, rBase, r_scratch, r_src, 0, size);
976 FreeTemp(cu, r_scratch);
Bill Buzbeea114add2012-05-03 15:00:40 -0700977 }
buzbee67bf8852011-08-17 17:51:35 -0700978
Bill Buzbeea114add2012-05-03 15:00:40 -0700979 // TODO: In future, may need to differentiate Dalvik & spill accesses
buzbeef0504cd2012-11-13 16:31:10 -0800980 if (rBase == rARM_SP) {
buzbeefa57c472012-11-21 12:06:18 -0800981 AnnotateDalvikRegAccess(store, displacement >> 2, false /* is_load */,
Bill Buzbeea114add2012-05-03 15:00:40 -0700982 is64bit);
983 }
984 return res;
buzbee67bf8852011-08-17 17:51:35 -0700985}
986
buzbeefa57c472012-11-21 12:06:18 -0800987LIR* StoreBaseDisp(CompilationUnit* cu, int rBase, int displacement,
988 int r_src, OpSize size)
buzbee67bf8852011-08-17 17:51:35 -0700989{
buzbeefa57c472012-11-21 12:06:18 -0800990 return StoreBaseDispBody(cu, rBase, displacement, r_src, -1, size);
buzbee67bf8852011-08-17 17:51:35 -0700991}
992
buzbeefa57c472012-11-21 12:06:18 -0800993LIR* StoreBaseDispWide(CompilationUnit* cu, int rBase, int displacement,
994 int r_src_lo, int r_src_hi)
buzbee67bf8852011-08-17 17:51:35 -0700995{
buzbeefa57c472012-11-21 12:06:18 -0800996 return StoreBaseDispBody(cu, rBase, displacement, r_src_lo, r_src_hi, kLong);
buzbee67bf8852011-08-17 17:51:35 -0700997}
998
buzbeefa57c472012-11-21 12:06:18 -0800999void LoadPair(CompilationUnit* cu, int base, int low_reg, int high_reg)
buzbee67bf8852011-08-17 17:51:35 -07001000{
buzbeefa57c472012-11-21 12:06:18 -08001001 LoadBaseDispWide(cu, base, 0, low_reg, high_reg, INVALID_SREG);
buzbee67bf8852011-08-17 17:51:35 -07001002}
1003
buzbeefa57c472012-11-21 12:06:18 -08001004LIR* FpRegCopy(CompilationUnit* cu, int r_dest, int r_src)
buzbee67bf8852011-08-17 17:51:35 -07001005{
Bill Buzbeea114add2012-05-03 15:00:40 -07001006 int opcode;
buzbeefa57c472012-11-21 12:06:18 -08001007 DCHECK_EQ(ARM_DOUBLEREG(r_dest), ARM_DOUBLEREG(r_src));
1008 if (ARM_DOUBLEREG(r_dest)) {
Bill Buzbeea114add2012-05-03 15:00:40 -07001009 opcode = kThumb2Vmovd;
1010 } else {
buzbeefa57c472012-11-21 12:06:18 -08001011 if (ARM_SINGLEREG(r_dest)) {
1012 opcode = ARM_SINGLEREG(r_src) ? kThumb2Vmovs : kThumb2Fmsr;
buzbeea2ebdd72012-03-04 14:57:06 -08001013 } else {
buzbeefa57c472012-11-21 12:06:18 -08001014 DCHECK(ARM_SINGLEREG(r_src));
Bill Buzbeea114add2012-05-03 15:00:40 -07001015 opcode = kThumb2Fmrs;
buzbeea2ebdd72012-03-04 14:57:06 -08001016 }
Bill Buzbeea114add2012-05-03 15:00:40 -07001017 }
buzbeefa57c472012-11-21 12:06:18 -08001018 LIR* res = RawLIR(cu, cu->current_dalvik_offset, opcode, r_dest, r_src);
1019 if (!(cu->disable_opt & (1 << kSafeOptimizations)) && r_dest == r_src) {
1020 res->flags.is_nop = true;
Bill Buzbeea114add2012-05-03 15:00:40 -07001021 }
1022 return res;
buzbee67bf8852011-08-17 17:51:35 -07001023}
1024
buzbeefa57c472012-11-21 12:06:18 -08001025LIR* OpThreadMem(CompilationUnit* cu, OpKind op, int thread_offset)
buzbeeb046e162012-10-30 15:48:42 -07001026{
buzbee52a77fc2012-11-20 19:50:46 -08001027 LOG(FATAL) << "Unexpected use of OpThreadMem for Arm";
buzbeeb046e162012-10-30 15:48:42 -07001028 return NULL;
1029}
buzbee67bf8852011-08-17 17:51:35 -07001030
buzbeefa57c472012-11-21 12:06:18 -08001031LIR* OpMem(CompilationUnit* cu, OpKind op, int rBase, int disp)
buzbeeb046e162012-10-30 15:48:42 -07001032{
buzbee52a77fc2012-11-20 19:50:46 -08001033 LOG(FATAL) << "Unexpected use of OpMem for Arm";
buzbeeb046e162012-10-30 15:48:42 -07001034 return NULL;
1035}
1036
buzbeefa57c472012-11-21 12:06:18 -08001037LIR* StoreBaseIndexedDisp(CompilationUnit *cu,
1038 int rBase, int r_index, int scale, int displacement,
1039 int r_src, int r_src_hi,
1040 OpSize size, int s_reg)
buzbeeb046e162012-10-30 15:48:42 -07001041{
buzbee52a77fc2012-11-20 19:50:46 -08001042 LOG(FATAL) << "Unexpected use of StoreBaseIndexedDisp for Arm";
buzbeeb046e162012-10-30 15:48:42 -07001043 return NULL;
1044}
1045
buzbeefa57c472012-11-21 12:06:18 -08001046LIR* OpRegMem(CompilationUnit *cu, OpKind op, int r_dest, int rBase,
buzbeeb046e162012-10-30 15:48:42 -07001047 int offset)
1048{
buzbee52a77fc2012-11-20 19:50:46 -08001049 LOG(FATAL) << "Unexpected use of OpRegMem for Arm";
buzbeeb046e162012-10-30 15:48:42 -07001050 return NULL;
1051}
1052
buzbeefa57c472012-11-21 12:06:18 -08001053LIR* LoadBaseIndexedDisp(CompilationUnit *cu,
1054 int rBase, int r_index, int scale, int displacement,
1055 int r_dest, int r_dest_hi,
1056 OpSize size, int s_reg)
buzbeeb046e162012-10-30 15:48:42 -07001057{
buzbee52a77fc2012-11-20 19:50:46 -08001058 LOG(FATAL) << "Unexpected use of LoadBaseIndexedDisp for Arm";
buzbeeb046e162012-10-30 15:48:42 -07001059 return NULL;
1060}
Elliott Hughes11d1b0c2012-01-23 16:57:47 -08001061
1062} // namespace art