blob: 7d612b04a1e5043661f9d13940750b268f850694 [file] [log] [blame]
buzbeee3acd072012-02-25 17:03:10 -08001/*
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
17#include "object_utils.h"
18
19namespace art {
20
21#define DISPLAY_MISSING_TARGETS (cUnit->enableDebug & \
Bill Buzbeea114add2012-05-03 15:00:40 -070022 (1 << kDebugDisplayMissingTargets))
buzbeee3acd072012-02-25 17:03:10 -080023
buzbee2cfc6392012-05-07 14:51:40 -070024const RegLocation badLoc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0,
25 INVALID_REG, INVALID_REG, INVALID_SREG,
26 INVALID_SREG};
buzbeee3acd072012-02-25 17:03:10 -080027
28/* Mark register usage state and return long retloc */
Ian Rogersf7d9ad32012-03-13 18:45:39 -070029RegLocation oatGetReturnWide(CompilationUnit* cUnit, bool isDouble)
buzbeee3acd072012-02-25 17:03:10 -080030{
Bill Buzbeea114add2012-05-03 15:00:40 -070031 RegLocation gpr_res = LOC_C_RETURN_WIDE;
32 RegLocation fpr_res = LOC_C_RETURN_WIDE_DOUBLE;
33 RegLocation res = isDouble ? fpr_res : gpr_res;
34 oatClobber(cUnit, res.lowReg);
35 oatClobber(cUnit, res.highReg);
36 oatLockTemp(cUnit, res.lowReg);
37 oatLockTemp(cUnit, res.highReg);
38 oatMarkPair(cUnit, res.lowReg, res.highReg);
39 return res;
buzbeee3acd072012-02-25 17:03:10 -080040}
41
Ian Rogersf7d9ad32012-03-13 18:45:39 -070042RegLocation oatGetReturn(CompilationUnit* cUnit, bool isFloat)
buzbeee3acd072012-02-25 17:03:10 -080043{
Ian Rogersf7d9ad32012-03-13 18:45:39 -070044 RegLocation gpr_res = LOC_C_RETURN;
45 RegLocation fpr_res = LOC_C_RETURN_FLOAT;
46 RegLocation res = isFloat ? fpr_res : gpr_res;
Bill Buzbeea114add2012-05-03 15:00:40 -070047 oatClobber(cUnit, res.lowReg);
48 if (cUnit->instructionSet == kMips) {
49 oatMarkInUse(cUnit, res.lowReg);
50 } else {
51 oatLockTemp(cUnit, res.lowReg);
52 }
53 return res;
buzbeee3acd072012-02-25 17:03:10 -080054}
55
buzbee3b3dbdd2012-06-13 13:39:34 -070056void genInvoke(CompilationUnit* cUnit, CallInfo* info)
buzbeee3acd072012-02-25 17:03:10 -080057{
buzbee15bf9802012-06-12 17:49:27 -070058 if (genIntrinsic(cUnit, info)) {
Bill Buzbeea114add2012-05-03 15:00:40 -070059 return;
60 }
buzbee15bf9802012-06-12 17:49:27 -070061 InvokeType originalType = info->type; // avoiding mutation by ComputeInvokeInfo
Bill Buzbeea114add2012-05-03 15:00:40 -070062 int callState = 0;
63 LIR* nullCk;
64 LIR** pNullCk = NULL;
65 NextCallInsn nextCallInsn;
66 oatFlushAllRegs(cUnit); /* Everything to home location */
67 // Explicit register usage
68 oatLockCallTemps(cUnit);
buzbeee3acd072012-02-25 17:03:10 -080069
Bill Buzbeea114add2012-05-03 15:00:40 -070070 OatCompilationUnit mUnit(cUnit->class_loader, cUnit->class_linker,
Ian Rogers00f7d0e2012-07-19 15:28:27 -070071 *cUnit->dex_file,
Bill Buzbeea114add2012-05-03 15:00:40 -070072 cUnit->code_item, cUnit->method_idx,
73 cUnit->access_flags);
Logan Chien4dd96f52012-02-29 01:26:58 +080074
buzbee3b3dbdd2012-06-13 13:39:34 -070075 uint32_t dexMethodIdx = info->index;
Bill Buzbeea114add2012-05-03 15:00:40 -070076 int vtableIdx;
77 uintptr_t directCode;
78 uintptr_t directMethod;
79 bool skipThis;
80 bool fastPath =
buzbee15bf9802012-06-12 17:49:27 -070081 cUnit->compiler->ComputeInvokeInfo(dexMethodIdx, &mUnit, info->type,
Bill Buzbeea114add2012-05-03 15:00:40 -070082 vtableIdx, directCode,
83 directMethod)
84 && !SLOW_INVOKE_PATH;
buzbee15bf9802012-06-12 17:49:27 -070085 if (info->type == kInterface) {
Bill Buzbeea114add2012-05-03 15:00:40 -070086 nextCallInsn = fastPath ? nextInterfaceCallInsn
87 : nextInterfaceCallInsnWithAccessCheck;
88 skipThis = false;
buzbee15bf9802012-06-12 17:49:27 -070089 } else if (info->type == kDirect) {
Bill Buzbeea114add2012-05-03 15:00:40 -070090 if (fastPath) {
91 pNullCk = &nullCk;
buzbeee3acd072012-02-25 17:03:10 -080092 }
Bill Buzbeea114add2012-05-03 15:00:40 -070093 nextCallInsn = fastPath ? nextSDCallInsn : nextDirectCallInsnSP;
94 skipThis = false;
buzbee15bf9802012-06-12 17:49:27 -070095 } else if (info->type == kStatic) {
Bill Buzbeea114add2012-05-03 15:00:40 -070096 nextCallInsn = fastPath ? nextSDCallInsn : nextStaticCallInsnSP;
97 skipThis = false;
buzbee15bf9802012-06-12 17:49:27 -070098 } else if (info->type == kSuper) {
Bill Buzbeea114add2012-05-03 15:00:40 -070099 DCHECK(!fastPath); // Fast path is a direct call.
100 nextCallInsn = nextSuperCallInsnSP;
101 skipThis = false;
102 } else {
buzbee15bf9802012-06-12 17:49:27 -0700103 DCHECK_EQ(info->type, kVirtual);
Bill Buzbeea114add2012-05-03 15:00:40 -0700104 nextCallInsn = fastPath ? nextVCallInsn : nextVCallInsnSP;
105 skipThis = fastPath;
106 }
buzbee15bf9802012-06-12 17:49:27 -0700107 if (!info->isRange) {
108 callState = genDalvikArgsNoRange(cUnit, info, callState, pNullCk,
Bill Buzbeea114add2012-05-03 15:00:40 -0700109 nextCallInsn, dexMethodIdx,
110 vtableIdx, directCode, directMethod,
111 originalType, skipThis);
112 } else {
buzbee15bf9802012-06-12 17:49:27 -0700113 callState = genDalvikArgsRange(cUnit, info, callState, pNullCk,
Bill Buzbeea114add2012-05-03 15:00:40 -0700114 nextCallInsn, dexMethodIdx, vtableIdx,
115 directCode, directMethod, originalType,
116 skipThis);
117 }
118 // Finish up any of the call sequence not interleaved in arg loading
119 while (callState >= 0) {
buzbee15bf9802012-06-12 17:49:27 -0700120 callState = nextCallInsn(cUnit, info, callState, dexMethodIdx,
Bill Buzbeea114add2012-05-03 15:00:40 -0700121 vtableIdx, directCode, directMethod,
122 originalType);
123 }
124 if (DISPLAY_MISSING_TARGETS) {
125 genShowTarget(cUnit);
126 }
buzbee8320f382012-09-11 16:29:42 -0700127 LIR* callInst;
Ian Rogers6cbb2bd2012-03-16 13:45:30 -0700128#if !defined(TARGET_X86)
buzbee8320f382012-09-11 16:29:42 -0700129 callInst = opReg(cUnit, kOpBlx, rINVOKE_TGT);
Ian Rogers6cbb2bd2012-03-16 13:45:30 -0700130#else
buzbee15bf9802012-06-12 17:49:27 -0700131 if (fastPath && info->type != kInterface) {
buzbee8320f382012-09-11 16:29:42 -0700132 callInst = opMem(cUnit, kOpBlx, rARG0, Method::GetCodeOffset().Int32Value());
Bill Buzbeea114add2012-05-03 15:00:40 -0700133 } else {
134 int trampoline = 0;
buzbee15bf9802012-06-12 17:49:27 -0700135 switch (info->type) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700136 case kInterface:
137 trampoline = fastPath ? ENTRYPOINT_OFFSET(pInvokeInterfaceTrampoline)
138 : ENTRYPOINT_OFFSET(pInvokeInterfaceTrampolineWithAccessCheck);
139 break;
140 case kDirect:
141 trampoline = ENTRYPOINT_OFFSET(pInvokeDirectTrampolineWithAccessCheck);
142 break;
143 case kStatic:
144 trampoline = ENTRYPOINT_OFFSET(pInvokeStaticTrampolineWithAccessCheck);
145 break;
146 case kSuper:
147 trampoline = ENTRYPOINT_OFFSET(pInvokeSuperTrampolineWithAccessCheck);
148 break;
149 case kVirtual:
150 trampoline = ENTRYPOINT_OFFSET(pInvokeVirtualTrampolineWithAccessCheck);
151 break;
152 default:
153 LOG(FATAL) << "Unexpected invoke type";
Ian Rogers6cbb2bd2012-03-16 13:45:30 -0700154 }
buzbee8320f382012-09-11 16:29:42 -0700155 callInst = opThreadMem(cUnit, kOpBlx, trampoline);
Bill Buzbeea114add2012-05-03 15:00:40 -0700156 }
buzbeea7678db2012-03-05 15:35:46 -0800157#endif
buzbee8320f382012-09-11 16:29:42 -0700158 markSafepointPC(cUnit, callInst);
Ian Rogers6cbb2bd2012-03-16 13:45:30 -0700159
Bill Buzbeea114add2012-05-03 15:00:40 -0700160 oatClobberCalleeSave(cUnit);
buzbee15bf9802012-06-12 17:49:27 -0700161 if (info->result.location != kLocInvalid) {
162 // We have a following MOVE_RESULT - do it now.
163 if (info->result.wide) {
buzbee52ed7762012-06-13 23:43:14 -0700164 RegLocation retLoc = oatGetReturnWide(cUnit, info->result.fp);
buzbee15bf9802012-06-12 17:49:27 -0700165 storeValueWide(cUnit, info->result, retLoc);
166 } else {
buzbee52ed7762012-06-13 23:43:14 -0700167 RegLocation retLoc = oatGetReturn(cUnit, info->result.fp);
buzbee15bf9802012-06-12 17:49:27 -0700168 storeValue(cUnit, info->result, retLoc);
169 }
170 }
171}
172
173/*
174 * Build an array of location records for the incoming arguments.
175 * Note: one location record per word of arguments, with dummy
176 * high-word loc for wide arguments. Also pull up any following
177 * MOVE_RESULT and incorporate it into the invoke.
178 */
buzbee6969d502012-06-15 16:40:31 -0700179CallInfo* oatNewCallInfo(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
180 InvokeType type, bool isRange)
buzbee15bf9802012-06-12 17:49:27 -0700181{
buzbee3b3dbdd2012-06-13 13:39:34 -0700182 CallInfo* info = (CallInfo*)oatNew(cUnit, sizeof(CallInfo), true,
buzbee15bf9802012-06-12 17:49:27 -0700183 kAllocMisc);
184 MIR* moveResultMIR = oatFindMoveResult(cUnit, bb, mir);
185 if (moveResultMIR == NULL) {
186 info->result.location = kLocInvalid;
187 } else {
188 info->result = oatGetRawDest(cUnit, moveResultMIR);
189 moveResultMIR->dalvikInsn.opcode = Instruction::NOP;
190 }
191 info->numArgWords = mir->ssaRep->numUses;
192 info->args = (info->numArgWords == 0) ? NULL : (RegLocation*)
193 oatNew(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc);
194 for (int i = 0; i < info->numArgWords; i++) {
195 info->args[i] = oatGetRawSrc(cUnit, mir, i);
196 }
197 info->optFlags = mir->optimizationFlags;
198 info->type = type;
199 info->isRange = isRange;
buzbee3b3dbdd2012-06-13 13:39:34 -0700200 info->index = mir->dalvikInsn.vB;
buzbee15bf9802012-06-12 17:49:27 -0700201 info->offset = mir->offset;
202 return info;
buzbeee3acd072012-02-25 17:03:10 -0800203}
204
205/*
206 * Target-independent code generation. Use only high-level
207 * load/store utilities here, or target-dependent genXX() handlers
208 * when necessary.
209 */
buzbee31a4a6f2012-02-28 15:36:15 -0800210bool compileDalvikInstruction(CompilationUnit* cUnit, MIR* mir,
211 BasicBlock* bb, LIR* labelList)
buzbeee3acd072012-02-25 17:03:10 -0800212{
Bill Buzbeea114add2012-05-03 15:00:40 -0700213 bool res = false; // Assume success
214 RegLocation rlSrc[3];
215 RegLocation rlDest = badLoc;
216 RegLocation rlResult = badLoc;
217 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbee408ad162012-06-06 16:45:18 -0700218 int optFlags = mir->optimizationFlags;
buzbee408ad162012-06-06 16:45:18 -0700219 uint32_t vB = mir->dalvikInsn.vB;
220 uint32_t vC = mir->dalvikInsn.vC;
buzbeee3acd072012-02-25 17:03:10 -0800221
Bill Buzbeea114add2012-05-03 15:00:40 -0700222 /* Prep Src and Dest locations */
223 int nextSreg = 0;
224 int nextLoc = 0;
225 int attrs = oatDataFlowAttributes[opcode];
226 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
227 if (attrs & DF_UA) {
buzbeebff24652012-05-06 16:22:05 -0700228 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700229 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbeebff24652012-05-06 16:22:05 -0700230 nextSreg+= 2;
231 } else {
232 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
233 nextSreg++;
234 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700235 }
236 if (attrs & DF_UB) {
buzbeebff24652012-05-06 16:22:05 -0700237 if (attrs & DF_B_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700238 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbeebff24652012-05-06 16:22:05 -0700239 nextSreg+= 2;
240 } else {
241 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
242 nextSreg++;
243 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700244 }
245 if (attrs & DF_UC) {
buzbeebff24652012-05-06 16:22:05 -0700246 if (attrs & DF_C_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700247 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbeebff24652012-05-06 16:22:05 -0700248 } else {
249 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
250 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700251 }
252 if (attrs & DF_DA) {
buzbeebff24652012-05-06 16:22:05 -0700253 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700254 rlDest = oatGetDestWide(cUnit, mir);
buzbeebff24652012-05-06 16:22:05 -0700255 } else {
buzbee15bf9802012-06-12 17:49:27 -0700256 rlDest = oatGetDest(cUnit, mir);
buzbeebff24652012-05-06 16:22:05 -0700257 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700258 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700259 switch (opcode) {
260 case Instruction::NOP:
261 break;
buzbeee3acd072012-02-25 17:03:10 -0800262
Bill Buzbeea114add2012-05-03 15:00:40 -0700263 case Instruction::MOVE_EXCEPTION: {
264 int exOffset = Thread::ExceptionOffset().Int32Value();
265 rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
Ian Rogersc6f3bb82012-03-21 20:40:33 -0700266#if defined(TARGET_X86)
Bill Buzbeea114add2012-05-03 15:00:40 -0700267 newLIR2(cUnit, kX86Mov32RT, rlResult.lowReg, exOffset);
268 newLIR2(cUnit, kX86Mov32TI, exOffset, 0);
Ian Rogersc6f3bb82012-03-21 20:40:33 -0700269#else
Bill Buzbeea114add2012-05-03 15:00:40 -0700270 int resetReg = oatAllocTemp(cUnit);
271 loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
272 loadConstant(cUnit, resetReg, 0);
273 storeWordDisp(cUnit, rSELF, exOffset, resetReg);
Bill Buzbeea114add2012-05-03 15:00:40 -0700274 oatFreeTemp(cUnit, resetReg);
buzbeea7678db2012-03-05 15:35:46 -0800275#endif
jeffhao41005dd2012-05-09 17:58:52 -0700276 storeValue(cUnit, rlDest, rlResult);
Bill Buzbeea114add2012-05-03 15:00:40 -0700277 break;
buzbeee3acd072012-02-25 17:03:10 -0800278 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700279 case Instruction::RETURN_VOID:
TDYa1274f2935e2012-06-22 06:25:03 -0700280 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee408ad162012-06-06 16:45:18 -0700281 genSuspendTest(cUnit, optFlags);
Bill Buzbeea114add2012-05-03 15:00:40 -0700282 }
283 break;
284
285 case Instruction::RETURN:
286 case Instruction::RETURN_OBJECT:
TDYa1274f2935e2012-06-22 06:25:03 -0700287 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee408ad162012-06-06 16:45:18 -0700288 genSuspendTest(cUnit, optFlags);
Bill Buzbeea114add2012-05-03 15:00:40 -0700289 }
290 storeValue(cUnit, oatGetReturn(cUnit, cUnit->shorty[0] == 'F'), rlSrc[0]);
291 break;
292
293 case Instruction::RETURN_WIDE:
TDYa1274f2935e2012-06-22 06:25:03 -0700294 if (!(cUnit->attrs & METHOD_IS_LEAF)) {
buzbee408ad162012-06-06 16:45:18 -0700295 genSuspendTest(cUnit, optFlags);
Bill Buzbeea114add2012-05-03 15:00:40 -0700296 }
297 storeValueWide(cUnit, oatGetReturnWide(cUnit,
298 cUnit->shorty[0] == 'D'), rlSrc[0]);
299 break;
300
301 case Instruction::MOVE_RESULT_WIDE:
buzbee408ad162012-06-06 16:45:18 -0700302 if (optFlags & MIR_INLINED)
Bill Buzbeea114add2012-05-03 15:00:40 -0700303 break; // Nop - combined w/ previous invoke
304 storeValueWide(cUnit, rlDest, oatGetReturnWide(cUnit, rlDest.fp));
305 break;
306
307 case Instruction::MOVE_RESULT:
308 case Instruction::MOVE_RESULT_OBJECT:
buzbee408ad162012-06-06 16:45:18 -0700309 if (optFlags & MIR_INLINED)
Bill Buzbeea114add2012-05-03 15:00:40 -0700310 break; // Nop - combined w/ previous invoke
311 storeValue(cUnit, rlDest, oatGetReturn(cUnit, rlDest.fp));
312 break;
313
314 case Instruction::MOVE:
315 case Instruction::MOVE_OBJECT:
316 case Instruction::MOVE_16:
317 case Instruction::MOVE_OBJECT_16:
318 case Instruction::MOVE_FROM16:
319 case Instruction::MOVE_OBJECT_FROM16:
320 storeValue(cUnit, rlDest, rlSrc[0]);
321 break;
322
323 case Instruction::MOVE_WIDE:
324 case Instruction::MOVE_WIDE_16:
325 case Instruction::MOVE_WIDE_FROM16:
326 storeValueWide(cUnit, rlDest, rlSrc[0]);
327 break;
328
329 case Instruction::CONST:
330 case Instruction::CONST_4:
331 case Instruction::CONST_16:
332 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
buzbee408ad162012-06-06 16:45:18 -0700333 loadConstantNoClobber(cUnit, rlResult.lowReg, vB);
Bill Buzbeea114add2012-05-03 15:00:40 -0700334 storeValue(cUnit, rlDest, rlResult);
335 break;
336
337 case Instruction::CONST_HIGH16:
338 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
buzbee408ad162012-06-06 16:45:18 -0700339 loadConstantNoClobber(cUnit, rlResult.lowReg, vB << 16);
Bill Buzbeea114add2012-05-03 15:00:40 -0700340 storeValue(cUnit, rlDest, rlResult);
341 break;
342
343 case Instruction::CONST_WIDE_16:
344 case Instruction::CONST_WIDE_32:
345 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
buzbee408ad162012-06-06 16:45:18 -0700346 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg, vB,
347 (vB & 0x80000000) ? -1 : 0);
Bill Buzbeea114add2012-05-03 15:00:40 -0700348 storeValueWide(cUnit, rlDest, rlResult);
349 break;
350
351 case Instruction::CONST_WIDE:
352 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
353 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
354 mir->dalvikInsn.vB_wide & 0xffffffff,
355 (mir->dalvikInsn.vB_wide >> 32) & 0xffffffff);
356 storeValueWide(cUnit, rlDest, rlResult);
357 break;
358
359 case Instruction::CONST_WIDE_HIGH16:
360 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
361 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
buzbee408ad162012-06-06 16:45:18 -0700362 0, vB << 16);
Bill Buzbeea114add2012-05-03 15:00:40 -0700363 storeValueWide(cUnit, rlDest, rlResult);
364 break;
365
366 case Instruction::MONITOR_ENTER:
buzbee408ad162012-06-06 16:45:18 -0700367 genMonitorEnter(cUnit, optFlags, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700368 break;
369
370 case Instruction::MONITOR_EXIT:
buzbee408ad162012-06-06 16:45:18 -0700371 genMonitorExit(cUnit, optFlags, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700372 break;
373
374 case Instruction::CHECK_CAST:
buzbee408ad162012-06-06 16:45:18 -0700375 genCheckCast(cUnit, vB, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700376 break;
377
378 case Instruction::INSTANCE_OF:
buzbee408ad162012-06-06 16:45:18 -0700379 genInstanceof(cUnit, vC, rlDest, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700380 break;
381
382 case Instruction::NEW_INSTANCE:
buzbee408ad162012-06-06 16:45:18 -0700383 genNewInstance(cUnit, vB, rlDest);
Bill Buzbeea114add2012-05-03 15:00:40 -0700384 break;
385
386 case Instruction::THROW:
buzbee408ad162012-06-06 16:45:18 -0700387 genThrow(cUnit, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700388 break;
389
Bill Buzbeea114add2012-05-03 15:00:40 -0700390 case Instruction::ARRAY_LENGTH:
391 int lenOffset;
392 lenOffset = Array::LengthOffset().Int32Value();
393 rlSrc[0] = loadValue(cUnit, rlSrc[0], kCoreReg);
buzbee408ad162012-06-06 16:45:18 -0700394 genNullCheck(cUnit, rlSrc[0].sRegLow, rlSrc[0].lowReg, optFlags);
Bill Buzbeea114add2012-05-03 15:00:40 -0700395 rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
396 loadWordDisp(cUnit, rlSrc[0].lowReg, lenOffset, rlResult.lowReg);
397 storeValue(cUnit, rlDest, rlResult);
398 break;
399
400 case Instruction::CONST_STRING:
401 case Instruction::CONST_STRING_JUMBO:
buzbee6969d502012-06-15 16:40:31 -0700402 genConstString(cUnit, vB, rlDest);
Bill Buzbeea114add2012-05-03 15:00:40 -0700403 break;
404
405 case Instruction::CONST_CLASS:
buzbee6969d502012-06-15 16:40:31 -0700406 genConstClass(cUnit, vB, rlDest);
Bill Buzbeea114add2012-05-03 15:00:40 -0700407 break;
408
409 case Instruction::FILL_ARRAY_DATA:
buzbee408ad162012-06-06 16:45:18 -0700410 genFillArrayData(cUnit, vB, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700411 break;
412
413 case Instruction::FILLED_NEW_ARRAY:
buzbee6969d502012-06-15 16:40:31 -0700414 genFilledNewArray(cUnit, oatNewCallInfo(cUnit, bb, mir, kStatic,
buzbee3b3dbdd2012-06-13 13:39:34 -0700415 false /* not range */));
Bill Buzbeea114add2012-05-03 15:00:40 -0700416 break;
417
418 case Instruction::FILLED_NEW_ARRAY_RANGE:
buzbee6969d502012-06-15 16:40:31 -0700419 genFilledNewArray(cUnit, oatNewCallInfo(cUnit, bb, mir, kStatic,
buzbee3b3dbdd2012-06-13 13:39:34 -0700420 true /* range */));
Bill Buzbeea114add2012-05-03 15:00:40 -0700421 break;
422
423 case Instruction::NEW_ARRAY:
buzbee408ad162012-06-06 16:45:18 -0700424 genNewArray(cUnit, vC, rlDest, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700425 break;
426
427 case Instruction::GOTO:
428 case Instruction::GOTO_16:
429 case Instruction::GOTO_32:
430 if (bb->taken->startOffset <= mir->offset) {
buzbee408ad162012-06-06 16:45:18 -0700431 genSuspendTestAndBranch(cUnit, optFlags, &labelList[bb->taken->id]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700432 } else {
433 opUnconditionalBranch(cUnit, &labelList[bb->taken->id]);
434 }
435 break;
436
437 case Instruction::PACKED_SWITCH:
buzbee408ad162012-06-06 16:45:18 -0700438 genPackedSwitch(cUnit, vB, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700439 break;
440
441 case Instruction::SPARSE_SWITCH:
buzbeea1da8a52012-07-09 14:00:21 -0700442 genSparseSwitch(cUnit, vB, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700443 break;
444
445 case Instruction::CMPL_FLOAT:
446 case Instruction::CMPG_FLOAT:
447 case Instruction::CMPL_DOUBLE:
448 case Instruction::CMPG_DOUBLE:
buzbee408ad162012-06-06 16:45:18 -0700449 res = genCmpFP(cUnit, opcode, rlDest, rlSrc[0], rlSrc[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700450 break;
451
452 case Instruction::CMP_LONG:
buzbee408ad162012-06-06 16:45:18 -0700453 genCmpLong(cUnit, rlDest, rlSrc[0], rlSrc[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700454 break;
455
456 case Instruction::IF_EQ:
457 case Instruction::IF_NE:
458 case Instruction::IF_LT:
459 case Instruction::IF_GE:
460 case Instruction::IF_GT:
461 case Instruction::IF_LE: {
buzbee3b3dbdd2012-06-13 13:39:34 -0700462 LIR* taken = &labelList[bb->taken->id];
463 LIR* fallThrough = &labelList[bb->fallThrough->id];
Bill Buzbeea114add2012-05-03 15:00:40 -0700464 bool backwardBranch;
465 backwardBranch = (bb->taken->startOffset <= mir->offset);
466 if (backwardBranch) {
buzbee408ad162012-06-06 16:45:18 -0700467 genSuspendTest(cUnit, optFlags);
Bill Buzbeea114add2012-05-03 15:00:40 -0700468 }
buzbee3b3dbdd2012-06-13 13:39:34 -0700469 genCompareAndBranch(cUnit, opcode, rlSrc[0], rlSrc[1], taken,
470 fallThrough);
Bill Buzbeea114add2012-05-03 15:00:40 -0700471 break;
472 }
473
474 case Instruction::IF_EQZ:
475 case Instruction::IF_NEZ:
476 case Instruction::IF_LTZ:
477 case Instruction::IF_GEZ:
478 case Instruction::IF_GTZ:
479 case Instruction::IF_LEZ: {
buzbee3b3dbdd2012-06-13 13:39:34 -0700480 LIR* taken = &labelList[bb->taken->id];
481 LIR* fallThrough = &labelList[bb->fallThrough->id];
Bill Buzbeea114add2012-05-03 15:00:40 -0700482 bool backwardBranch;
483 backwardBranch = (bb->taken->startOffset <= mir->offset);
484 if (backwardBranch) {
buzbee408ad162012-06-06 16:45:18 -0700485 genSuspendTest(cUnit, optFlags);
Bill Buzbeea114add2012-05-03 15:00:40 -0700486 }
buzbee3b3dbdd2012-06-13 13:39:34 -0700487 genCompareZeroAndBranch(cUnit, opcode, rlSrc[0], taken, fallThrough);
Bill Buzbeea114add2012-05-03 15:00:40 -0700488 break;
489 }
490
491 case Instruction::AGET_WIDE:
buzbee408ad162012-06-06 16:45:18 -0700492 genArrayGet(cUnit, optFlags, kLong, rlSrc[0], rlSrc[1], rlDest, 3);
Bill Buzbeea114add2012-05-03 15:00:40 -0700493 break;
494 case Instruction::AGET:
495 case Instruction::AGET_OBJECT:
buzbee408ad162012-06-06 16:45:18 -0700496 genArrayGet(cUnit, optFlags, kWord, rlSrc[0], rlSrc[1], rlDest, 2);
Bill Buzbeea114add2012-05-03 15:00:40 -0700497 break;
498 case Instruction::AGET_BOOLEAN:
buzbee408ad162012-06-06 16:45:18 -0700499 genArrayGet(cUnit, optFlags, kUnsignedByte, rlSrc[0], rlSrc[1], rlDest, 0);
Bill Buzbeea114add2012-05-03 15:00:40 -0700500 break;
501 case Instruction::AGET_BYTE:
buzbee408ad162012-06-06 16:45:18 -0700502 genArrayGet(cUnit, optFlags, kSignedByte, rlSrc[0], rlSrc[1], rlDest, 0);
Bill Buzbeea114add2012-05-03 15:00:40 -0700503 break;
504 case Instruction::AGET_CHAR:
buzbee408ad162012-06-06 16:45:18 -0700505 genArrayGet(cUnit, optFlags, kUnsignedHalf, rlSrc[0], rlSrc[1], rlDest, 1);
Bill Buzbeea114add2012-05-03 15:00:40 -0700506 break;
507 case Instruction::AGET_SHORT:
buzbee408ad162012-06-06 16:45:18 -0700508 genArrayGet(cUnit, optFlags, kSignedHalf, rlSrc[0], rlSrc[1], rlDest, 1);
Bill Buzbeea114add2012-05-03 15:00:40 -0700509 break;
510 case Instruction::APUT_WIDE:
buzbee408ad162012-06-06 16:45:18 -0700511 genArrayPut(cUnit, optFlags, kLong, rlSrc[1], rlSrc[2], rlSrc[0], 3);
Bill Buzbeea114add2012-05-03 15:00:40 -0700512 break;
513 case Instruction::APUT:
buzbee408ad162012-06-06 16:45:18 -0700514 genArrayPut(cUnit, optFlags, kWord, rlSrc[1], rlSrc[2], rlSrc[0], 2);
Bill Buzbeea114add2012-05-03 15:00:40 -0700515 break;
516 case Instruction::APUT_OBJECT:
buzbee408ad162012-06-06 16:45:18 -0700517 genArrayObjPut(cUnit, optFlags, rlSrc[1], rlSrc[2], rlSrc[0], 2);
Bill Buzbeea114add2012-05-03 15:00:40 -0700518 break;
519 case Instruction::APUT_SHORT:
520 case Instruction::APUT_CHAR:
buzbee408ad162012-06-06 16:45:18 -0700521 genArrayPut(cUnit, optFlags, kUnsignedHalf, rlSrc[1], rlSrc[2], rlSrc[0], 1);
Bill Buzbeea114add2012-05-03 15:00:40 -0700522 break;
523 case Instruction::APUT_BYTE:
524 case Instruction::APUT_BOOLEAN:
buzbee408ad162012-06-06 16:45:18 -0700525 genArrayPut(cUnit, optFlags, kUnsignedByte, rlSrc[1], rlSrc[2],
Bill Buzbeea114add2012-05-03 15:00:40 -0700526 rlSrc[0], 0);
527 break;
528
529 case Instruction::IGET_OBJECT:
530 //case Instruction::IGET_OBJECT_VOLATILE:
buzbee408ad162012-06-06 16:45:18 -0700531 genIGet(cUnit, vC, optFlags, kWord, rlDest, rlSrc[0], false, true);
Bill Buzbeea114add2012-05-03 15:00:40 -0700532 break;
533
534 case Instruction::IGET_WIDE:
535 //case Instruction::IGET_WIDE_VOLATILE:
buzbee408ad162012-06-06 16:45:18 -0700536 genIGet(cUnit, vC, optFlags, kLong, rlDest, rlSrc[0], true, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700537 break;
538
539 case Instruction::IGET:
540 //case Instruction::IGET_VOLATILE:
buzbee408ad162012-06-06 16:45:18 -0700541 genIGet(cUnit, vC, optFlags, kWord, rlDest, rlSrc[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700542 break;
543
544 case Instruction::IGET_CHAR:
buzbee408ad162012-06-06 16:45:18 -0700545 genIGet(cUnit, vC, optFlags, kUnsignedHalf, rlDest, rlSrc[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700546 break;
547
548 case Instruction::IGET_SHORT:
buzbee408ad162012-06-06 16:45:18 -0700549 genIGet(cUnit, vC, optFlags, kSignedHalf, rlDest, rlSrc[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700550 break;
551
552 case Instruction::IGET_BOOLEAN:
553 case Instruction::IGET_BYTE:
buzbee408ad162012-06-06 16:45:18 -0700554 genIGet(cUnit, vC, optFlags, kUnsignedByte, rlDest, rlSrc[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700555 break;
556
557 case Instruction::IPUT_WIDE:
558 //case Instruction::IPUT_WIDE_VOLATILE:
buzbee408ad162012-06-06 16:45:18 -0700559 genIPut(cUnit, vC, optFlags, kLong, rlSrc[0], rlSrc[1], true, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700560 break;
561
562 case Instruction::IPUT_OBJECT:
563 //case Instruction::IPUT_OBJECT_VOLATILE:
buzbee408ad162012-06-06 16:45:18 -0700564 genIPut(cUnit, vC, optFlags, kWord, rlSrc[0], rlSrc[1], false, true);
Bill Buzbeea114add2012-05-03 15:00:40 -0700565 break;
566
567 case Instruction::IPUT:
568 //case Instruction::IPUT_VOLATILE:
buzbee408ad162012-06-06 16:45:18 -0700569 genIPut(cUnit, vC, optFlags, kWord, rlSrc[0], rlSrc[1], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700570 break;
571
572 case Instruction::IPUT_BOOLEAN:
573 case Instruction::IPUT_BYTE:
buzbee408ad162012-06-06 16:45:18 -0700574 genIPut(cUnit, vC, optFlags, kUnsignedByte, rlSrc[0], rlSrc[1], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700575 break;
576
577 case Instruction::IPUT_CHAR:
buzbee408ad162012-06-06 16:45:18 -0700578 genIPut(cUnit, vC, optFlags, kUnsignedHalf, rlSrc[0], rlSrc[1], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700579 break;
580
581 case Instruction::IPUT_SHORT:
buzbee408ad162012-06-06 16:45:18 -0700582 genIPut(cUnit, vC, optFlags, kSignedHalf, rlSrc[0], rlSrc[1], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700583 break;
584
585 case Instruction::SGET_OBJECT:
buzbee408ad162012-06-06 16:45:18 -0700586 genSget(cUnit, vB, rlDest, false, true);
Bill Buzbeea114add2012-05-03 15:00:40 -0700587 break;
588 case Instruction::SGET:
589 case Instruction::SGET_BOOLEAN:
590 case Instruction::SGET_BYTE:
591 case Instruction::SGET_CHAR:
592 case Instruction::SGET_SHORT:
buzbee408ad162012-06-06 16:45:18 -0700593 genSget(cUnit, vB, rlDest, false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700594 break;
595
596 case Instruction::SGET_WIDE:
buzbee408ad162012-06-06 16:45:18 -0700597 genSget(cUnit, vB, rlDest, true, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700598 break;
599
600 case Instruction::SPUT_OBJECT:
buzbee408ad162012-06-06 16:45:18 -0700601 genSput(cUnit, vB, rlSrc[0], false, true);
Bill Buzbeea114add2012-05-03 15:00:40 -0700602 break;
603
604 case Instruction::SPUT:
605 case Instruction::SPUT_BOOLEAN:
606 case Instruction::SPUT_BYTE:
607 case Instruction::SPUT_CHAR:
608 case Instruction::SPUT_SHORT:
buzbee408ad162012-06-06 16:45:18 -0700609 genSput(cUnit, vB, rlSrc[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700610 break;
611
612 case Instruction::SPUT_WIDE:
buzbee408ad162012-06-06 16:45:18 -0700613 genSput(cUnit, vB, rlSrc[0], true, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700614 break;
615
616 case Instruction::INVOKE_STATIC_RANGE:
buzbee6969d502012-06-15 16:40:31 -0700617 genInvoke(cUnit, oatNewCallInfo(cUnit, bb, mir, kStatic, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700618 break;
619 case Instruction::INVOKE_STATIC:
buzbee6969d502012-06-15 16:40:31 -0700620 genInvoke(cUnit, oatNewCallInfo(cUnit, bb, mir, kStatic, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700621 break;
622
623 case Instruction::INVOKE_DIRECT:
buzbee6969d502012-06-15 16:40:31 -0700624 genInvoke(cUnit, oatNewCallInfo(cUnit, bb, mir, kDirect, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700625 break;
626 case Instruction::INVOKE_DIRECT_RANGE:
buzbee6969d502012-06-15 16:40:31 -0700627 genInvoke(cUnit, oatNewCallInfo(cUnit, bb, mir, kDirect, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700628 break;
629
630 case Instruction::INVOKE_VIRTUAL:
buzbee6969d502012-06-15 16:40:31 -0700631 genInvoke(cUnit, oatNewCallInfo(cUnit, bb, mir, kVirtual, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700632 break;
633 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbee6969d502012-06-15 16:40:31 -0700634 genInvoke(cUnit, oatNewCallInfo(cUnit, bb, mir, kVirtual, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700635 break;
636
637 case Instruction::INVOKE_SUPER:
buzbee6969d502012-06-15 16:40:31 -0700638 genInvoke(cUnit, oatNewCallInfo(cUnit, bb, mir, kSuper, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700639 break;
640 case Instruction::INVOKE_SUPER_RANGE:
buzbee6969d502012-06-15 16:40:31 -0700641 genInvoke(cUnit, oatNewCallInfo(cUnit, bb, mir, kSuper, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700642 break;
643
644 case Instruction::INVOKE_INTERFACE:
buzbee6969d502012-06-15 16:40:31 -0700645 genInvoke(cUnit, oatNewCallInfo(cUnit, bb, mir, kInterface, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700646 break;
647 case Instruction::INVOKE_INTERFACE_RANGE:
buzbee6969d502012-06-15 16:40:31 -0700648 genInvoke(cUnit, oatNewCallInfo(cUnit, bb, mir, kInterface, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700649 break;
650
651 case Instruction::NEG_INT:
652 case Instruction::NOT_INT:
buzbee408ad162012-06-06 16:45:18 -0700653 res = genArithOpInt(cUnit, opcode, rlDest, rlSrc[0], rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700654 break;
655
656 case Instruction::NEG_LONG:
657 case Instruction::NOT_LONG:
buzbee408ad162012-06-06 16:45:18 -0700658 res = genArithOpLong(cUnit, opcode, rlDest, rlSrc[0], rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700659 break;
660
661 case Instruction::NEG_FLOAT:
buzbee408ad162012-06-06 16:45:18 -0700662 res = genArithOpFloat(cUnit, opcode, rlDest, rlSrc[0], rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700663 break;
664
665 case Instruction::NEG_DOUBLE:
buzbee408ad162012-06-06 16:45:18 -0700666 res = genArithOpDouble(cUnit, opcode, rlDest, rlSrc[0], rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700667 break;
668
669 case Instruction::INT_TO_LONG:
buzbee408ad162012-06-06 16:45:18 -0700670 genIntToLong(cUnit, rlDest, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700671 break;
672
673 case Instruction::LONG_TO_INT:
674 rlSrc[0] = oatUpdateLocWide(cUnit, rlSrc[0]);
675 rlSrc[0] = oatWideToNarrow(cUnit, rlSrc[0]);
676 storeValue(cUnit, rlDest, rlSrc[0]);
677 break;
678
679 case Instruction::INT_TO_BYTE:
680 case Instruction::INT_TO_SHORT:
681 case Instruction::INT_TO_CHAR:
buzbee408ad162012-06-06 16:45:18 -0700682 genIntNarrowing(cUnit, opcode, rlDest, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700683 break;
684
685 case Instruction::INT_TO_FLOAT:
686 case Instruction::INT_TO_DOUBLE:
687 case Instruction::LONG_TO_FLOAT:
688 case Instruction::LONG_TO_DOUBLE:
689 case Instruction::FLOAT_TO_INT:
690 case Instruction::FLOAT_TO_LONG:
691 case Instruction::FLOAT_TO_DOUBLE:
692 case Instruction::DOUBLE_TO_INT:
693 case Instruction::DOUBLE_TO_LONG:
694 case Instruction::DOUBLE_TO_FLOAT:
buzbee408ad162012-06-06 16:45:18 -0700695 genConversion(cUnit, opcode, rlDest, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700696 break;
697
698 case Instruction::ADD_INT:
699 case Instruction::SUB_INT:
700 case Instruction::MUL_INT:
701 case Instruction::DIV_INT:
702 case Instruction::REM_INT:
703 case Instruction::AND_INT:
704 case Instruction::OR_INT:
705 case Instruction::XOR_INT:
706 case Instruction::SHL_INT:
707 case Instruction::SHR_INT:
708 case Instruction::USHR_INT:
709 case Instruction::ADD_INT_2ADDR:
710 case Instruction::SUB_INT_2ADDR:
711 case Instruction::MUL_INT_2ADDR:
712 case Instruction::DIV_INT_2ADDR:
713 case Instruction::REM_INT_2ADDR:
714 case Instruction::AND_INT_2ADDR:
715 case Instruction::OR_INT_2ADDR:
716 case Instruction::XOR_INT_2ADDR:
717 case Instruction::SHL_INT_2ADDR:
718 case Instruction::SHR_INT_2ADDR:
719 case Instruction::USHR_INT_2ADDR:
buzbee408ad162012-06-06 16:45:18 -0700720 genArithOpInt(cUnit, opcode, rlDest, rlSrc[0], rlSrc[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700721 break;
722
723 case Instruction::ADD_LONG:
724 case Instruction::SUB_LONG:
725 case Instruction::MUL_LONG:
726 case Instruction::DIV_LONG:
727 case Instruction::REM_LONG:
728 case Instruction::AND_LONG:
729 case Instruction::OR_LONG:
730 case Instruction::XOR_LONG:
731 case Instruction::ADD_LONG_2ADDR:
732 case Instruction::SUB_LONG_2ADDR:
733 case Instruction::MUL_LONG_2ADDR:
734 case Instruction::DIV_LONG_2ADDR:
735 case Instruction::REM_LONG_2ADDR:
736 case Instruction::AND_LONG_2ADDR:
737 case Instruction::OR_LONG_2ADDR:
738 case Instruction::XOR_LONG_2ADDR:
buzbee408ad162012-06-06 16:45:18 -0700739 genArithOpLong(cUnit, opcode, rlDest, rlSrc[0], rlSrc[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700740 break;
741
742 case Instruction::SHL_LONG:
743 case Instruction::SHR_LONG:
744 case Instruction::USHR_LONG:
745 case Instruction::SHL_LONG_2ADDR:
746 case Instruction::SHR_LONG_2ADDR:
747 case Instruction::USHR_LONG_2ADDR:
buzbee408ad162012-06-06 16:45:18 -0700748 genShiftOpLong(cUnit, opcode, rlDest, rlSrc[0], rlSrc[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700749 break;
750
751 case Instruction::ADD_FLOAT:
752 case Instruction::SUB_FLOAT:
753 case Instruction::MUL_FLOAT:
754 case Instruction::DIV_FLOAT:
755 case Instruction::REM_FLOAT:
756 case Instruction::ADD_FLOAT_2ADDR:
757 case Instruction::SUB_FLOAT_2ADDR:
758 case Instruction::MUL_FLOAT_2ADDR:
759 case Instruction::DIV_FLOAT_2ADDR:
760 case Instruction::REM_FLOAT_2ADDR:
buzbee408ad162012-06-06 16:45:18 -0700761 genArithOpFloat(cUnit, opcode, rlDest, rlSrc[0], rlSrc[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700762 break;
763
764 case Instruction::ADD_DOUBLE:
765 case Instruction::SUB_DOUBLE:
766 case Instruction::MUL_DOUBLE:
767 case Instruction::DIV_DOUBLE:
768 case Instruction::REM_DOUBLE:
769 case Instruction::ADD_DOUBLE_2ADDR:
770 case Instruction::SUB_DOUBLE_2ADDR:
771 case Instruction::MUL_DOUBLE_2ADDR:
772 case Instruction::DIV_DOUBLE_2ADDR:
773 case Instruction::REM_DOUBLE_2ADDR:
buzbee408ad162012-06-06 16:45:18 -0700774 genArithOpDouble(cUnit, opcode, rlDest, rlSrc[0], rlSrc[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700775 break;
776
777 case Instruction::RSUB_INT:
778 case Instruction::ADD_INT_LIT16:
779 case Instruction::MUL_INT_LIT16:
780 case Instruction::DIV_INT_LIT16:
781 case Instruction::REM_INT_LIT16:
782 case Instruction::AND_INT_LIT16:
783 case Instruction::OR_INT_LIT16:
784 case Instruction::XOR_INT_LIT16:
785 case Instruction::ADD_INT_LIT8:
786 case Instruction::RSUB_INT_LIT8:
787 case Instruction::MUL_INT_LIT8:
788 case Instruction::DIV_INT_LIT8:
789 case Instruction::REM_INT_LIT8:
790 case Instruction::AND_INT_LIT8:
791 case Instruction::OR_INT_LIT8:
792 case Instruction::XOR_INT_LIT8:
793 case Instruction::SHL_INT_LIT8:
794 case Instruction::SHR_INT_LIT8:
795 case Instruction::USHR_INT_LIT8:
buzbee408ad162012-06-06 16:45:18 -0700796 genArithOpIntLit(cUnit, opcode, rlDest, rlSrc[0], vC);
Bill Buzbeea114add2012-05-03 15:00:40 -0700797 break;
798
799 default:
800 res = true;
801 }
802 return res;
buzbeee3acd072012-02-25 17:03:10 -0800803}
804
buzbee31a4a6f2012-02-28 15:36:15 -0800805const char* extendedMIROpNames[kMirOpLast - kMirOpFirst] = {
Bill Buzbeea114add2012-05-03 15:00:40 -0700806 "kMirOpPhi",
807 "kMirOpCopy",
808 "kMirFusedCmplFloat",
809 "kMirFusedCmpgFloat",
810 "kMirFusedCmplDouble",
811 "kMirFusedCmpgDouble",
812 "kMirFusedCmpLong",
813 "kMirNop",
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700814 "kMirOpNullCheck",
815 "kMirOpRangeCheck",
816 "kMirOpDivZeroCheck",
817 "kMirOpCheck",
buzbeee3acd072012-02-25 17:03:10 -0800818};
819
820/* Extended MIR instructions like PHI */
buzbee84fd6932012-03-29 16:44:16 -0700821void handleExtendedMethodMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir)
buzbeee3acd072012-02-25 17:03:10 -0800822{
Bill Buzbeea114add2012-05-03 15:00:40 -0700823 int opOffset = mir->dalvikInsn.opcode - kMirOpFirst;
824 char* msg = NULL;
825 if (cUnit->printMe) {
826 msg = (char*)oatNew(cUnit, strlen(extendedMIROpNames[opOffset]) + 1,
827 false, kAllocDebugInfo);
828 strcpy(msg, extendedMIROpNames[opOffset]);
829 }
830 LIR* op = newLIR1(cUnit, kPseudoExtended, (int) msg);
buzbeee3acd072012-02-25 17:03:10 -0800831
Bill Buzbeea114add2012-05-03 15:00:40 -0700832 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
833 case kMirOpPhi: {
834 char* ssaString = NULL;
835 if (cUnit->printMe) {
836 ssaString = oatGetSSAString(cUnit, mir->ssaRep);
837 }
838 op->flags.isNop = true;
839 newLIR1(cUnit, kPseudoSSARep, (int) ssaString);
840 break;
buzbeee3acd072012-02-25 17:03:10 -0800841 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700842 case kMirOpCopy: {
843 RegLocation rlSrc = oatGetSrc(cUnit, mir, 0);
buzbee15bf9802012-06-12 17:49:27 -0700844 RegLocation rlDest = oatGetDest(cUnit, mir);
Bill Buzbeea114add2012-05-03 15:00:40 -0700845 storeValue(cUnit, rlDest, rlSrc);
846 break;
847 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700848 case kMirOpFusedCmplFloat:
849 genFusedFPCmpBranch(cUnit, bb, mir, false /*gt bias*/, false /*double*/);
850 break;
851 case kMirOpFusedCmpgFloat:
852 genFusedFPCmpBranch(cUnit, bb, mir, true /*gt bias*/, false /*double*/);
853 break;
854 case kMirOpFusedCmplDouble:
855 genFusedFPCmpBranch(cUnit, bb, mir, false /*gt bias*/, true /*double*/);
856 break;
857 case kMirOpFusedCmpgDouble:
858 genFusedFPCmpBranch(cUnit, bb, mir, true /*gt bias*/, true /*double*/);
859 break;
860 case kMirOpFusedCmpLong:
861 genFusedLongCmpBranch(cUnit, bb, mir);
862 break;
Bill Buzbeea114add2012-05-03 15:00:40 -0700863 default:
864 break;
865 }
buzbeee3acd072012-02-25 17:03:10 -0800866}
867
868/* Handle the content in each basic block */
buzbee31a4a6f2012-02-28 15:36:15 -0800869bool methodBlockCodeGen(CompilationUnit* cUnit, BasicBlock* bb)
buzbeee3acd072012-02-25 17:03:10 -0800870{
buzbee488a78c2012-09-10 15:55:34 -0700871 if (bb->blockType == kDead) return false;
buzbee8320f382012-09-11 16:29:42 -0700872 cUnit->currentDalvikOffset = bb->startOffset;
Bill Buzbeea114add2012-05-03 15:00:40 -0700873 MIR* mir;
buzbeea1da8a52012-07-09 14:00:21 -0700874 LIR* labelList = cUnit->blockLabelList;
Bill Buzbeea114add2012-05-03 15:00:40 -0700875 int blockId = bb->id;
buzbeee3acd072012-02-25 17:03:10 -0800876
Bill Buzbeea114add2012-05-03 15:00:40 -0700877 cUnit->curBlock = bb;
878 labelList[blockId].operands[0] = bb->startOffset;
buzbeee3acd072012-02-25 17:03:10 -0800879
Bill Buzbeea114add2012-05-03 15:00:40 -0700880 /* Insert the block label */
881 labelList[blockId].opcode = kPseudoNormalBlockLabel;
882 oatAppendLIR(cUnit, (LIR*) &labelList[blockId]);
buzbeee3acd072012-02-25 17:03:10 -0800883
buzbee8320f382012-09-11 16:29:42 -0700884 LIR* headLIR = NULL;
885
886 /* If this is a catch block, mark the beginning as a safepoint */
887 if (bb->catchEntry) {
888 headLIR = newLIR0(cUnit, kPseudoSafepointPC);
889 }
890
Bill Buzbeea114add2012-05-03 15:00:40 -0700891 /* Free temp registers and reset redundant store tracking */
892 oatResetRegPool(cUnit);
893 oatResetDefTracking(cUnit);
894
buzbeed1643e42012-09-05 14:06:51 -0700895 oatClobberAllRegs(cUnit);
Bill Buzbeea114add2012-05-03 15:00:40 -0700896
Bill Buzbeea114add2012-05-03 15:00:40 -0700897
898 if (bb->blockType == kEntryBlock) {
buzbeead8f15e2012-06-18 14:49:45 -0700899 int startVReg = cUnit->numDalvikRegisters - cUnit->numIns;
900 genEntrySequence(cUnit, &cUnit->regLocation[startVReg],
901 cUnit->regLocation[cUnit->methodSReg]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700902 } else if (bb->blockType == kExitBlock) {
buzbee2cfc6392012-05-07 14:51:40 -0700903 genExitSequence(cUnit);
Bill Buzbeea114add2012-05-03 15:00:40 -0700904 }
905
906 for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
buzbeee3acd072012-02-25 17:03:10 -0800907 oatResetRegPool(cUnit);
Bill Buzbeea114add2012-05-03 15:00:40 -0700908 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
909 oatClobberAllRegs(cUnit);
buzbeee1965672012-03-11 18:39:19 -0700910 }
911
Bill Buzbeea114add2012-05-03 15:00:40 -0700912 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
913 oatResetDefTracking(cUnit);
buzbeee3acd072012-02-25 17:03:10 -0800914 }
915
buzbee3d661942012-03-14 17:37:27 -0700916#ifndef NDEBUG
Bill Buzbeea114add2012-05-03 15:00:40 -0700917 /* Reset temp tracking sanity check */
918 cUnit->liveSReg = INVALID_SREG;
buzbee3d661942012-03-14 17:37:27 -0700919#endif
920
Bill Buzbeea114add2012-05-03 15:00:40 -0700921 cUnit->currentDalvikOffset = mir->offset;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700922 int opcode = mir->dalvikInsn.opcode;
Bill Buzbeea114add2012-05-03 15:00:40 -0700923 LIR* boundaryLIR;
buzbeee3acd072012-02-25 17:03:10 -0800924
Bill Buzbeea114add2012-05-03 15:00:40 -0700925 /* Mark the beginning of a Dalvik instruction for line tracking */
926 char* instStr = cUnit->printMe ?
927 oatGetDalvikDisassembly(cUnit, mir->dalvikInsn, "") : NULL;
buzbeed1643e42012-09-05 14:06:51 -0700928 boundaryLIR = markBoundary(cUnit, mir->offset, instStr);
Bill Buzbeea114add2012-05-03 15:00:40 -0700929 /* Remember the first LIR for this block */
930 if (headLIR == NULL) {
931 headLIR = boundaryLIR;
932 /* Set the first boundaryLIR as a scheduling barrier */
933 headLIR->defMask = ENCODE_ALL;
buzbeee3acd072012-02-25 17:03:10 -0800934 }
935
Bill Buzbeea114add2012-05-03 15:00:40 -0700936 /* If we're compiling for the debugger, generate an update callout */
937 if (cUnit->genDebugger) {
938 genDebuggerUpdate(cUnit, mir->offset);
buzbeee3acd072012-02-25 17:03:10 -0800939 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700940
941 /* Don't generate the SSA annotation unless verbose mode is on */
942 if (cUnit->printMe && mir->ssaRep) {
943 char* ssaString = oatGetSSAString(cUnit, mir->ssaRep);
944 newLIR1(cUnit, kPseudoSSARep, (int) ssaString);
945 }
946
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700947 if (opcode == kMirOpCheck) {
948 // Combine check and work halves of throwing instruction.
949 MIR* workHalf = mir->meta.throwInsn;
950 mir->dalvikInsn.opcode = workHalf->dalvikInsn.opcode;
951 opcode = workHalf->dalvikInsn.opcode;
952 SSARepresentation* ssaRep = workHalf->ssaRep;
953 workHalf->ssaRep = mir->ssaRep;
954 mir->ssaRep = ssaRep;
955 workHalf->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
956 }
957
958 if (opcode >= kMirOpFirst) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700959 handleExtendedMethodMIR(cUnit, bb, mir);
960 continue;
961 }
962
963 bool notHandled = compileDalvikInstruction(cUnit, mir, bb, labelList);
964 if (notHandled) {
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700965 LOG(FATAL) << StringPrintf("%#06x: Opcode %#x (%s)",
966 mir->offset, opcode,
967 Instruction::Name(mir->dalvikInsn.opcode));
Bill Buzbeea114add2012-05-03 15:00:40 -0700968 }
969 }
970
971 if (headLIR) {
972 /*
973 * Eliminate redundant loads/stores and delay stores into later
974 * slots
975 */
976 oatApplyLocalOptimizations(cUnit, (LIR*) headLIR, cUnit->lastLIRInsn);
977
978 /*
979 * Generate an unconditional branch to the fallthrough block.
980 */
981 if (bb->fallThrough) {
982 opUnconditionalBranch(cUnit, &labelList[bb->fallThrough->id]);
983 }
984 }
985 return false;
buzbeee3acd072012-02-25 17:03:10 -0800986}
987
buzbee16da88c2012-03-20 10:38:17 -0700988/* Set basic block labels */
989bool labelBlocks(CompilationUnit* cUnit, BasicBlock* bb)
990{
buzbeea1da8a52012-07-09 14:00:21 -0700991 LIR* labelList = cUnit->blockLabelList;
Bill Buzbeea114add2012-05-03 15:00:40 -0700992 int blockId = bb->id;
buzbee16da88c2012-03-20 10:38:17 -0700993
Bill Buzbeea114add2012-05-03 15:00:40 -0700994 cUnit->curBlock = bb;
995 labelList[blockId].operands[0] = bb->startOffset;
buzbee16da88c2012-03-20 10:38:17 -0700996
Bill Buzbeea114add2012-05-03 15:00:40 -0700997 /* Insert the block label */
998 labelList[blockId].opcode = kPseudoNormalBlockLabel;
999 return false;
buzbee16da88c2012-03-20 10:38:17 -07001000}
1001
1002void oatSpecialMIR2LIR(CompilationUnit* cUnit, SpecialCaseHandler specialCase)
1003{
Bill Buzbeea114add2012-05-03 15:00:40 -07001004 /* Find the first DalvikByteCode block */
1005 int numReachableBlocks = cUnit->numReachableBlocks;
1006 const GrowableList *blockList = &cUnit->blockList;
1007 BasicBlock*bb = NULL;
1008 for (int idx = 0; idx < numReachableBlocks; idx++) {
1009 int dfsIndex = cUnit->dfsOrder.elemList[idx];
1010 bb = (BasicBlock*)oatGrowableListGetElement(blockList, dfsIndex);
1011 if (bb->blockType == kDalvikByteCode) {
1012 break;
buzbee16da88c2012-03-20 10:38:17 -07001013 }
Bill Buzbeea114add2012-05-03 15:00:40 -07001014 }
1015 if (bb == NULL) {
1016 return;
1017 }
1018 DCHECK_EQ(bb->startOffset, 0);
Elliott Hughes74847412012-06-20 18:10:21 -07001019 DCHECK(bb->firstMIRInsn != NULL);
buzbee16da88c2012-03-20 10:38:17 -07001020
Bill Buzbeea114add2012-05-03 15:00:40 -07001021 /* Get the first instruction */
1022 MIR* mir = bb->firstMIRInsn;
buzbee16da88c2012-03-20 10:38:17 -07001023
Bill Buzbeea114add2012-05-03 15:00:40 -07001024 /* Free temp registers and reset redundant store tracking */
1025 oatResetRegPool(cUnit);
1026 oatResetDefTracking(cUnit);
1027 oatClobberAllRegs(cUnit);
buzbee16da88c2012-03-20 10:38:17 -07001028
Bill Buzbeea114add2012-05-03 15:00:40 -07001029 genSpecialCase(cUnit, bb, mir, specialCase);
buzbee16da88c2012-03-20 10:38:17 -07001030}
1031
buzbeee3acd072012-02-25 17:03:10 -08001032void oatMethodMIR2LIR(CompilationUnit* cUnit)
1033{
Bill Buzbeea114add2012-05-03 15:00:40 -07001034 /* Used to hold the labels of each block */
1035 cUnit->blockLabelList =
buzbeea1da8a52012-07-09 14:00:21 -07001036 (LIR*) oatNew(cUnit, sizeof(LIR) * cUnit->numBlocks, true, kAllocLIR);
buzbeee3acd072012-02-25 17:03:10 -08001037
Bill Buzbeea114add2012-05-03 15:00:40 -07001038 oatDataFlowAnalysisDispatcher(cUnit, methodBlockCodeGen,
1039 kPreOrderDFSTraversal, false /* Iterative */);
Ian Rogersab2b55d2012-03-18 00:06:11 -07001040
Bill Buzbeea114add2012-05-03 15:00:40 -07001041 handleSuspendLaunchpads(cUnit);
buzbeee3acd072012-02-25 17:03:10 -08001042
Bill Buzbeea114add2012-05-03 15:00:40 -07001043 handleThrowLaunchpads(cUnit);
buzbeee3acd072012-02-25 17:03:10 -08001044
Bill Buzbeea114add2012-05-03 15:00:40 -07001045 handleIntrinsicLaunchpads(cUnit);
buzbeefc9e6fa2012-03-23 15:14:29 -07001046
Bill Buzbeea114add2012-05-03 15:00:40 -07001047 if (!(cUnit->disableOpt & (1 << kSafeOptimizations))) {
1048 removeRedundantBranches(cUnit);
1049 }
buzbeee3acd072012-02-25 17:03:10 -08001050}
1051
1052/* Needed by the ld/st optmizatons */
buzbee31a4a6f2012-02-28 15:36:15 -08001053LIR* oatRegCopyNoInsert(CompilationUnit* cUnit, int rDest, int rSrc)
buzbeee3acd072012-02-25 17:03:10 -08001054{
Bill Buzbeea114add2012-05-03 15:00:40 -07001055 return opRegCopyNoInsert(cUnit, rDest, rSrc);
buzbeee3acd072012-02-25 17:03:10 -08001056}
1057
1058/* Needed by the register allocator */
1059void oatRegCopy(CompilationUnit* cUnit, int rDest, int rSrc)
1060{
Bill Buzbeea114add2012-05-03 15:00:40 -07001061 opRegCopy(cUnit, rDest, rSrc);
buzbeee3acd072012-02-25 17:03:10 -08001062}
1063
1064/* Needed by the register allocator */
1065void oatRegCopyWide(CompilationUnit* cUnit, int destLo, int destHi,
Bill Buzbeea114add2012-05-03 15:00:40 -07001066 int srcLo, int srcHi)
buzbeee3acd072012-02-25 17:03:10 -08001067{
Bill Buzbeea114add2012-05-03 15:00:40 -07001068 opRegCopyWide(cUnit, destLo, destHi, srcLo, srcHi);
buzbeee3acd072012-02-25 17:03:10 -08001069}
1070
1071void oatFlushRegImpl(CompilationUnit* cUnit, int rBase,
Bill Buzbeea114add2012-05-03 15:00:40 -07001072 int displacement, int rSrc, OpSize size)
buzbeee3acd072012-02-25 17:03:10 -08001073{
Bill Buzbeea114add2012-05-03 15:00:40 -07001074 storeBaseDisp(cUnit, rBase, displacement, rSrc, size);
buzbeee3acd072012-02-25 17:03:10 -08001075}
1076
1077void oatFlushRegWideImpl(CompilationUnit* cUnit, int rBase,
Bill Buzbeea114add2012-05-03 15:00:40 -07001078 int displacement, int rSrcLo, int rSrcHi)
buzbeee3acd072012-02-25 17:03:10 -08001079{
Bill Buzbeea114add2012-05-03 15:00:40 -07001080 storeBaseDispWide(cUnit, rBase, displacement, rSrcLo, rSrcHi);
buzbeee3acd072012-02-25 17:03:10 -08001081}
1082
1083} // namespace art