blob: aab323b5826a904b87562174c458a72cbb3f85cc [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,
71 *cUnit->dex_file, *cUnit->dex_cache,
72 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 }
Ian Rogers6cbb2bd2012-03-16 13:45:30 -0700127#if !defined(TARGET_X86)
Bill Buzbeea114add2012-05-03 15:00:40 -0700128 opReg(cUnit, kOpBlx, rINVOKE_TGT);
Ian Rogers6cbb2bd2012-03-16 13:45:30 -0700129#else
buzbee15bf9802012-06-12 17:49:27 -0700130 if (fastPath && info->type != kInterface) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700131 opMem(cUnit, kOpBlx, rARG0, Method::GetCodeOffset().Int32Value());
132 } else {
133 int trampoline = 0;
buzbee15bf9802012-06-12 17:49:27 -0700134 switch (info->type) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700135 case kInterface:
136 trampoline = fastPath ? ENTRYPOINT_OFFSET(pInvokeInterfaceTrampoline)
137 : ENTRYPOINT_OFFSET(pInvokeInterfaceTrampolineWithAccessCheck);
138 break;
139 case kDirect:
140 trampoline = ENTRYPOINT_OFFSET(pInvokeDirectTrampolineWithAccessCheck);
141 break;
142 case kStatic:
143 trampoline = ENTRYPOINT_OFFSET(pInvokeStaticTrampolineWithAccessCheck);
144 break;
145 case kSuper:
146 trampoline = ENTRYPOINT_OFFSET(pInvokeSuperTrampolineWithAccessCheck);
147 break;
148 case kVirtual:
149 trampoline = ENTRYPOINT_OFFSET(pInvokeVirtualTrampolineWithAccessCheck);
150 break;
151 default:
152 LOG(FATAL) << "Unexpected invoke type";
Ian Rogers6cbb2bd2012-03-16 13:45:30 -0700153 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700154 opThreadMem(cUnit, kOpBlx, trampoline);
155 }
buzbeea7678db2012-03-05 15:35:46 -0800156#endif
Ian Rogers6cbb2bd2012-03-16 13:45:30 -0700157
Bill Buzbeea114add2012-05-03 15:00:40 -0700158 oatClobberCalleeSave(cUnit);
buzbee15bf9802012-06-12 17:49:27 -0700159 if (info->result.location != kLocInvalid) {
160 // We have a following MOVE_RESULT - do it now.
161 if (info->result.wide) {
buzbee52ed7762012-06-13 23:43:14 -0700162 RegLocation retLoc = oatGetReturnWide(cUnit, info->result.fp);
buzbee15bf9802012-06-12 17:49:27 -0700163 storeValueWide(cUnit, info->result, retLoc);
164 } else {
buzbee52ed7762012-06-13 23:43:14 -0700165 RegLocation retLoc = oatGetReturn(cUnit, info->result.fp);
buzbee15bf9802012-06-12 17:49:27 -0700166 storeValue(cUnit, info->result, retLoc);
167 }
168 }
169}
170
171/*
172 * Build an array of location records for the incoming arguments.
173 * Note: one location record per word of arguments, with dummy
174 * high-word loc for wide arguments. Also pull up any following
175 * MOVE_RESULT and incorporate it into the invoke.
176 */
buzbee6969d502012-06-15 16:40:31 -0700177CallInfo* oatNewCallInfo(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
178 InvokeType type, bool isRange)
buzbee15bf9802012-06-12 17:49:27 -0700179{
buzbee3b3dbdd2012-06-13 13:39:34 -0700180 CallInfo* info = (CallInfo*)oatNew(cUnit, sizeof(CallInfo), true,
buzbee15bf9802012-06-12 17:49:27 -0700181 kAllocMisc);
buzbeee5f01222012-06-14 15:19:35 -0700182//FIXME: Disable fusing for x86
183#if defined(TARGET_X86)
buzbee52ed7762012-06-13 23:43:14 -0700184 info->result.location = kLocInvalid;
185#else
buzbee15bf9802012-06-12 17:49:27 -0700186 MIR* moveResultMIR = oatFindMoveResult(cUnit, bb, mir);
187 if (moveResultMIR == NULL) {
188 info->result.location = kLocInvalid;
189 } else {
190 info->result = oatGetRawDest(cUnit, moveResultMIR);
191 moveResultMIR->dalvikInsn.opcode = Instruction::NOP;
192 }
buzbee52ed7762012-06-13 23:43:14 -0700193#endif
buzbee15bf9802012-06-12 17:49:27 -0700194 info->numArgWords = mir->ssaRep->numUses;
195 info->args = (info->numArgWords == 0) ? NULL : (RegLocation*)
196 oatNew(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc);
197 for (int i = 0; i < info->numArgWords; i++) {
198 info->args[i] = oatGetRawSrc(cUnit, mir, i);
199 }
200 info->optFlags = mir->optimizationFlags;
201 info->type = type;
202 info->isRange = isRange;
buzbee3b3dbdd2012-06-13 13:39:34 -0700203 info->index = mir->dalvikInsn.vB;
buzbee15bf9802012-06-12 17:49:27 -0700204 info->offset = mir->offset;
205 return info;
buzbeee3acd072012-02-25 17:03:10 -0800206}
207
208/*
209 * Target-independent code generation. Use only high-level
210 * load/store utilities here, or target-dependent genXX() handlers
211 * when necessary.
212 */
buzbee31a4a6f2012-02-28 15:36:15 -0800213bool compileDalvikInstruction(CompilationUnit* cUnit, MIR* mir,
214 BasicBlock* bb, LIR* labelList)
buzbeee3acd072012-02-25 17:03:10 -0800215{
Bill Buzbeea114add2012-05-03 15:00:40 -0700216 bool res = false; // Assume success
217 RegLocation rlSrc[3];
218 RegLocation rlDest = badLoc;
219 RegLocation rlResult = badLoc;
220 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbee408ad162012-06-06 16:45:18 -0700221 int optFlags = mir->optimizationFlags;
222 uint32_t vA = mir->dalvikInsn.vA;
223 uint32_t vB = mir->dalvikInsn.vB;
224 uint32_t vC = mir->dalvikInsn.vC;
buzbeee3acd072012-02-25 17:03:10 -0800225
Bill Buzbeea114add2012-05-03 15:00:40 -0700226 /* Prep Src and Dest locations */
227 int nextSreg = 0;
228 int nextLoc = 0;
229 int attrs = oatDataFlowAttributes[opcode];
230 rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
231 if (attrs & DF_UA) {
buzbeebff24652012-05-06 16:22:05 -0700232 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700233 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbeebff24652012-05-06 16:22:05 -0700234 nextSreg+= 2;
235 } else {
236 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
237 nextSreg++;
238 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700239 }
240 if (attrs & DF_UB) {
buzbeebff24652012-05-06 16:22:05 -0700241 if (attrs & DF_B_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700242 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbeebff24652012-05-06 16:22:05 -0700243 nextSreg+= 2;
244 } else {
245 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
246 nextSreg++;
247 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700248 }
249 if (attrs & DF_UC) {
buzbeebff24652012-05-06 16:22:05 -0700250 if (attrs & DF_C_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700251 rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
buzbeebff24652012-05-06 16:22:05 -0700252 } else {
253 rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
254 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700255 }
256 if (attrs & DF_DA) {
buzbeebff24652012-05-06 16:22:05 -0700257 if (attrs & DF_A_WIDE) {
buzbee15bf9802012-06-12 17:49:27 -0700258 rlDest = oatGetDestWide(cUnit, mir);
buzbeebff24652012-05-06 16:22:05 -0700259 } else {
buzbee15bf9802012-06-12 17:49:27 -0700260 rlDest = oatGetDest(cUnit, mir);
buzbeebff24652012-05-06 16:22:05 -0700261 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700262 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700263 switch (opcode) {
264 case Instruction::NOP:
265 break;
buzbeee3acd072012-02-25 17:03:10 -0800266
Bill Buzbeea114add2012-05-03 15:00:40 -0700267 case Instruction::MOVE_EXCEPTION: {
268 int exOffset = Thread::ExceptionOffset().Int32Value();
269 rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
Ian Rogersc6f3bb82012-03-21 20:40:33 -0700270#if defined(TARGET_X86)
Bill Buzbeea114add2012-05-03 15:00:40 -0700271 newLIR2(cUnit, kX86Mov32RT, rlResult.lowReg, exOffset);
272 newLIR2(cUnit, kX86Mov32TI, exOffset, 0);
Ian Rogersc6f3bb82012-03-21 20:40:33 -0700273#else
Bill Buzbeea114add2012-05-03 15:00:40 -0700274 int resetReg = oatAllocTemp(cUnit);
275 loadWordDisp(cUnit, rSELF, exOffset, rlResult.lowReg);
276 loadConstant(cUnit, resetReg, 0);
277 storeWordDisp(cUnit, rSELF, exOffset, resetReg);
Bill Buzbeea114add2012-05-03 15:00:40 -0700278 oatFreeTemp(cUnit, resetReg);
buzbeea7678db2012-03-05 15:35:46 -0800279#endif
jeffhao41005dd2012-05-09 17:58:52 -0700280 storeValue(cUnit, rlDest, rlResult);
Bill Buzbeea114add2012-05-03 15:00:40 -0700281 break;
buzbeee3acd072012-02-25 17:03:10 -0800282 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700283 case Instruction::RETURN_VOID:
284 if (!cUnit->attrs & METHOD_IS_LEAF) {
buzbee408ad162012-06-06 16:45:18 -0700285 genSuspendTest(cUnit, optFlags);
Bill Buzbeea114add2012-05-03 15:00:40 -0700286 }
287 break;
288
289 case Instruction::RETURN:
290 case Instruction::RETURN_OBJECT:
291 if (!cUnit->attrs & METHOD_IS_LEAF) {
buzbee408ad162012-06-06 16:45:18 -0700292 genSuspendTest(cUnit, optFlags);
Bill Buzbeea114add2012-05-03 15:00:40 -0700293 }
294 storeValue(cUnit, oatGetReturn(cUnit, cUnit->shorty[0] == 'F'), rlSrc[0]);
295 break;
296
297 case Instruction::RETURN_WIDE:
298 if (!cUnit->attrs & METHOD_IS_LEAF) {
buzbee408ad162012-06-06 16:45:18 -0700299 genSuspendTest(cUnit, optFlags);
Bill Buzbeea114add2012-05-03 15:00:40 -0700300 }
301 storeValueWide(cUnit, oatGetReturnWide(cUnit,
302 cUnit->shorty[0] == 'D'), rlSrc[0]);
303 break;
304
305 case Instruction::MOVE_RESULT_WIDE:
buzbee408ad162012-06-06 16:45:18 -0700306 if (optFlags & MIR_INLINED)
Bill Buzbeea114add2012-05-03 15:00:40 -0700307 break; // Nop - combined w/ previous invoke
308 storeValueWide(cUnit, rlDest, oatGetReturnWide(cUnit, rlDest.fp));
309 break;
310
311 case Instruction::MOVE_RESULT:
312 case Instruction::MOVE_RESULT_OBJECT:
buzbee408ad162012-06-06 16:45:18 -0700313 if (optFlags & MIR_INLINED)
Bill Buzbeea114add2012-05-03 15:00:40 -0700314 break; // Nop - combined w/ previous invoke
315 storeValue(cUnit, rlDest, oatGetReturn(cUnit, rlDest.fp));
316 break;
317
318 case Instruction::MOVE:
319 case Instruction::MOVE_OBJECT:
320 case Instruction::MOVE_16:
321 case Instruction::MOVE_OBJECT_16:
322 case Instruction::MOVE_FROM16:
323 case Instruction::MOVE_OBJECT_FROM16:
324 storeValue(cUnit, rlDest, rlSrc[0]);
325 break;
326
327 case Instruction::MOVE_WIDE:
328 case Instruction::MOVE_WIDE_16:
329 case Instruction::MOVE_WIDE_FROM16:
330 storeValueWide(cUnit, rlDest, rlSrc[0]);
331 break;
332
333 case Instruction::CONST:
334 case Instruction::CONST_4:
335 case Instruction::CONST_16:
336 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
buzbee408ad162012-06-06 16:45:18 -0700337 loadConstantNoClobber(cUnit, rlResult.lowReg, vB);
Bill Buzbeea114add2012-05-03 15:00:40 -0700338 storeValue(cUnit, rlDest, rlResult);
339 break;
340
341 case Instruction::CONST_HIGH16:
342 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
buzbee408ad162012-06-06 16:45:18 -0700343 loadConstantNoClobber(cUnit, rlResult.lowReg, vB << 16);
Bill Buzbeea114add2012-05-03 15:00:40 -0700344 storeValue(cUnit, rlDest, rlResult);
345 break;
346
347 case Instruction::CONST_WIDE_16:
348 case Instruction::CONST_WIDE_32:
349 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
buzbee408ad162012-06-06 16:45:18 -0700350 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg, vB,
351 (vB & 0x80000000) ? -1 : 0);
Bill Buzbeea114add2012-05-03 15:00:40 -0700352 storeValueWide(cUnit, rlDest, rlResult);
353 break;
354
355 case Instruction::CONST_WIDE:
356 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
357 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
358 mir->dalvikInsn.vB_wide & 0xffffffff,
359 (mir->dalvikInsn.vB_wide >> 32) & 0xffffffff);
360 storeValueWide(cUnit, rlDest, rlResult);
361 break;
362
363 case Instruction::CONST_WIDE_HIGH16:
364 rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
365 loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
buzbee408ad162012-06-06 16:45:18 -0700366 0, vB << 16);
Bill Buzbeea114add2012-05-03 15:00:40 -0700367 storeValueWide(cUnit, rlDest, rlResult);
368 break;
369
370 case Instruction::MONITOR_ENTER:
buzbee408ad162012-06-06 16:45:18 -0700371 genMonitorEnter(cUnit, optFlags, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700372 break;
373
374 case Instruction::MONITOR_EXIT:
buzbee408ad162012-06-06 16:45:18 -0700375 genMonitorExit(cUnit, optFlags, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700376 break;
377
378 case Instruction::CHECK_CAST:
buzbee408ad162012-06-06 16:45:18 -0700379 genCheckCast(cUnit, vB, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700380 break;
381
382 case Instruction::INSTANCE_OF:
buzbee408ad162012-06-06 16:45:18 -0700383 genInstanceof(cUnit, vC, rlDest, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700384 break;
385
386 case Instruction::NEW_INSTANCE:
buzbee408ad162012-06-06 16:45:18 -0700387 genNewInstance(cUnit, vB, rlDest);
Bill Buzbeea114add2012-05-03 15:00:40 -0700388 break;
389
390 case Instruction::THROW:
buzbee408ad162012-06-06 16:45:18 -0700391 genThrow(cUnit, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700392 break;
393
394 case Instruction::THROW_VERIFICATION_ERROR:
buzbee408ad162012-06-06 16:45:18 -0700395 genThrowVerificationError(cUnit, vA, vB);
Bill Buzbeea114add2012-05-03 15:00:40 -0700396 break;
397
398 case Instruction::ARRAY_LENGTH:
399 int lenOffset;
400 lenOffset = Array::LengthOffset().Int32Value();
401 rlSrc[0] = loadValue(cUnit, rlSrc[0], kCoreReg);
buzbee408ad162012-06-06 16:45:18 -0700402 genNullCheck(cUnit, rlSrc[0].sRegLow, rlSrc[0].lowReg, optFlags);
Bill Buzbeea114add2012-05-03 15:00:40 -0700403 rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
404 loadWordDisp(cUnit, rlSrc[0].lowReg, lenOffset, rlResult.lowReg);
405 storeValue(cUnit, rlDest, rlResult);
406 break;
407
408 case Instruction::CONST_STRING:
409 case Instruction::CONST_STRING_JUMBO:
buzbee6969d502012-06-15 16:40:31 -0700410 genConstString(cUnit, vB, rlDest);
Bill Buzbeea114add2012-05-03 15:00:40 -0700411 break;
412
413 case Instruction::CONST_CLASS:
buzbee6969d502012-06-15 16:40:31 -0700414 genConstClass(cUnit, vB, rlDest);
Bill Buzbeea114add2012-05-03 15:00:40 -0700415 break;
416
417 case Instruction::FILL_ARRAY_DATA:
buzbee408ad162012-06-06 16:45:18 -0700418 genFillArrayData(cUnit, vB, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700419 break;
420
421 case Instruction::FILLED_NEW_ARRAY:
buzbee6969d502012-06-15 16:40:31 -0700422 genFilledNewArray(cUnit, oatNewCallInfo(cUnit, bb, mir, kStatic,
buzbee3b3dbdd2012-06-13 13:39:34 -0700423 false /* not range */));
Bill Buzbeea114add2012-05-03 15:00:40 -0700424 break;
425
426 case Instruction::FILLED_NEW_ARRAY_RANGE:
buzbee6969d502012-06-15 16:40:31 -0700427 genFilledNewArray(cUnit, oatNewCallInfo(cUnit, bb, mir, kStatic,
buzbee3b3dbdd2012-06-13 13:39:34 -0700428 true /* range */));
Bill Buzbeea114add2012-05-03 15:00:40 -0700429 break;
430
431 case Instruction::NEW_ARRAY:
buzbee408ad162012-06-06 16:45:18 -0700432 genNewArray(cUnit, vC, rlDest, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700433 break;
434
435 case Instruction::GOTO:
436 case Instruction::GOTO_16:
437 case Instruction::GOTO_32:
438 if (bb->taken->startOffset <= mir->offset) {
buzbee408ad162012-06-06 16:45:18 -0700439 genSuspendTestAndBranch(cUnit, optFlags, &labelList[bb->taken->id]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700440 } else {
441 opUnconditionalBranch(cUnit, &labelList[bb->taken->id]);
442 }
443 break;
444
445 case Instruction::PACKED_SWITCH:
buzbee408ad162012-06-06 16:45:18 -0700446 genPackedSwitch(cUnit, vB, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700447 break;
448
449 case Instruction::SPARSE_SWITCH:
buzbee408ad162012-06-06 16:45:18 -0700450 genSparseSwitch(cUnit, vB, rlSrc[0], labelList);
Bill Buzbeea114add2012-05-03 15:00:40 -0700451 break;
452
453 case Instruction::CMPL_FLOAT:
454 case Instruction::CMPG_FLOAT:
455 case Instruction::CMPL_DOUBLE:
456 case Instruction::CMPG_DOUBLE:
buzbee408ad162012-06-06 16:45:18 -0700457 res = genCmpFP(cUnit, opcode, rlDest, rlSrc[0], rlSrc[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700458 break;
459
460 case Instruction::CMP_LONG:
buzbee408ad162012-06-06 16:45:18 -0700461 genCmpLong(cUnit, rlDest, rlSrc[0], rlSrc[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700462 break;
463
464 case Instruction::IF_EQ:
465 case Instruction::IF_NE:
466 case Instruction::IF_LT:
467 case Instruction::IF_GE:
468 case Instruction::IF_GT:
469 case Instruction::IF_LE: {
buzbee3b3dbdd2012-06-13 13:39:34 -0700470 LIR* taken = &labelList[bb->taken->id];
471 LIR* fallThrough = &labelList[bb->fallThrough->id];
Bill Buzbeea114add2012-05-03 15:00:40 -0700472 bool backwardBranch;
473 backwardBranch = (bb->taken->startOffset <= mir->offset);
474 if (backwardBranch) {
buzbee408ad162012-06-06 16:45:18 -0700475 genSuspendTest(cUnit, optFlags);
Bill Buzbeea114add2012-05-03 15:00:40 -0700476 }
buzbee3b3dbdd2012-06-13 13:39:34 -0700477 genCompareAndBranch(cUnit, opcode, rlSrc[0], rlSrc[1], taken,
478 fallThrough);
Bill Buzbeea114add2012-05-03 15:00:40 -0700479 break;
480 }
481
482 case Instruction::IF_EQZ:
483 case Instruction::IF_NEZ:
484 case Instruction::IF_LTZ:
485 case Instruction::IF_GEZ:
486 case Instruction::IF_GTZ:
487 case Instruction::IF_LEZ: {
buzbee3b3dbdd2012-06-13 13:39:34 -0700488 LIR* taken = &labelList[bb->taken->id];
489 LIR* fallThrough = &labelList[bb->fallThrough->id];
Bill Buzbeea114add2012-05-03 15:00:40 -0700490 bool backwardBranch;
491 backwardBranch = (bb->taken->startOffset <= mir->offset);
492 if (backwardBranch) {
buzbee408ad162012-06-06 16:45:18 -0700493 genSuspendTest(cUnit, optFlags);
Bill Buzbeea114add2012-05-03 15:00:40 -0700494 }
buzbee3b3dbdd2012-06-13 13:39:34 -0700495 genCompareZeroAndBranch(cUnit, opcode, rlSrc[0], taken, fallThrough);
Bill Buzbeea114add2012-05-03 15:00:40 -0700496 break;
497 }
498
499 case Instruction::AGET_WIDE:
buzbee408ad162012-06-06 16:45:18 -0700500 genArrayGet(cUnit, optFlags, kLong, rlSrc[0], rlSrc[1], rlDest, 3);
Bill Buzbeea114add2012-05-03 15:00:40 -0700501 break;
502 case Instruction::AGET:
503 case Instruction::AGET_OBJECT:
buzbee408ad162012-06-06 16:45:18 -0700504 genArrayGet(cUnit, optFlags, kWord, rlSrc[0], rlSrc[1], rlDest, 2);
Bill Buzbeea114add2012-05-03 15:00:40 -0700505 break;
506 case Instruction::AGET_BOOLEAN:
buzbee408ad162012-06-06 16:45:18 -0700507 genArrayGet(cUnit, optFlags, kUnsignedByte, rlSrc[0], rlSrc[1], rlDest, 0);
Bill Buzbeea114add2012-05-03 15:00:40 -0700508 break;
509 case Instruction::AGET_BYTE:
buzbee408ad162012-06-06 16:45:18 -0700510 genArrayGet(cUnit, optFlags, kSignedByte, rlSrc[0], rlSrc[1], rlDest, 0);
Bill Buzbeea114add2012-05-03 15:00:40 -0700511 break;
512 case Instruction::AGET_CHAR:
buzbee408ad162012-06-06 16:45:18 -0700513 genArrayGet(cUnit, optFlags, kUnsignedHalf, rlSrc[0], rlSrc[1], rlDest, 1);
Bill Buzbeea114add2012-05-03 15:00:40 -0700514 break;
515 case Instruction::AGET_SHORT:
buzbee408ad162012-06-06 16:45:18 -0700516 genArrayGet(cUnit, optFlags, kSignedHalf, rlSrc[0], rlSrc[1], rlDest, 1);
Bill Buzbeea114add2012-05-03 15:00:40 -0700517 break;
518 case Instruction::APUT_WIDE:
buzbee408ad162012-06-06 16:45:18 -0700519 genArrayPut(cUnit, optFlags, kLong, rlSrc[1], rlSrc[2], rlSrc[0], 3);
Bill Buzbeea114add2012-05-03 15:00:40 -0700520 break;
521 case Instruction::APUT:
buzbee408ad162012-06-06 16:45:18 -0700522 genArrayPut(cUnit, optFlags, kWord, rlSrc[1], rlSrc[2], rlSrc[0], 2);
Bill Buzbeea114add2012-05-03 15:00:40 -0700523 break;
524 case Instruction::APUT_OBJECT:
buzbee408ad162012-06-06 16:45:18 -0700525 genArrayObjPut(cUnit, optFlags, rlSrc[1], rlSrc[2], rlSrc[0], 2);
Bill Buzbeea114add2012-05-03 15:00:40 -0700526 break;
527 case Instruction::APUT_SHORT:
528 case Instruction::APUT_CHAR:
buzbee408ad162012-06-06 16:45:18 -0700529 genArrayPut(cUnit, optFlags, kUnsignedHalf, rlSrc[1], rlSrc[2], rlSrc[0], 1);
Bill Buzbeea114add2012-05-03 15:00:40 -0700530 break;
531 case Instruction::APUT_BYTE:
532 case Instruction::APUT_BOOLEAN:
buzbee408ad162012-06-06 16:45:18 -0700533 genArrayPut(cUnit, optFlags, kUnsignedByte, rlSrc[1], rlSrc[2],
Bill Buzbeea114add2012-05-03 15:00:40 -0700534 rlSrc[0], 0);
535 break;
536
537 case Instruction::IGET_OBJECT:
538 //case Instruction::IGET_OBJECT_VOLATILE:
buzbee408ad162012-06-06 16:45:18 -0700539 genIGet(cUnit, vC, optFlags, kWord, rlDest, rlSrc[0], false, true);
Bill Buzbeea114add2012-05-03 15:00:40 -0700540 break;
541
542 case Instruction::IGET_WIDE:
543 //case Instruction::IGET_WIDE_VOLATILE:
buzbee408ad162012-06-06 16:45:18 -0700544 genIGet(cUnit, vC, optFlags, kLong, rlDest, rlSrc[0], true, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700545 break;
546
547 case Instruction::IGET:
548 //case Instruction::IGET_VOLATILE:
buzbee408ad162012-06-06 16:45:18 -0700549 genIGet(cUnit, vC, optFlags, kWord, rlDest, rlSrc[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700550 break;
551
552 case Instruction::IGET_CHAR:
buzbee408ad162012-06-06 16:45:18 -0700553 genIGet(cUnit, vC, optFlags, kUnsignedHalf, rlDest, rlSrc[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700554 break;
555
556 case Instruction::IGET_SHORT:
buzbee408ad162012-06-06 16:45:18 -0700557 genIGet(cUnit, vC, optFlags, kSignedHalf, rlDest, rlSrc[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700558 break;
559
560 case Instruction::IGET_BOOLEAN:
561 case Instruction::IGET_BYTE:
buzbee408ad162012-06-06 16:45:18 -0700562 genIGet(cUnit, vC, optFlags, kUnsignedByte, rlDest, rlSrc[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700563 break;
564
565 case Instruction::IPUT_WIDE:
566 //case Instruction::IPUT_WIDE_VOLATILE:
buzbee408ad162012-06-06 16:45:18 -0700567 genIPut(cUnit, vC, optFlags, kLong, rlSrc[0], rlSrc[1], true, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700568 break;
569
570 case Instruction::IPUT_OBJECT:
571 //case Instruction::IPUT_OBJECT_VOLATILE:
buzbee408ad162012-06-06 16:45:18 -0700572 genIPut(cUnit, vC, optFlags, kWord, rlSrc[0], rlSrc[1], false, true);
Bill Buzbeea114add2012-05-03 15:00:40 -0700573 break;
574
575 case Instruction::IPUT:
576 //case Instruction::IPUT_VOLATILE:
buzbee408ad162012-06-06 16:45:18 -0700577 genIPut(cUnit, vC, optFlags, kWord, rlSrc[0], rlSrc[1], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700578 break;
579
580 case Instruction::IPUT_BOOLEAN:
581 case Instruction::IPUT_BYTE:
buzbee408ad162012-06-06 16:45:18 -0700582 genIPut(cUnit, vC, optFlags, kUnsignedByte, rlSrc[0], rlSrc[1], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700583 break;
584
585 case Instruction::IPUT_CHAR:
buzbee408ad162012-06-06 16:45:18 -0700586 genIPut(cUnit, vC, optFlags, kUnsignedHalf, rlSrc[0], rlSrc[1], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700587 break;
588
589 case Instruction::IPUT_SHORT:
buzbee408ad162012-06-06 16:45:18 -0700590 genIPut(cUnit, vC, optFlags, kSignedHalf, rlSrc[0], rlSrc[1], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700591 break;
592
593 case Instruction::SGET_OBJECT:
buzbee408ad162012-06-06 16:45:18 -0700594 genSget(cUnit, vB, rlDest, false, true);
Bill Buzbeea114add2012-05-03 15:00:40 -0700595 break;
596 case Instruction::SGET:
597 case Instruction::SGET_BOOLEAN:
598 case Instruction::SGET_BYTE:
599 case Instruction::SGET_CHAR:
600 case Instruction::SGET_SHORT:
buzbee408ad162012-06-06 16:45:18 -0700601 genSget(cUnit, vB, rlDest, false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700602 break;
603
604 case Instruction::SGET_WIDE:
buzbee408ad162012-06-06 16:45:18 -0700605 genSget(cUnit, vB, rlDest, true, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700606 break;
607
608 case Instruction::SPUT_OBJECT:
buzbee408ad162012-06-06 16:45:18 -0700609 genSput(cUnit, vB, rlSrc[0], false, true);
Bill Buzbeea114add2012-05-03 15:00:40 -0700610 break;
611
612 case Instruction::SPUT:
613 case Instruction::SPUT_BOOLEAN:
614 case Instruction::SPUT_BYTE:
615 case Instruction::SPUT_CHAR:
616 case Instruction::SPUT_SHORT:
buzbee408ad162012-06-06 16:45:18 -0700617 genSput(cUnit, vB, rlSrc[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700618 break;
619
620 case Instruction::SPUT_WIDE:
buzbee408ad162012-06-06 16:45:18 -0700621 genSput(cUnit, vB, rlSrc[0], true, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700622 break;
623
624 case Instruction::INVOKE_STATIC_RANGE:
buzbee6969d502012-06-15 16:40:31 -0700625 genInvoke(cUnit, oatNewCallInfo(cUnit, bb, mir, kStatic, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700626 break;
627 case Instruction::INVOKE_STATIC:
buzbee6969d502012-06-15 16:40:31 -0700628 genInvoke(cUnit, oatNewCallInfo(cUnit, bb, mir, kStatic, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700629 break;
630
631 case Instruction::INVOKE_DIRECT:
buzbee6969d502012-06-15 16:40:31 -0700632 genInvoke(cUnit, oatNewCallInfo(cUnit, bb, mir, kDirect, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700633 break;
634 case Instruction::INVOKE_DIRECT_RANGE:
buzbee6969d502012-06-15 16:40:31 -0700635 genInvoke(cUnit, oatNewCallInfo(cUnit, bb, mir, kDirect, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700636 break;
637
638 case Instruction::INVOKE_VIRTUAL:
buzbee6969d502012-06-15 16:40:31 -0700639 genInvoke(cUnit, oatNewCallInfo(cUnit, bb, mir, kVirtual, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700640 break;
641 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbee6969d502012-06-15 16:40:31 -0700642 genInvoke(cUnit, oatNewCallInfo(cUnit, bb, mir, kVirtual, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700643 break;
644
645 case Instruction::INVOKE_SUPER:
buzbee6969d502012-06-15 16:40:31 -0700646 genInvoke(cUnit, oatNewCallInfo(cUnit, bb, mir, kSuper, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700647 break;
648 case Instruction::INVOKE_SUPER_RANGE:
buzbee6969d502012-06-15 16:40:31 -0700649 genInvoke(cUnit, oatNewCallInfo(cUnit, bb, mir, kSuper, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700650 break;
651
652 case Instruction::INVOKE_INTERFACE:
buzbee6969d502012-06-15 16:40:31 -0700653 genInvoke(cUnit, oatNewCallInfo(cUnit, bb, mir, kInterface, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700654 break;
655 case Instruction::INVOKE_INTERFACE_RANGE:
buzbee6969d502012-06-15 16:40:31 -0700656 genInvoke(cUnit, oatNewCallInfo(cUnit, bb, mir, kInterface, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700657 break;
658
659 case Instruction::NEG_INT:
660 case Instruction::NOT_INT:
buzbee408ad162012-06-06 16:45:18 -0700661 res = genArithOpInt(cUnit, opcode, rlDest, rlSrc[0], rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700662 break;
663
664 case Instruction::NEG_LONG:
665 case Instruction::NOT_LONG:
buzbee408ad162012-06-06 16:45:18 -0700666 res = genArithOpLong(cUnit, opcode, rlDest, rlSrc[0], rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700667 break;
668
669 case Instruction::NEG_FLOAT:
buzbee408ad162012-06-06 16:45:18 -0700670 res = genArithOpFloat(cUnit, opcode, rlDest, rlSrc[0], rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700671 break;
672
673 case Instruction::NEG_DOUBLE:
buzbee408ad162012-06-06 16:45:18 -0700674 res = genArithOpDouble(cUnit, opcode, rlDest, rlSrc[0], rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700675 break;
676
677 case Instruction::INT_TO_LONG:
buzbee408ad162012-06-06 16:45:18 -0700678 genIntToLong(cUnit, rlDest, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700679 break;
680
681 case Instruction::LONG_TO_INT:
682 rlSrc[0] = oatUpdateLocWide(cUnit, rlSrc[0]);
683 rlSrc[0] = oatWideToNarrow(cUnit, rlSrc[0]);
684 storeValue(cUnit, rlDest, rlSrc[0]);
685 break;
686
687 case Instruction::INT_TO_BYTE:
688 case Instruction::INT_TO_SHORT:
689 case Instruction::INT_TO_CHAR:
buzbee408ad162012-06-06 16:45:18 -0700690 genIntNarrowing(cUnit, opcode, rlDest, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700691 break;
692
693 case Instruction::INT_TO_FLOAT:
694 case Instruction::INT_TO_DOUBLE:
695 case Instruction::LONG_TO_FLOAT:
696 case Instruction::LONG_TO_DOUBLE:
697 case Instruction::FLOAT_TO_INT:
698 case Instruction::FLOAT_TO_LONG:
699 case Instruction::FLOAT_TO_DOUBLE:
700 case Instruction::DOUBLE_TO_INT:
701 case Instruction::DOUBLE_TO_LONG:
702 case Instruction::DOUBLE_TO_FLOAT:
buzbee408ad162012-06-06 16:45:18 -0700703 genConversion(cUnit, opcode, rlDest, rlSrc[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700704 break;
705
706 case Instruction::ADD_INT:
707 case Instruction::SUB_INT:
708 case Instruction::MUL_INT:
709 case Instruction::DIV_INT:
710 case Instruction::REM_INT:
711 case Instruction::AND_INT:
712 case Instruction::OR_INT:
713 case Instruction::XOR_INT:
714 case Instruction::SHL_INT:
715 case Instruction::SHR_INT:
716 case Instruction::USHR_INT:
717 case Instruction::ADD_INT_2ADDR:
718 case Instruction::SUB_INT_2ADDR:
719 case Instruction::MUL_INT_2ADDR:
720 case Instruction::DIV_INT_2ADDR:
721 case Instruction::REM_INT_2ADDR:
722 case Instruction::AND_INT_2ADDR:
723 case Instruction::OR_INT_2ADDR:
724 case Instruction::XOR_INT_2ADDR:
725 case Instruction::SHL_INT_2ADDR:
726 case Instruction::SHR_INT_2ADDR:
727 case Instruction::USHR_INT_2ADDR:
buzbee408ad162012-06-06 16:45:18 -0700728 genArithOpInt(cUnit, opcode, rlDest, rlSrc[0], rlSrc[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700729 break;
730
731 case Instruction::ADD_LONG:
732 case Instruction::SUB_LONG:
733 case Instruction::MUL_LONG:
734 case Instruction::DIV_LONG:
735 case Instruction::REM_LONG:
736 case Instruction::AND_LONG:
737 case Instruction::OR_LONG:
738 case Instruction::XOR_LONG:
739 case Instruction::ADD_LONG_2ADDR:
740 case Instruction::SUB_LONG_2ADDR:
741 case Instruction::MUL_LONG_2ADDR:
742 case Instruction::DIV_LONG_2ADDR:
743 case Instruction::REM_LONG_2ADDR:
744 case Instruction::AND_LONG_2ADDR:
745 case Instruction::OR_LONG_2ADDR:
746 case Instruction::XOR_LONG_2ADDR:
buzbee408ad162012-06-06 16:45:18 -0700747 genArithOpLong(cUnit, opcode, rlDest, rlSrc[0], rlSrc[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700748 break;
749
750 case Instruction::SHL_LONG:
751 case Instruction::SHR_LONG:
752 case Instruction::USHR_LONG:
753 case Instruction::SHL_LONG_2ADDR:
754 case Instruction::SHR_LONG_2ADDR:
755 case Instruction::USHR_LONG_2ADDR:
buzbee408ad162012-06-06 16:45:18 -0700756 genShiftOpLong(cUnit, opcode, rlDest, rlSrc[0], rlSrc[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700757 break;
758
759 case Instruction::ADD_FLOAT:
760 case Instruction::SUB_FLOAT:
761 case Instruction::MUL_FLOAT:
762 case Instruction::DIV_FLOAT:
763 case Instruction::REM_FLOAT:
764 case Instruction::ADD_FLOAT_2ADDR:
765 case Instruction::SUB_FLOAT_2ADDR:
766 case Instruction::MUL_FLOAT_2ADDR:
767 case Instruction::DIV_FLOAT_2ADDR:
768 case Instruction::REM_FLOAT_2ADDR:
buzbee408ad162012-06-06 16:45:18 -0700769 genArithOpFloat(cUnit, opcode, rlDest, rlSrc[0], rlSrc[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700770 break;
771
772 case Instruction::ADD_DOUBLE:
773 case Instruction::SUB_DOUBLE:
774 case Instruction::MUL_DOUBLE:
775 case Instruction::DIV_DOUBLE:
776 case Instruction::REM_DOUBLE:
777 case Instruction::ADD_DOUBLE_2ADDR:
778 case Instruction::SUB_DOUBLE_2ADDR:
779 case Instruction::MUL_DOUBLE_2ADDR:
780 case Instruction::DIV_DOUBLE_2ADDR:
781 case Instruction::REM_DOUBLE_2ADDR:
buzbee408ad162012-06-06 16:45:18 -0700782 genArithOpDouble(cUnit, opcode, rlDest, rlSrc[0], rlSrc[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700783 break;
784
785 case Instruction::RSUB_INT:
786 case Instruction::ADD_INT_LIT16:
787 case Instruction::MUL_INT_LIT16:
788 case Instruction::DIV_INT_LIT16:
789 case Instruction::REM_INT_LIT16:
790 case Instruction::AND_INT_LIT16:
791 case Instruction::OR_INT_LIT16:
792 case Instruction::XOR_INT_LIT16:
793 case Instruction::ADD_INT_LIT8:
794 case Instruction::RSUB_INT_LIT8:
795 case Instruction::MUL_INT_LIT8:
796 case Instruction::DIV_INT_LIT8:
797 case Instruction::REM_INT_LIT8:
798 case Instruction::AND_INT_LIT8:
799 case Instruction::OR_INT_LIT8:
800 case Instruction::XOR_INT_LIT8:
801 case Instruction::SHL_INT_LIT8:
802 case Instruction::SHR_INT_LIT8:
803 case Instruction::USHR_INT_LIT8:
buzbee408ad162012-06-06 16:45:18 -0700804 genArithOpIntLit(cUnit, opcode, rlDest, rlSrc[0], vC);
Bill Buzbeea114add2012-05-03 15:00:40 -0700805 break;
806
807 default:
808 res = true;
809 }
810 return res;
buzbeee3acd072012-02-25 17:03:10 -0800811}
812
buzbee31a4a6f2012-02-28 15:36:15 -0800813const char* extendedMIROpNames[kMirOpLast - kMirOpFirst] = {
Bill Buzbeea114add2012-05-03 15:00:40 -0700814 "kMirOpPhi",
815 "kMirOpCopy",
816 "kMirFusedCmplFloat",
817 "kMirFusedCmpgFloat",
818 "kMirFusedCmplDouble",
819 "kMirFusedCmpgDouble",
820 "kMirFusedCmpLong",
821 "kMirNop",
822 "kMirOpNullNRangeUpCheck",
823 "kMirOpNullNRangeDownCheck",
824 "kMirOpLowerBound",
buzbeee3acd072012-02-25 17:03:10 -0800825};
826
827/* Extended MIR instructions like PHI */
buzbee84fd6932012-03-29 16:44:16 -0700828void handleExtendedMethodMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir)
buzbeee3acd072012-02-25 17:03:10 -0800829{
Bill Buzbeea114add2012-05-03 15:00:40 -0700830 int opOffset = mir->dalvikInsn.opcode - kMirOpFirst;
831 char* msg = NULL;
832 if (cUnit->printMe) {
833 msg = (char*)oatNew(cUnit, strlen(extendedMIROpNames[opOffset]) + 1,
834 false, kAllocDebugInfo);
835 strcpy(msg, extendedMIROpNames[opOffset]);
836 }
837 LIR* op = newLIR1(cUnit, kPseudoExtended, (int) msg);
buzbeee3acd072012-02-25 17:03:10 -0800838
Bill Buzbeea114add2012-05-03 15:00:40 -0700839 switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
840 case kMirOpPhi: {
841 char* ssaString = NULL;
842 if (cUnit->printMe) {
843 ssaString = oatGetSSAString(cUnit, mir->ssaRep);
844 }
845 op->flags.isNop = true;
846 newLIR1(cUnit, kPseudoSSARep, (int) ssaString);
847 break;
buzbeee3acd072012-02-25 17:03:10 -0800848 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700849 case kMirOpCopy: {
850 RegLocation rlSrc = oatGetSrc(cUnit, mir, 0);
buzbee15bf9802012-06-12 17:49:27 -0700851 RegLocation rlDest = oatGetDest(cUnit, mir);
Bill Buzbeea114add2012-05-03 15:00:40 -0700852 storeValue(cUnit, rlDest, rlSrc);
853 break;
854 }
855#if defined(TARGET_ARM)
856 case kMirOpFusedCmplFloat:
857 genFusedFPCmpBranch(cUnit, bb, mir, false /*gt bias*/, false /*double*/);
858 break;
859 case kMirOpFusedCmpgFloat:
860 genFusedFPCmpBranch(cUnit, bb, mir, true /*gt bias*/, false /*double*/);
861 break;
862 case kMirOpFusedCmplDouble:
863 genFusedFPCmpBranch(cUnit, bb, mir, false /*gt bias*/, true /*double*/);
864 break;
865 case kMirOpFusedCmpgDouble:
866 genFusedFPCmpBranch(cUnit, bb, mir, true /*gt bias*/, true /*double*/);
867 break;
868 case kMirOpFusedCmpLong:
869 genFusedLongCmpBranch(cUnit, bb, mir);
870 break;
871#endif
872 default:
873 break;
874 }
buzbeee3acd072012-02-25 17:03:10 -0800875}
876
877/* Handle the content in each basic block */
buzbee31a4a6f2012-02-28 15:36:15 -0800878bool methodBlockCodeGen(CompilationUnit* cUnit, BasicBlock* bb)
buzbeee3acd072012-02-25 17:03:10 -0800879{
Bill Buzbeea114add2012-05-03 15:00:40 -0700880 MIR* mir;
881 LIR* labelList = (LIR*) cUnit->blockLabelList;
882 int blockId = bb->id;
buzbeee3acd072012-02-25 17:03:10 -0800883
Bill Buzbeea114add2012-05-03 15:00:40 -0700884 cUnit->curBlock = bb;
885 labelList[blockId].operands[0] = bb->startOffset;
buzbeee3acd072012-02-25 17:03:10 -0800886
Bill Buzbeea114add2012-05-03 15:00:40 -0700887 /* Insert the block label */
888 labelList[blockId].opcode = kPseudoNormalBlockLabel;
889 oatAppendLIR(cUnit, (LIR*) &labelList[blockId]);
buzbeee3acd072012-02-25 17:03:10 -0800890
Bill Buzbeea114add2012-05-03 15:00:40 -0700891 /* Free temp registers and reset redundant store tracking */
892 oatResetRegPool(cUnit);
893 oatResetDefTracking(cUnit);
894
895 /*
896 * If control reached us from our immediate predecessor via
897 * fallthrough and we have no other incoming arcs we can
898 * reuse existing liveness. Otherwise, reset.
899 */
900 if (!bb->fallThroughTarget || bb->predecessors->numUsed != 1) {
901 oatClobberAllRegs(cUnit);
902 }
903
904 LIR* headLIR = NULL;
905
906 if (bb->blockType == kEntryBlock) {
buzbee2cfc6392012-05-07 14:51:40 -0700907 genEntrySequence(cUnit);
Bill Buzbeea114add2012-05-03 15:00:40 -0700908 } else if (bb->blockType == kExitBlock) {
buzbee2cfc6392012-05-07 14:51:40 -0700909 genExitSequence(cUnit);
Bill Buzbeea114add2012-05-03 15:00:40 -0700910 }
911
912 for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
913
buzbeee3acd072012-02-25 17:03:10 -0800914 oatResetRegPool(cUnit);
Bill Buzbeea114add2012-05-03 15:00:40 -0700915 if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
916 oatClobberAllRegs(cUnit);
buzbeee1965672012-03-11 18:39:19 -0700917 }
918
Bill Buzbeea114add2012-05-03 15:00:40 -0700919 if (cUnit->disableOpt & (1 << kSuppressLoads)) {
920 oatResetDefTracking(cUnit);
buzbeee3acd072012-02-25 17:03:10 -0800921 }
922
buzbee3d661942012-03-14 17:37:27 -0700923#ifndef NDEBUG
Bill Buzbeea114add2012-05-03 15:00:40 -0700924 /* Reset temp tracking sanity check */
925 cUnit->liveSReg = INVALID_SREG;
buzbee3d661942012-03-14 17:37:27 -0700926#endif
927
Bill Buzbeea114add2012-05-03 15:00:40 -0700928 cUnit->currentDalvikOffset = mir->offset;
buzbeee3acd072012-02-25 17:03:10 -0800929
Bill Buzbeea114add2012-05-03 15:00:40 -0700930 Instruction::Code dalvikOpcode = mir->dalvikInsn.opcode;
931 Instruction::Format dalvikFormat = Instruction::FormatOf(dalvikOpcode);
buzbeee3acd072012-02-25 17:03:10 -0800932
Bill Buzbeea114add2012-05-03 15:00:40 -0700933 LIR* boundaryLIR;
buzbeee3acd072012-02-25 17:03:10 -0800934
Bill Buzbeea114add2012-05-03 15:00:40 -0700935 /* Mark the beginning of a Dalvik instruction for line tracking */
936 char* instStr = cUnit->printMe ?
937 oatGetDalvikDisassembly(cUnit, mir->dalvikInsn, "") : NULL;
938 boundaryLIR = newLIR1(cUnit, kPseudoDalvikByteCodeBoundary,
939 (intptr_t) instStr);
940 cUnit->boundaryMap.Overwrite(mir->offset, boundaryLIR);
941 /* Remember the first LIR for this block */
942 if (headLIR == NULL) {
943 headLIR = boundaryLIR;
944 /* Set the first boundaryLIR as a scheduling barrier */
945 headLIR->defMask = ENCODE_ALL;
buzbeee3acd072012-02-25 17:03:10 -0800946 }
947
Bill Buzbeea114add2012-05-03 15:00:40 -0700948 /* If we're compiling for the debugger, generate an update callout */
949 if (cUnit->genDebugger) {
950 genDebuggerUpdate(cUnit, mir->offset);
buzbeee3acd072012-02-25 17:03:10 -0800951 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700952
953 /* Don't generate the SSA annotation unless verbose mode is on */
954 if (cUnit->printMe && mir->ssaRep) {
955 char* ssaString = oatGetSSAString(cUnit, mir->ssaRep);
956 newLIR1(cUnit, kPseudoSSARep, (int) ssaString);
957 }
958
959 if ((int)mir->dalvikInsn.opcode >= (int)kMirOpFirst) {
960 handleExtendedMethodMIR(cUnit, bb, mir);
961 continue;
962 }
963
964 bool notHandled = compileDalvikInstruction(cUnit, mir, bb, labelList);
965 if (notHandled) {
966 LOG(FATAL) << StringPrintf("%#06x: Opcode %#x (%s) / Fmt %d not handled",
967 mir->offset, dalvikOpcode,
968 Instruction::Name(dalvikOpcode), dalvikFormat);
969
970 }
971 }
972
973 if (headLIR) {
974 /*
975 * Eliminate redundant loads/stores and delay stores into later
976 * slots
977 */
978 oatApplyLocalOptimizations(cUnit, (LIR*) headLIR, cUnit->lastLIRInsn);
979
980 /*
981 * Generate an unconditional branch to the fallthrough block.
982 */
983 if (bb->fallThrough) {
984 opUnconditionalBranch(cUnit, &labelList[bb->fallThrough->id]);
985 }
986 }
987 return false;
buzbeee3acd072012-02-25 17:03:10 -0800988}
989
buzbee16da88c2012-03-20 10:38:17 -0700990/* Set basic block labels */
991bool labelBlocks(CompilationUnit* cUnit, BasicBlock* bb)
992{
Bill Buzbeea114add2012-05-03 15:00:40 -0700993 LIR* labelList = (LIR*) cUnit->blockLabelList;
994 int blockId = bb->id;
buzbee16da88c2012-03-20 10:38:17 -0700995
Bill Buzbeea114add2012-05-03 15:00:40 -0700996 cUnit->curBlock = bb;
997 labelList[blockId].operands[0] = bb->startOffset;
buzbee16da88c2012-03-20 10:38:17 -0700998
Bill Buzbeea114add2012-05-03 15:00:40 -0700999 /* Insert the block label */
1000 labelList[blockId].opcode = kPseudoNormalBlockLabel;
1001 return false;
buzbee16da88c2012-03-20 10:38:17 -07001002}
1003
1004void oatSpecialMIR2LIR(CompilationUnit* cUnit, SpecialCaseHandler specialCase)
1005{
Bill Buzbeea114add2012-05-03 15:00:40 -07001006 /* Find the first DalvikByteCode block */
1007 int numReachableBlocks = cUnit->numReachableBlocks;
1008 const GrowableList *blockList = &cUnit->blockList;
1009 BasicBlock*bb = NULL;
1010 for (int idx = 0; idx < numReachableBlocks; idx++) {
1011 int dfsIndex = cUnit->dfsOrder.elemList[idx];
1012 bb = (BasicBlock*)oatGrowableListGetElement(blockList, dfsIndex);
1013 if (bb->blockType == kDalvikByteCode) {
1014 break;
buzbee16da88c2012-03-20 10:38:17 -07001015 }
Bill Buzbeea114add2012-05-03 15:00:40 -07001016 }
1017 if (bb == NULL) {
1018 return;
1019 }
1020 DCHECK_EQ(bb->startOffset, 0);
1021 DCHECK(bb->firstMIRInsn != 0);
buzbee16da88c2012-03-20 10:38:17 -07001022
Bill Buzbeea114add2012-05-03 15:00:40 -07001023 /* Get the first instruction */
1024 MIR* mir = bb->firstMIRInsn;
buzbee16da88c2012-03-20 10:38:17 -07001025
Bill Buzbeea114add2012-05-03 15:00:40 -07001026 /* Free temp registers and reset redundant store tracking */
1027 oatResetRegPool(cUnit);
1028 oatResetDefTracking(cUnit);
1029 oatClobberAllRegs(cUnit);
buzbee16da88c2012-03-20 10:38:17 -07001030
Bill Buzbeea114add2012-05-03 15:00:40 -07001031 genSpecialCase(cUnit, bb, mir, specialCase);
buzbee16da88c2012-03-20 10:38:17 -07001032}
1033
buzbeee3acd072012-02-25 17:03:10 -08001034void oatMethodMIR2LIR(CompilationUnit* cUnit)
1035{
Bill Buzbeea114add2012-05-03 15:00:40 -07001036 /* Used to hold the labels of each block */
1037 cUnit->blockLabelList =
1038 (void *) oatNew(cUnit, sizeof(LIR) * cUnit->numBlocks, true, kAllocLIR);
buzbeee3acd072012-02-25 17:03:10 -08001039
Bill Buzbeea114add2012-05-03 15:00:40 -07001040 oatDataFlowAnalysisDispatcher(cUnit, methodBlockCodeGen,
1041 kPreOrderDFSTraversal, false /* Iterative */);
Ian Rogersab2b55d2012-03-18 00:06:11 -07001042
Bill Buzbeea114add2012-05-03 15:00:40 -07001043 handleSuspendLaunchpads(cUnit);
buzbeee3acd072012-02-25 17:03:10 -08001044
Bill Buzbeea114add2012-05-03 15:00:40 -07001045 handleThrowLaunchpads(cUnit);
buzbeee3acd072012-02-25 17:03:10 -08001046
Bill Buzbeea114add2012-05-03 15:00:40 -07001047 handleIntrinsicLaunchpads(cUnit);
buzbeefc9e6fa2012-03-23 15:14:29 -07001048
Bill Buzbeea114add2012-05-03 15:00:40 -07001049 if (!(cUnit->disableOpt & (1 << kSafeOptimizations))) {
1050 removeRedundantBranches(cUnit);
1051 }
buzbeee3acd072012-02-25 17:03:10 -08001052}
1053
1054/* Needed by the ld/st optmizatons */
buzbee31a4a6f2012-02-28 15:36:15 -08001055LIR* oatRegCopyNoInsert(CompilationUnit* cUnit, int rDest, int rSrc)
buzbeee3acd072012-02-25 17:03:10 -08001056{
Bill Buzbeea114add2012-05-03 15:00:40 -07001057 return opRegCopyNoInsert(cUnit, rDest, rSrc);
buzbeee3acd072012-02-25 17:03:10 -08001058}
1059
1060/* Needed by the register allocator */
1061void oatRegCopy(CompilationUnit* cUnit, int rDest, int rSrc)
1062{
Bill Buzbeea114add2012-05-03 15:00:40 -07001063 opRegCopy(cUnit, rDest, rSrc);
buzbeee3acd072012-02-25 17:03:10 -08001064}
1065
1066/* Needed by the register allocator */
1067void oatRegCopyWide(CompilationUnit* cUnit, int destLo, int destHi,
Bill Buzbeea114add2012-05-03 15:00:40 -07001068 int srcLo, int srcHi)
buzbeee3acd072012-02-25 17:03:10 -08001069{
Bill Buzbeea114add2012-05-03 15:00:40 -07001070 opRegCopyWide(cUnit, destLo, destHi, srcLo, srcHi);
buzbeee3acd072012-02-25 17:03:10 -08001071}
1072
1073void oatFlushRegImpl(CompilationUnit* cUnit, int rBase,
Bill Buzbeea114add2012-05-03 15:00:40 -07001074 int displacement, int rSrc, OpSize size)
buzbeee3acd072012-02-25 17:03:10 -08001075{
Bill Buzbeea114add2012-05-03 15:00:40 -07001076 storeBaseDisp(cUnit, rBase, displacement, rSrc, size);
buzbeee3acd072012-02-25 17:03:10 -08001077}
1078
1079void oatFlushRegWideImpl(CompilationUnit* cUnit, int rBase,
Bill Buzbeea114add2012-05-03 15:00:40 -07001080 int displacement, int rSrcLo, int rSrcHi)
buzbeee3acd072012-02-25 17:03:10 -08001081{
Bill Buzbeea114add2012-05-03 15:00:40 -07001082 storeBaseDispWide(cUnit, rBase, displacement, rSrcLo, rSrcHi);
buzbeee3acd072012-02-25 17:03:10 -08001083}
1084
1085} // namespace art