mir_to_lir.cc revision eaf09bc65f9a10d12befcdb239156938c9bceef2
1e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/*
2e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * Copyright (C) 2011 The Android Open Source Project
3e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee *
4e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * Licensed under the Apache License, Version 2.0 (the "License");
5e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * you may not use this file except in compliance with the License.
6e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * You may obtain a copy of the License at
7e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee *
8e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee *      http://www.apache.org/licenses/LICENSE-2.0
9e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee *
10e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * Unless required by applicable law or agreed to in writing, software
11e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * distributed under the License is distributed on an "AS IS" BASIS,
12e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * See the License for the specific language governing permissions and
14e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * limitations under the License.
15e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee */
16e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
17e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee#include "object_utils.h"
18e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
19eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee#include "local_optimizations.h"
20eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee
21e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbeenamespace art {
22e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
232cfc639fc803bf67e3d2a961f2b637220c86d5f7buzbeeconst RegLocation badLoc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0,
242cfc639fc803bf67e3d2a961f2b637220c86d5f7buzbee                            INVALID_REG, INVALID_REG, INVALID_SREG,
252cfc639fc803bf67e3d2a961f2b637220c86d5f7buzbee                            INVALID_SREG};
26e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
27e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Mark register usage state and return long retloc */
28f7d9ad39541dd09030e26d54d3b73a076f90cc74Ian RogersRegLocation oatGetReturnWide(CompilationUnit* cUnit, bool isDouble)
29e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee{
30f0504cdc5b6400edd4b39eea64ac280465042d5bbuzbee  RegLocation gpr_res = locCReturnWide();
31f0504cdc5b6400edd4b39eea64ac280465042d5bbuzbee  RegLocation fpr_res = locCReturnDouble();
32a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  RegLocation res = isDouble ? fpr_res : gpr_res;
33a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  oatClobber(cUnit, res.lowReg);
34a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  oatClobber(cUnit, res.highReg);
35a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  oatLockTemp(cUnit, res.lowReg);
36a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  oatLockTemp(cUnit, res.highReg);
37a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  oatMarkPair(cUnit, res.lowReg, res.highReg);
38a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  return res;
39e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
40e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
41f7d9ad39541dd09030e26d54d3b73a076f90cc74Ian RogersRegLocation oatGetReturn(CompilationUnit* cUnit, bool isFloat)
42e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee{
43f0504cdc5b6400edd4b39eea64ac280465042d5bbuzbee  RegLocation gpr_res = locCReturn();
44f0504cdc5b6400edd4b39eea64ac280465042d5bbuzbee  RegLocation fpr_res = locCReturnFloat();
45f7d9ad39541dd09030e26d54d3b73a076f90cc74Ian Rogers  RegLocation res = isFloat ? fpr_res : gpr_res;
46a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  oatClobber(cUnit, res.lowReg);
47a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  if (cUnit->instructionSet == kMips) {
48a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    oatMarkInUse(cUnit, res.lowReg);
49a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  } else {
50a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    oatLockTemp(cUnit, res.lowReg);
51a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
52a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  return res;
53e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
54e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
55eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee// TODO: move to gen_invoke.cc
563b3dbddcbc7a7bee505a608061304f9b26a91750buzbeevoid genInvoke(CompilationUnit* cUnit, CallInfo* info)
57e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee{
5815bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee  if (genIntrinsic(cUnit, info)) {
59a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    return;
60a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
6115bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee  InvokeType originalType = info->type;  // avoiding mutation by ComputeInvokeInfo
62a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  int callState = 0;
63a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  LIR* nullCk;
64a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  LIR** pNullCk = NULL;
65a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  NextCallInsn nextCallInsn;
66a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  oatFlushAllRegs(cUnit);  /* Everything to home location */
67a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  // Explicit register usage
68a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  oatLockCallTemps(cUnit);
69a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
70a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  OatCompilationUnit mUnit(cUnit->class_loader, cUnit->class_linker,
7100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                           *cUnit->dex_file,
72a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                           cUnit->code_item, cUnit->method_idx,
73a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                           cUnit->access_flags);
74a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
753b3dbddcbc7a7bee505a608061304f9b26a91750buzbee  uint32_t dexMethodIdx = info->index;
76a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  int vtableIdx;
77a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  uintptr_t directCode;
78a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  uintptr_t directMethod;
79a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  bool skipThis;
80a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  bool fastPath =
8115bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee    cUnit->compiler->ComputeInvokeInfo(dexMethodIdx, &mUnit, info->type,
82a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                                       vtableIdx, directCode,
83a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                                       directMethod)
84a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    && !SLOW_INVOKE_PATH;
8515bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee  if (info->type == kInterface) {
86137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers    if (fastPath) {
87137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers      pNullCk = &nullCk;
88137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers    }
89a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    nextCallInsn = fastPath ? nextInterfaceCallInsn
90137e88f798857321f4007631fdf052d2830ec2c4Ian Rogers                            : nextInterfaceCallInsnWithAccessCheck;
91a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    skipThis = false;
9215bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee  } else if (info->type == kDirect) {
93a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    if (fastPath) {
94a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      pNullCk = &nullCk;
95e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee    }
96a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    nextCallInsn = fastPath ? nextSDCallInsn : nextDirectCallInsnSP;
97a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    skipThis = false;
9815bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee  } else if (info->type == kStatic) {
99a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    nextCallInsn = fastPath ? nextSDCallInsn : nextStaticCallInsnSP;
100a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    skipThis = false;
10115bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee  } else if (info->type == kSuper) {
102a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    DCHECK(!fastPath);  // Fast path is a direct call.
103a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    nextCallInsn = nextSuperCallInsnSP;
104a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    skipThis = false;
105a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  } else {
10615bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee    DCHECK_EQ(info->type, kVirtual);
107a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    nextCallInsn = fastPath ? nextVCallInsn : nextVCallInsnSP;
108a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    skipThis = fastPath;
109a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
11015bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee  if (!info->isRange) {
11115bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee    callState = genDalvikArgsNoRange(cUnit, info, callState, pNullCk,
112a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                                     nextCallInsn, dexMethodIdx,
113a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                                     vtableIdx, directCode, directMethod,
114a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                                     originalType, skipThis);
115a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  } else {
11615bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee    callState = genDalvikArgsRange(cUnit, info, callState, pNullCk,
117a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                                   nextCallInsn, dexMethodIdx, vtableIdx,
118a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                                   directCode, directMethod, originalType,
119a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                                   skipThis);
120a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
121a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  // Finish up any of the call sequence not interleaved in arg loading
122a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  while (callState >= 0) {
12315bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee    callState = nextCallInsn(cUnit, info, callState, dexMethodIdx,
124a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                             vtableIdx, directCode, directMethod,
125a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                             originalType);
126a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
127b046e16d8b8da318d6055f9308950131f1255e08buzbee  if (cUnit->enableDebug & (1 << kDebugDisplayMissingTargets)) {
128a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    genShowTarget(cUnit);
129a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
1308320f3867c02bae9bef6cdab267820cb7b412781buzbee  LIR* callInst;
131b046e16d8b8da318d6055f9308950131f1255e08buzbee  if (cUnit->instructionSet != kX86) {
132f0504cdc5b6400edd4b39eea64ac280465042d5bbuzbee    callInst = opReg(cUnit, kOpBlx, targetReg(kInvokeTgt));
133a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  } else {
134b046e16d8b8da318d6055f9308950131f1255e08buzbee    if (fastPath && info->type != kInterface) {
135f0504cdc5b6400edd4b39eea64ac280465042d5bbuzbee      callInst = opMem(cUnit, kOpBlx, targetReg(kArg0),
136f0504cdc5b6400edd4b39eea64ac280465042d5bbuzbee                       AbstractMethod::GetCodeOffset().Int32Value());
137b046e16d8b8da318d6055f9308950131f1255e08buzbee    } else {
138b046e16d8b8da318d6055f9308950131f1255e08buzbee      int trampoline = 0;
139b046e16d8b8da318d6055f9308950131f1255e08buzbee      switch (info->type) {
140b046e16d8b8da318d6055f9308950131f1255e08buzbee      case kInterface:
141b046e16d8b8da318d6055f9308950131f1255e08buzbee        trampoline = fastPath ? ENTRYPOINT_OFFSET(pInvokeInterfaceTrampoline)
142b046e16d8b8da318d6055f9308950131f1255e08buzbee            : ENTRYPOINT_OFFSET(pInvokeInterfaceTrampolineWithAccessCheck);
143b046e16d8b8da318d6055f9308950131f1255e08buzbee        break;
144b046e16d8b8da318d6055f9308950131f1255e08buzbee      case kDirect:
145b046e16d8b8da318d6055f9308950131f1255e08buzbee        trampoline = ENTRYPOINT_OFFSET(pInvokeDirectTrampolineWithAccessCheck);
146b046e16d8b8da318d6055f9308950131f1255e08buzbee        break;
147b046e16d8b8da318d6055f9308950131f1255e08buzbee      case kStatic:
148b046e16d8b8da318d6055f9308950131f1255e08buzbee        trampoline = ENTRYPOINT_OFFSET(pInvokeStaticTrampolineWithAccessCheck);
149b046e16d8b8da318d6055f9308950131f1255e08buzbee        break;
150b046e16d8b8da318d6055f9308950131f1255e08buzbee      case kSuper:
151b046e16d8b8da318d6055f9308950131f1255e08buzbee        trampoline = ENTRYPOINT_OFFSET(pInvokeSuperTrampolineWithAccessCheck);
152b046e16d8b8da318d6055f9308950131f1255e08buzbee        break;
153b046e16d8b8da318d6055f9308950131f1255e08buzbee      case kVirtual:
154b046e16d8b8da318d6055f9308950131f1255e08buzbee        trampoline = ENTRYPOINT_OFFSET(pInvokeVirtualTrampolineWithAccessCheck);
155b046e16d8b8da318d6055f9308950131f1255e08buzbee        break;
156b046e16d8b8da318d6055f9308950131f1255e08buzbee      default:
157b046e16d8b8da318d6055f9308950131f1255e08buzbee        LOG(FATAL) << "Unexpected invoke type";
158b046e16d8b8da318d6055f9308950131f1255e08buzbee      }
159b046e16d8b8da318d6055f9308950131f1255e08buzbee      callInst = opThreadMem(cUnit, kOpBlx, trampoline);
1606cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers    }
161a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
1628320f3867c02bae9bef6cdab267820cb7b412781buzbee  markSafepointPC(cUnit, callInst);
1636cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers
164a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  oatClobberCalleeSave(cUnit);
16515bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee  if (info->result.location != kLocInvalid) {
16615bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee    // We have a following MOVE_RESULT - do it now.
16715bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee    if (info->result.wide) {
16852ed776c9b71abbdee7c24119859371549bd3172buzbee      RegLocation retLoc = oatGetReturnWide(cUnit, info->result.fp);
16915bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee      storeValueWide(cUnit, info->result, retLoc);
17015bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee    } else {
17152ed776c9b71abbdee7c24119859371549bd3172buzbee      RegLocation retLoc = oatGetReturn(cUnit, info->result.fp);
17215bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee      storeValue(cUnit, info->result, retLoc);
17315bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee    }
17415bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee  }
17515bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee}
17615bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee
17715bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee/*
17815bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee * Build an array of location records for the incoming arguments.
17915bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee * Note: one location record per word of arguments, with dummy
18015bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee * high-word loc for wide arguments.  Also pull up any following
18115bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee * MOVE_RESULT and incorporate it into the invoke.
18215bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee */
183eaf09bc65f9a10d12befcdb239156938c9bceef2buzbee//TODO: move to gen_invoke.cc or utils
1846969d50c820bd63043940b0e0f0ddc6e6ac763b0buzbeeCallInfo* oatNewCallInfo(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
1856969d50c820bd63043940b0e0f0ddc6e6ac763b0buzbee                         InvokeType type, bool isRange)
18615bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee{
1873b3dbddcbc7a7bee505a608061304f9b26a91750buzbee  CallInfo* info = (CallInfo*)oatNew(cUnit, sizeof(CallInfo), true,
18815bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee                                         kAllocMisc);
18915bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee  MIR* moveResultMIR = oatFindMoveResult(cUnit, bb, mir);
19015bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee  if (moveResultMIR == NULL) {
19115bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee    info->result.location = kLocInvalid;
19215bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee  } else {
19315bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee    info->result = oatGetRawDest(cUnit, moveResultMIR);
19415bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee    moveResultMIR->dalvikInsn.opcode = Instruction::NOP;
19515bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee  }
19615bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee  info->numArgWords = mir->ssaRep->numUses;
19715bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee  info->args = (info->numArgWords == 0) ? NULL : (RegLocation*)
19815bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee      oatNew(cUnit, sizeof(RegLocation) * info->numArgWords, false, kAllocMisc);
19915bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee  for (int i = 0; i < info->numArgWords; i++) {
20015bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee    info->args[i] = oatGetRawSrc(cUnit, mir, i);
20115bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee  }
20215bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee  info->optFlags = mir->optimizationFlags;
20315bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee  info->type = type;
20415bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee  info->isRange = isRange;
2053b3dbddcbc7a7bee505a608061304f9b26a91750buzbee  info->index = mir->dalvikInsn.vB;
20615bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee  info->offset = mir->offset;
20715bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee  return info;
208e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
209e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
210e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/*
211e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * Target-independent code generation.  Use only high-level
212e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * load/store utilities here, or target-dependent genXX() handlers
213e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee * when necessary.
214e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee */
21531a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeebool compileDalvikInstruction(CompilationUnit* cUnit, MIR* mir,
21631a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbee                              BasicBlock* bb, LIR* labelList)
217e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee{
218a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  bool res = false;   // Assume success
219a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  RegLocation rlSrc[3];
220a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  RegLocation rlDest = badLoc;
221a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  RegLocation rlResult = badLoc;
222a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  Instruction::Code opcode = mir->dalvikInsn.opcode;
223408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee  int optFlags = mir->optimizationFlags;
224408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee  uint32_t vB = mir->dalvikInsn.vB;
225408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee  uint32_t vC = mir->dalvikInsn.vC;
226a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
227a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /* Prep Src and Dest locations */
228a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  int nextSreg = 0;
229a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  int nextLoc = 0;
230a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  int attrs = oatDataFlowAttributes[opcode];
231a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  rlSrc[0] = rlSrc[1] = rlSrc[2] = badLoc;
232a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  if (attrs & DF_UA) {
233bff2465abb4b0c097623c82f18a1307ea890bff1buzbee    if (attrs & DF_A_WIDE) {
23415bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee      rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
235bff2465abb4b0c097623c82f18a1307ea890bff1buzbee      nextSreg+= 2;
236bff2465abb4b0c097623c82f18a1307ea890bff1buzbee    } else {
237bff2465abb4b0c097623c82f18a1307ea890bff1buzbee      rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
238bff2465abb4b0c097623c82f18a1307ea890bff1buzbee      nextSreg++;
239bff2465abb4b0c097623c82f18a1307ea890bff1buzbee    }
240a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
241a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  if (attrs & DF_UB) {
242bff2465abb4b0c097623c82f18a1307ea890bff1buzbee    if (attrs & DF_B_WIDE) {
24315bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee      rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
244bff2465abb4b0c097623c82f18a1307ea890bff1buzbee      nextSreg+= 2;
245bff2465abb4b0c097623c82f18a1307ea890bff1buzbee    } else {
246bff2465abb4b0c097623c82f18a1307ea890bff1buzbee      rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
247bff2465abb4b0c097623c82f18a1307ea890bff1buzbee      nextSreg++;
248bff2465abb4b0c097623c82f18a1307ea890bff1buzbee    }
249a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
250a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  if (attrs & DF_UC) {
251bff2465abb4b0c097623c82f18a1307ea890bff1buzbee    if (attrs & DF_C_WIDE) {
25215bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee      rlSrc[nextLoc++] = oatGetSrcWide(cUnit, mir, nextSreg);
253bff2465abb4b0c097623c82f18a1307ea890bff1buzbee    } else {
254bff2465abb4b0c097623c82f18a1307ea890bff1buzbee      rlSrc[nextLoc++] = oatGetSrc(cUnit, mir, nextSreg);
255bff2465abb4b0c097623c82f18a1307ea890bff1buzbee    }
256a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
257a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  if (attrs & DF_DA) {
258bff2465abb4b0c097623c82f18a1307ea890bff1buzbee    if (attrs & DF_A_WIDE) {
25915bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee      rlDest = oatGetDestWide(cUnit, mir);
260bff2465abb4b0c097623c82f18a1307ea890bff1buzbee    } else {
26115bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee      rlDest = oatGetDest(cUnit, mir);
262bff2465abb4b0c097623c82f18a1307ea890bff1buzbee    }
263a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
264a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  switch (opcode) {
265a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::NOP:
266a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
267a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
268474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers    case Instruction::MOVE_EXCEPTION:
269474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers      genMoveException(cUnit, rlDest);
270a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
271a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::RETURN_VOID:
2724f2935ef077529cc41aa0b590262fa91acbf6558TDYa      if (!(cUnit->attrs & METHOD_IS_LEAF)) {
273408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee        genSuspendTest(cUnit, optFlags);
274a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      }
275a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
276a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
277a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::RETURN:
278a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::RETURN_OBJECT:
2794f2935ef077529cc41aa0b590262fa91acbf6558TDYa      if (!(cUnit->attrs & METHOD_IS_LEAF)) {
280408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee        genSuspendTest(cUnit, optFlags);
281a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      }
282a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      storeValue(cUnit, oatGetReturn(cUnit, cUnit->shorty[0] == 'F'), rlSrc[0]);
283a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
284a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
285a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::RETURN_WIDE:
2864f2935ef077529cc41aa0b590262fa91acbf6558TDYa      if (!(cUnit->attrs & METHOD_IS_LEAF)) {
287408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee        genSuspendTest(cUnit, optFlags);
288a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      }
289a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      storeValueWide(cUnit, oatGetReturnWide(cUnit,
290a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                       cUnit->shorty[0] == 'D'), rlSrc[0]);
291a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
292a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
293a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::MOVE_RESULT_WIDE:
294408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      if (optFlags & MIR_INLINED)
295a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee        break;  // Nop - combined w/ previous invoke
296a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      storeValueWide(cUnit, rlDest, oatGetReturnWide(cUnit, rlDest.fp));
297a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
298a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
299a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::MOVE_RESULT:
300a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::MOVE_RESULT_OBJECT:
301408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      if (optFlags & MIR_INLINED)
302a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee        break;  // Nop - combined w/ previous invoke
303a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      storeValue(cUnit, rlDest, oatGetReturn(cUnit, rlDest.fp));
304a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
305a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
306a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::MOVE:
307a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::MOVE_OBJECT:
308a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::MOVE_16:
309a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::MOVE_OBJECT_16:
310a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::MOVE_FROM16:
311a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::MOVE_OBJECT_FROM16:
312a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      storeValue(cUnit, rlDest, rlSrc[0]);
313a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
314a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
315a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::MOVE_WIDE:
316a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::MOVE_WIDE_16:
317a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::MOVE_WIDE_FROM16:
318a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      storeValueWide(cUnit, rlDest, rlSrc[0]);
319a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
320a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
321a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::CONST:
322a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::CONST_4:
323a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::CONST_16:
324a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
325408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      loadConstantNoClobber(cUnit, rlResult.lowReg, vB);
326a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      storeValue(cUnit, rlDest, rlResult);
327a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
328a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
329a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::CONST_HIGH16:
330a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
331408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      loadConstantNoClobber(cUnit, rlResult.lowReg, vB << 16);
332a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      storeValue(cUnit, rlDest, rlResult);
333a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
334a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
335a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::CONST_WIDE_16:
336a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::CONST_WIDE_32:
337a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
338408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg, vB,
339408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee                            (vB & 0x80000000) ? -1 : 0);
340a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      storeValueWide(cUnit, rlDest, rlResult);
341a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
342a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
343a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::CONST_WIDE:
344a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
345a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
346a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                            mir->dalvikInsn.vB_wide & 0xffffffff,
347a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                            (mir->dalvikInsn.vB_wide >> 32) & 0xffffffff);
348a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      storeValueWide(cUnit, rlDest, rlResult);
349a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
350a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
351a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::CONST_WIDE_HIGH16:
352a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
353a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
354408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee                            0, vB << 16);
355a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      storeValueWide(cUnit, rlDest, rlResult);
356a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
357a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
358a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::MONITOR_ENTER:
359408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genMonitorEnter(cUnit, optFlags, rlSrc[0]);
360a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
361a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
362a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::MONITOR_EXIT:
363408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genMonitorExit(cUnit, optFlags, rlSrc[0]);
364a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
365a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
366a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::CHECK_CAST:
367408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genCheckCast(cUnit, vB, rlSrc[0]);
368a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
369a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
370a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::INSTANCE_OF:
371408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genInstanceof(cUnit, vC, rlDest, rlSrc[0]);
372a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
373a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
374a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::NEW_INSTANCE:
375408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genNewInstance(cUnit, vB, rlDest);
376a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
377a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
378a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::THROW:
379408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genThrow(cUnit, rlSrc[0]);
380a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
381a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
382a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::ARRAY_LENGTH:
383a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      int lenOffset;
384a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      lenOffset = Array::LengthOffset().Int32Value();
385a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      rlSrc[0] = loadValue(cUnit, rlSrc[0], kCoreReg);
386408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genNullCheck(cUnit, rlSrc[0].sRegLow, rlSrc[0].lowReg, optFlags);
387a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
388a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      loadWordDisp(cUnit, rlSrc[0].lowReg, lenOffset, rlResult.lowReg);
389a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      storeValue(cUnit, rlDest, rlResult);
390a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
391a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
392a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::CONST_STRING:
393a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::CONST_STRING_JUMBO:
3946969d50c820bd63043940b0e0f0ddc6e6ac763b0buzbee      genConstString(cUnit, vB, rlDest);
395a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
396a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
397a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::CONST_CLASS:
3986969d50c820bd63043940b0e0f0ddc6e6ac763b0buzbee      genConstClass(cUnit, vB, rlDest);
399a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
400a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
401a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::FILL_ARRAY_DATA:
402408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genFillArrayData(cUnit, vB, rlSrc[0]);
403a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
404a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
405a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::FILLED_NEW_ARRAY:
4066969d50c820bd63043940b0e0f0ddc6e6ac763b0buzbee      genFilledNewArray(cUnit, oatNewCallInfo(cUnit, bb, mir, kStatic,
4073b3dbddcbc7a7bee505a608061304f9b26a91750buzbee                        false /* not range */));
408a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
409a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
410a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::FILLED_NEW_ARRAY_RANGE:
4116969d50c820bd63043940b0e0f0ddc6e6ac763b0buzbee      genFilledNewArray(cUnit, oatNewCallInfo(cUnit, bb, mir, kStatic,
4123b3dbddcbc7a7bee505a608061304f9b26a91750buzbee                        true /* range */));
413a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
414a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
415a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::NEW_ARRAY:
416408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genNewArray(cUnit, vC, rlDest, rlSrc[0]);
417a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
418a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
419a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::GOTO:
420a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::GOTO_16:
421a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::GOTO_32:
422a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      if (bb->taken->startOffset <= mir->offset) {
423408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee        genSuspendTestAndBranch(cUnit, optFlags, &labelList[bb->taken->id]);
424a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      } else {
425a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee        opUnconditionalBranch(cUnit, &labelList[bb->taken->id]);
426a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      }
427a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
428a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
429a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::PACKED_SWITCH:
430408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genPackedSwitch(cUnit, vB, rlSrc[0]);
431a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
432a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
433a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SPARSE_SWITCH:
434a1da8a553681d1f7aec305610c8848c26373e0f0buzbee      genSparseSwitch(cUnit, vB, rlSrc[0]);
435a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
436a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
437a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::CMPL_FLOAT:
438a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::CMPG_FLOAT:
439a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::CMPL_DOUBLE:
440a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::CMPG_DOUBLE:
441408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      res = genCmpFP(cUnit, opcode, rlDest, rlSrc[0], rlSrc[1]);
442a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
443a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
444a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::CMP_LONG:
445408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genCmpLong(cUnit, rlDest, rlSrc[0], rlSrc[1]);
446a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
447a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
448a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::IF_EQ:
449a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::IF_NE:
450a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::IF_LT:
451a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::IF_GE:
452a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::IF_GT:
453a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::IF_LE: {
4543b3dbddcbc7a7bee505a608061304f9b26a91750buzbee      LIR* taken = &labelList[bb->taken->id];
4553b3dbddcbc7a7bee505a608061304f9b26a91750buzbee      LIR* fallThrough = &labelList[bb->fallThrough->id];
456a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      bool backwardBranch;
457a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      backwardBranch = (bb->taken->startOffset <= mir->offset);
458a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      if (backwardBranch) {
459408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee        genSuspendTest(cUnit, optFlags);
460a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      }
4613b3dbddcbc7a7bee505a608061304f9b26a91750buzbee      genCompareAndBranch(cUnit, opcode, rlSrc[0], rlSrc[1], taken,
4623b3dbddcbc7a7bee505a608061304f9b26a91750buzbee                          fallThrough);
463a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
464a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      }
465a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
466a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::IF_EQZ:
467a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::IF_NEZ:
468a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::IF_LTZ:
469a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::IF_GEZ:
470a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::IF_GTZ:
471a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::IF_LEZ: {
4723b3dbddcbc7a7bee505a608061304f9b26a91750buzbee      LIR* taken = &labelList[bb->taken->id];
4733b3dbddcbc7a7bee505a608061304f9b26a91750buzbee      LIR* fallThrough = &labelList[bb->fallThrough->id];
474a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      bool backwardBranch;
475a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      backwardBranch = (bb->taken->startOffset <= mir->offset);
476a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      if (backwardBranch) {
477408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee        genSuspendTest(cUnit, optFlags);
478a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      }
4793b3dbddcbc7a7bee505a608061304f9b26a91750buzbee      genCompareZeroAndBranch(cUnit, opcode, rlSrc[0], taken, fallThrough);
480a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
481a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      }
482a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
483a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::AGET_WIDE:
484408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genArrayGet(cUnit, optFlags, kLong, rlSrc[0], rlSrc[1], rlDest, 3);
485a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
486a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::AGET:
487a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::AGET_OBJECT:
488408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genArrayGet(cUnit, optFlags, kWord, rlSrc[0], rlSrc[1], rlDest, 2);
489a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
490a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::AGET_BOOLEAN:
491408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genArrayGet(cUnit, optFlags, kUnsignedByte, rlSrc[0], rlSrc[1], rlDest, 0);
492a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
493a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::AGET_BYTE:
494408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genArrayGet(cUnit, optFlags, kSignedByte, rlSrc[0], rlSrc[1], rlDest, 0);
495a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
496a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::AGET_CHAR:
497408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genArrayGet(cUnit, optFlags, kUnsignedHalf, rlSrc[0], rlSrc[1], rlDest, 1);
498a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
499a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::AGET_SHORT:
500408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genArrayGet(cUnit, optFlags, kSignedHalf, rlSrc[0], rlSrc[1], rlDest, 1);
501a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
502a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::APUT_WIDE:
503408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genArrayPut(cUnit, optFlags, kLong, rlSrc[1], rlSrc[2], rlSrc[0], 3);
504a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
505a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::APUT:
506408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genArrayPut(cUnit, optFlags, kWord, rlSrc[1], rlSrc[2], rlSrc[0], 2);
507a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
508a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::APUT_OBJECT:
509408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genArrayObjPut(cUnit, optFlags, rlSrc[1], rlSrc[2], rlSrc[0], 2);
510a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
511a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::APUT_SHORT:
512a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::APUT_CHAR:
513408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genArrayPut(cUnit, optFlags, kUnsignedHalf, rlSrc[1], rlSrc[2], rlSrc[0], 1);
514a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
515a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::APUT_BYTE:
516a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::APUT_BOOLEAN:
517408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genArrayPut(cUnit, optFlags, kUnsignedByte, rlSrc[1], rlSrc[2],
518a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee            rlSrc[0], 0);
519a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
520a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
521a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::IGET_OBJECT:
522a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    //case Instruction::IGET_OBJECT_VOLATILE:
523408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genIGet(cUnit, vC, optFlags, kWord, rlDest, rlSrc[0], false, true);
524a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
525a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
526a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::IGET_WIDE:
527a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    //case Instruction::IGET_WIDE_VOLATILE:
528408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genIGet(cUnit, vC, optFlags, kLong, rlDest, rlSrc[0], true, false);
529a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
530a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
531a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::IGET:
532a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    //case Instruction::IGET_VOLATILE:
533408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genIGet(cUnit, vC, optFlags, kWord, rlDest, rlSrc[0], false, false);
534a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
535a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
536a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::IGET_CHAR:
537408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genIGet(cUnit, vC, optFlags, kUnsignedHalf, rlDest, rlSrc[0], false, false);
538a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
539a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
540a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::IGET_SHORT:
541408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genIGet(cUnit, vC, optFlags, kSignedHalf, rlDest, rlSrc[0], false, false);
542a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
543a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
544a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::IGET_BOOLEAN:
545a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::IGET_BYTE:
546408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genIGet(cUnit, vC, optFlags, kUnsignedByte, rlDest, rlSrc[0], false, false);
547a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
548a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
549a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::IPUT_WIDE:
550a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    //case Instruction::IPUT_WIDE_VOLATILE:
551408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genIPut(cUnit, vC, optFlags, kLong, rlSrc[0], rlSrc[1], true, false);
552a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
553a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
554a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::IPUT_OBJECT:
555a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    //case Instruction::IPUT_OBJECT_VOLATILE:
556408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genIPut(cUnit, vC, optFlags, kWord, rlSrc[0], rlSrc[1], false, true);
557a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
558a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
559a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::IPUT:
560a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    //case Instruction::IPUT_VOLATILE:
561408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genIPut(cUnit, vC, optFlags, kWord, rlSrc[0], rlSrc[1], false, false);
562a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
563a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
564a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::IPUT_BOOLEAN:
565a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::IPUT_BYTE:
566408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genIPut(cUnit, vC, optFlags, kUnsignedByte, rlSrc[0], rlSrc[1], false, false);
567a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
568a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
569a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::IPUT_CHAR:
570408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genIPut(cUnit, vC, optFlags, kUnsignedHalf, rlSrc[0], rlSrc[1], false, false);
571a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
572a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
573a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::IPUT_SHORT:
574408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genIPut(cUnit, vC, optFlags, kSignedHalf, rlSrc[0], rlSrc[1], false, false);
575a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
576a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
577a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SGET_OBJECT:
578408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genSget(cUnit, vB, rlDest, false, true);
579a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
580a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SGET:
581a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SGET_BOOLEAN:
582a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SGET_BYTE:
583a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SGET_CHAR:
584a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SGET_SHORT:
585408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genSget(cUnit, vB, rlDest, false, false);
586a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
587a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
588a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SGET_WIDE:
589408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genSget(cUnit, vB, rlDest, true, false);
590a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
591a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
592a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SPUT_OBJECT:
593408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genSput(cUnit, vB, rlSrc[0], false, true);
594a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
595a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
596a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SPUT:
597a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SPUT_BOOLEAN:
598a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SPUT_BYTE:
599a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SPUT_CHAR:
600a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SPUT_SHORT:
601408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genSput(cUnit, vB, rlSrc[0], false, false);
602a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
603a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
604a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SPUT_WIDE:
605408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genSput(cUnit, vB, rlSrc[0], true, false);
606a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
607a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
608a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::INVOKE_STATIC_RANGE:
6096969d50c820bd63043940b0e0f0ddc6e6ac763b0buzbee      genInvoke(cUnit, oatNewCallInfo(cUnit, bb, mir, kStatic, true));
610a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
611a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::INVOKE_STATIC:
6126969d50c820bd63043940b0e0f0ddc6e6ac763b0buzbee      genInvoke(cUnit, oatNewCallInfo(cUnit, bb, mir, kStatic, false));
613a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
614a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
615a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::INVOKE_DIRECT:
6166969d50c820bd63043940b0e0f0ddc6e6ac763b0buzbee      genInvoke(cUnit, oatNewCallInfo(cUnit, bb, mir, kDirect, false));
617a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
618a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::INVOKE_DIRECT_RANGE:
6196969d50c820bd63043940b0e0f0ddc6e6ac763b0buzbee      genInvoke(cUnit, oatNewCallInfo(cUnit, bb, mir, kDirect, true));
620a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
621a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
622a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::INVOKE_VIRTUAL:
6236969d50c820bd63043940b0e0f0ddc6e6ac763b0buzbee      genInvoke(cUnit, oatNewCallInfo(cUnit, bb, mir, kVirtual, false));
624a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
625a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::INVOKE_VIRTUAL_RANGE:
6266969d50c820bd63043940b0e0f0ddc6e6ac763b0buzbee      genInvoke(cUnit, oatNewCallInfo(cUnit, bb, mir, kVirtual, true));
627a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
628a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
629a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::INVOKE_SUPER:
6306969d50c820bd63043940b0e0f0ddc6e6ac763b0buzbee      genInvoke(cUnit, oatNewCallInfo(cUnit, bb, mir, kSuper, false));
631a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
632a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::INVOKE_SUPER_RANGE:
6336969d50c820bd63043940b0e0f0ddc6e6ac763b0buzbee      genInvoke(cUnit, oatNewCallInfo(cUnit, bb, mir, kSuper, true));
634a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
635a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
636a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::INVOKE_INTERFACE:
6376969d50c820bd63043940b0e0f0ddc6e6ac763b0buzbee      genInvoke(cUnit, oatNewCallInfo(cUnit, bb, mir, kInterface, false));
638a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
639a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::INVOKE_INTERFACE_RANGE:
6406969d50c820bd63043940b0e0f0ddc6e6ac763b0buzbee      genInvoke(cUnit, oatNewCallInfo(cUnit, bb, mir, kInterface, true));
641a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
642a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
643a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::NEG_INT:
644a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::NOT_INT:
645408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      res = genArithOpInt(cUnit, opcode, rlDest, rlSrc[0], rlSrc[0]);
646a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
647a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
648a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::NEG_LONG:
649a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::NOT_LONG:
650408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      res = genArithOpLong(cUnit, opcode, rlDest, rlSrc[0], rlSrc[0]);
651a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
652a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
653a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::NEG_FLOAT:
654408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      res = genArithOpFloat(cUnit, opcode, rlDest, rlSrc[0], rlSrc[0]);
655a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
656a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
657a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::NEG_DOUBLE:
658408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      res = genArithOpDouble(cUnit, opcode, rlDest, rlSrc[0], rlSrc[0]);
659a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
660a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
661a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::INT_TO_LONG:
662408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genIntToLong(cUnit, rlDest, rlSrc[0]);
663a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
664a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
665a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::LONG_TO_INT:
666a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      rlSrc[0] = oatUpdateLocWide(cUnit, rlSrc[0]);
667a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      rlSrc[0] = oatWideToNarrow(cUnit, rlSrc[0]);
668a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      storeValue(cUnit, rlDest, rlSrc[0]);
669a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
670a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
671a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::INT_TO_BYTE:
672a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::INT_TO_SHORT:
673a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::INT_TO_CHAR:
674408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genIntNarrowing(cUnit, opcode, rlDest, rlSrc[0]);
675a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
676a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
677a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::INT_TO_FLOAT:
678a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::INT_TO_DOUBLE:
679a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::LONG_TO_FLOAT:
680a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::LONG_TO_DOUBLE:
681a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::FLOAT_TO_INT:
682a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::FLOAT_TO_LONG:
683a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::FLOAT_TO_DOUBLE:
684a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::DOUBLE_TO_INT:
685a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::DOUBLE_TO_LONG:
686a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::DOUBLE_TO_FLOAT:
687408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genConversion(cUnit, opcode, rlDest, rlSrc[0]);
688a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
689a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
690a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::ADD_INT:
691a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SUB_INT:
692a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::MUL_INT:
693a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::DIV_INT:
694a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::REM_INT:
695a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::AND_INT:
696a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::OR_INT:
697a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::XOR_INT:
698a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SHL_INT:
699a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SHR_INT:
700a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::USHR_INT:
701a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::ADD_INT_2ADDR:
702a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SUB_INT_2ADDR:
703a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::MUL_INT_2ADDR:
704a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::DIV_INT_2ADDR:
705a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::REM_INT_2ADDR:
706a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::AND_INT_2ADDR:
707a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::OR_INT_2ADDR:
708a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::XOR_INT_2ADDR:
709a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SHL_INT_2ADDR:
710a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SHR_INT_2ADDR:
711a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::USHR_INT_2ADDR:
712408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genArithOpInt(cUnit, opcode, rlDest, rlSrc[0], rlSrc[1]);
713a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
714a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
715a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::ADD_LONG:
716a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SUB_LONG:
717a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::MUL_LONG:
718a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::DIV_LONG:
719a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::REM_LONG:
720a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::AND_LONG:
721a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::OR_LONG:
722a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::XOR_LONG:
723a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::ADD_LONG_2ADDR:
724a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SUB_LONG_2ADDR:
725a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::MUL_LONG_2ADDR:
726a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::DIV_LONG_2ADDR:
727a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::REM_LONG_2ADDR:
728a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::AND_LONG_2ADDR:
729a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::OR_LONG_2ADDR:
730a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::XOR_LONG_2ADDR:
731408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genArithOpLong(cUnit, opcode, rlDest, rlSrc[0], rlSrc[1]);
732a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
733a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
734a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SHL_LONG:
735a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SHR_LONG:
736a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::USHR_LONG:
737a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SHL_LONG_2ADDR:
738a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SHR_LONG_2ADDR:
739a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::USHR_LONG_2ADDR:
740408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genShiftOpLong(cUnit, opcode, rlDest, rlSrc[0], rlSrc[1]);
741a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
742a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
743a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::ADD_FLOAT:
744a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SUB_FLOAT:
745a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::MUL_FLOAT:
746a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::DIV_FLOAT:
747a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::REM_FLOAT:
748a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::ADD_FLOAT_2ADDR:
749a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SUB_FLOAT_2ADDR:
750a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::MUL_FLOAT_2ADDR:
751a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::DIV_FLOAT_2ADDR:
752a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::REM_FLOAT_2ADDR:
753408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genArithOpFloat(cUnit, opcode, rlDest, rlSrc[0], rlSrc[1]);
754a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
755a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
756a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::ADD_DOUBLE:
757a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SUB_DOUBLE:
758a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::MUL_DOUBLE:
759a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::DIV_DOUBLE:
760a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::REM_DOUBLE:
761a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::ADD_DOUBLE_2ADDR:
762a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SUB_DOUBLE_2ADDR:
763a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::MUL_DOUBLE_2ADDR:
764a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::DIV_DOUBLE_2ADDR:
765a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::REM_DOUBLE_2ADDR:
766408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genArithOpDouble(cUnit, opcode, rlDest, rlSrc[0], rlSrc[1]);
767a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
768a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
769a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::RSUB_INT:
770a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::ADD_INT_LIT16:
771a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::MUL_INT_LIT16:
772a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::DIV_INT_LIT16:
773a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::REM_INT_LIT16:
774a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::AND_INT_LIT16:
775a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::OR_INT_LIT16:
776a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::XOR_INT_LIT16:
777a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::ADD_INT_LIT8:
778a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::RSUB_INT_LIT8:
779a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::MUL_INT_LIT8:
780a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::DIV_INT_LIT8:
781a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::REM_INT_LIT8:
782a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::AND_INT_LIT8:
783a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::OR_INT_LIT8:
784a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::XOR_INT_LIT8:
785a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SHL_INT_LIT8:
786a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::SHR_INT_LIT8:
787a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case Instruction::USHR_INT_LIT8:
788408ad16bf7c460bf34ca55ff6351b79841a6fcd5buzbee      genArithOpIntLit(cUnit, opcode, rlDest, rlSrc[0], vC);
789a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
790a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
791a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    default:
792a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      res = true;
793a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
794a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  return res;
795e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
796e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
79731a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeeconst char* extendedMIROpNames[kMirOpLast - kMirOpFirst] = {
798a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  "kMirOpPhi",
799a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  "kMirOpCopy",
800a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  "kMirFusedCmplFloat",
801a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  "kMirFusedCmpgFloat",
802a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  "kMirFusedCmplDouble",
803a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  "kMirFusedCmpgDouble",
804a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  "kMirFusedCmpLong",
805a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  "kMirNop",
806c9f40dd0a3dba696fc694d51fb82b61dcff19066Bill Buzbee  "kMirOpNullCheck",
807c9f40dd0a3dba696fc694d51fb82b61dcff19066Bill Buzbee  "kMirOpRangeCheck",
808c9f40dd0a3dba696fc694d51fb82b61dcff19066Bill Buzbee  "kMirOpDivZeroCheck",
809c9f40dd0a3dba696fc694d51fb82b61dcff19066Bill Buzbee  "kMirOpCheck",
810e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee};
811e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
812e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Extended MIR instructions like PHI */
81384fd693103dddd50b6a18522bfb5eaab0e51b6ecbuzbeevoid handleExtendedMethodMIR(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir)
814e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee{
815a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  int opOffset = mir->dalvikInsn.opcode - kMirOpFirst;
816a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  char* msg = NULL;
817a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  if (cUnit->printMe) {
818a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    msg = (char*)oatNew(cUnit, strlen(extendedMIROpNames[opOffset]) + 1,
819a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                        false, kAllocDebugInfo);
820a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    strcpy(msg, extendedMIROpNames[opOffset]);
821a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
822a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  LIR* op = newLIR1(cUnit, kPseudoExtended, (int) msg);
823a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
824a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
825a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kMirOpPhi: {
826a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      char* ssaString = NULL;
827a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      if (cUnit->printMe) {
828a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee        ssaString = oatGetSSAString(cUnit, mir->ssaRep);
829a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      }
830a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      op->flags.isNop = true;
831a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      newLIR1(cUnit, kPseudoSSARep, (int) ssaString);
832a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
833a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    }
834a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kMirOpCopy: {
835a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      RegLocation rlSrc = oatGetSrc(cUnit, mir, 0);
83615bf9804820b73765899e4b3e0d8a1fa15e0dbd3buzbee      RegLocation rlDest = oatGetDest(cUnit, mir);
837a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      storeValue(cUnit, rlDest, rlSrc);
838a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
839e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee    }
840a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kMirOpFusedCmplFloat:
841a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      genFusedFPCmpBranch(cUnit, bb, mir, false /*gt bias*/, false /*double*/);
842a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
843a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kMirOpFusedCmpgFloat:
844a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      genFusedFPCmpBranch(cUnit, bb, mir, true /*gt bias*/, false /*double*/);
845a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
846a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kMirOpFusedCmplDouble:
847a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      genFusedFPCmpBranch(cUnit, bb, mir, false /*gt bias*/, true /*double*/);
848a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
849a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kMirOpFusedCmpgDouble:
850a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      genFusedFPCmpBranch(cUnit, bb, mir, true /*gt bias*/, true /*double*/);
851a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
852a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    case kMirOpFusedCmpLong:
853a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      genFusedLongCmpBranch(cUnit, bb, mir);
854a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
855a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    default:
856a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
857a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
858e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
859e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
860e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee/* Handle the content in each basic block */
86131a4a6f5717f645da6b97ccc1e420ae1e1c71ce0buzbeebool methodBlockCodeGen(CompilationUnit* cUnit, BasicBlock* bb)
862e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee{
863488a78ca207898490da3cfb58399534fa9fb3fbfbuzbee  if (bb->blockType == kDead) return false;
8648320f3867c02bae9bef6cdab267820cb7b412781buzbee  cUnit->currentDalvikOffset = bb->startOffset;
865a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  MIR* mir;
866a1da8a553681d1f7aec305610c8848c26373e0f0buzbee  LIR* labelList = cUnit->blockLabelList;
867a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  int blockId = bb->id;
868a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
869a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  cUnit->curBlock = bb;
870a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  labelList[blockId].operands[0] = bb->startOffset;
871a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
872a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /* Insert the block label */
873a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  labelList[blockId].opcode = kPseudoNormalBlockLabel;
874a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  oatAppendLIR(cUnit, (LIR*) &labelList[blockId]);
875a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
8768320f3867c02bae9bef6cdab267820cb7b412781buzbee  LIR* headLIR = NULL;
8778320f3867c02bae9bef6cdab267820cb7b412781buzbee
878a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee  /* If this is a catch block, export the start address */
8798320f3867c02bae9bef6cdab267820cb7b412781buzbee  if (bb->catchEntry) {
880a5b3024aed77a8204d5fb48ba7f763fb8c60fa76Bill Buzbee    headLIR = newLIR0(cUnit, kPseudoExportedPC);
8818320f3867c02bae9bef6cdab267820cb7b412781buzbee  }
8828320f3867c02bae9bef6cdab267820cb7b412781buzbee
883a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /* Free temp registers and reset redundant store tracking */
884a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  oatResetRegPool(cUnit);
885a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  oatResetDefTracking(cUnit);
886a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
887d1643e41ef242ae656f667bf3c8b0324635cefd3buzbee  oatClobberAllRegs(cUnit);
888e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
889e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
890a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  if (bb->blockType == kEntryBlock) {
891ad8f15e0b13383b2eaa2486b230debeae7a55661buzbee    int startVReg = cUnit->numDalvikRegisters - cUnit->numIns;
892ad8f15e0b13383b2eaa2486b230debeae7a55661buzbee    genEntrySequence(cUnit, &cUnit->regLocation[startVReg],
893ad8f15e0b13383b2eaa2486b230debeae7a55661buzbee                     cUnit->regLocation[cUnit->methodSReg]);
894a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  } else if (bb->blockType == kExitBlock) {
8952cfc639fc803bf67e3d2a961f2b637220c86d5f7buzbee    genExitSequence(cUnit);
896a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
897a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
898a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
899e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee    oatResetRegPool(cUnit);
900a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    if (cUnit->disableOpt & (1 << kTrackLiveTemps)) {
901a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      oatClobberAllRegs(cUnit);
902a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    }
903e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
904a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    if (cUnit->disableOpt & (1 << kSuppressLoads)) {
905a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      oatResetDefTracking(cUnit);
906e196567b50a084b163937ea9605b51ee1e48adebbuzbee    }
907e196567b50a084b163937ea9605b51ee1e48adebbuzbee
908a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee#ifndef NDEBUG
909a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    /* Reset temp tracking sanity check */
910a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    cUnit->liveSReg = INVALID_SREG;
911a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee#endif
912a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
913a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    cUnit->currentDalvikOffset = mir->offset;
914c9f40dd0a3dba696fc694d51fb82b61dcff19066Bill Buzbee    int opcode = mir->dalvikInsn.opcode;
915a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    LIR* boundaryLIR;
916e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
917a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    /* Mark the beginning of a Dalvik instruction for line tracking */
918a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    char* instStr = cUnit->printMe ?
919a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee       oatGetDalvikDisassembly(cUnit, mir->dalvikInsn, "") : NULL;
920d1643e41ef242ae656f667bf3c8b0324635cefd3buzbee    boundaryLIR = markBoundary(cUnit, mir->offset, instStr);
921a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    /* Remember the first LIR for this block */
922a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    if (headLIR == NULL) {
923a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      headLIR = boundaryLIR;
924a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      /* Set the first boundaryLIR as a scheduling barrier */
925a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      headLIR->defMask = ENCODE_ALL;
926e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee    }
927e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
928a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    /* Don't generate the SSA annotation unless verbose mode is on */
929a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    if (cUnit->printMe && mir->ssaRep) {
930a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      char* ssaString = oatGetSSAString(cUnit, mir->ssaRep);
931a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      newLIR1(cUnit, kPseudoSSARep, (int) ssaString);
932a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    }
933e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
934c9f40dd0a3dba696fc694d51fb82b61dcff19066Bill Buzbee    if (opcode == kMirOpCheck) {
935c9f40dd0a3dba696fc694d51fb82b61dcff19066Bill Buzbee      // Combine check and work halves of throwing instruction.
936c9f40dd0a3dba696fc694d51fb82b61dcff19066Bill Buzbee      MIR* workHalf = mir->meta.throwInsn;
937c9f40dd0a3dba696fc694d51fb82b61dcff19066Bill Buzbee      mir->dalvikInsn.opcode = workHalf->dalvikInsn.opcode;
938c9f40dd0a3dba696fc694d51fb82b61dcff19066Bill Buzbee      opcode = workHalf->dalvikInsn.opcode;
939c9f40dd0a3dba696fc694d51fb82b61dcff19066Bill Buzbee      SSARepresentation* ssaRep = workHalf->ssaRep;
940c9f40dd0a3dba696fc694d51fb82b61dcff19066Bill Buzbee      workHalf->ssaRep = mir->ssaRep;
941c9f40dd0a3dba696fc694d51fb82b61dcff19066Bill Buzbee      mir->ssaRep = ssaRep;
942c9f40dd0a3dba696fc694d51fb82b61dcff19066Bill Buzbee      workHalf->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
943c9f40dd0a3dba696fc694d51fb82b61dcff19066Bill Buzbee    }
944c9f40dd0a3dba696fc694d51fb82b61dcff19066Bill Buzbee
945c9f40dd0a3dba696fc694d51fb82b61dcff19066Bill Buzbee    if (opcode >= kMirOpFirst) {
946a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      handleExtendedMethodMIR(cUnit, bb, mir);
947a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      continue;
948a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    }
949e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
950a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    bool notHandled = compileDalvikInstruction(cUnit, mir, bb, labelList);
951a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    if (notHandled) {
952c9f40dd0a3dba696fc694d51fb82b61dcff19066Bill Buzbee      LOG(FATAL) << StringPrintf("%#06x: Opcode %#x (%s)",
953c9f40dd0a3dba696fc694d51fb82b61dcff19066Bill Buzbee                                 mir->offset, opcode,
954c9f40dd0a3dba696fc694d51fb82b61dcff19066Bill Buzbee                                 Instruction::Name(mir->dalvikInsn.opcode));
955e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee    }
956a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
957e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
958a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  if (headLIR) {
959a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    /*
960a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee     * Eliminate redundant loads/stores and delay stores into later
961a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee     * slots
962a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee     */
963a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    oatApplyLocalOptimizations(cUnit, (LIR*) headLIR, cUnit->lastLIRInsn);
964a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
965a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    /*
966a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee     * Generate an unconditional branch to the fallthrough block.
967a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee     */
968a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    if (bb->fallThrough) {
969a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      opUnconditionalBranch(cUnit, &labelList[bb->fallThrough->id]);
970e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee    }
971a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
972a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  return false;
973e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
974e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
97516da88c70c4bdbd97b8482be8b42103a52f22d59buzbee/* Set basic block labels */
97616da88c70c4bdbd97b8482be8b42103a52f22d59buzbeebool labelBlocks(CompilationUnit* cUnit, BasicBlock* bb)
97716da88c70c4bdbd97b8482be8b42103a52f22d59buzbee{
978a1da8a553681d1f7aec305610c8848c26373e0f0buzbee  LIR* labelList = cUnit->blockLabelList;
979a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  int blockId = bb->id;
98016da88c70c4bdbd97b8482be8b42103a52f22d59buzbee
981a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  cUnit->curBlock = bb;
982a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  labelList[blockId].operands[0] = bb->startOffset;
98316da88c70c4bdbd97b8482be8b42103a52f22d59buzbee
984a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /* Insert the block label */
985a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  labelList[blockId].opcode = kPseudoNormalBlockLabel;
986a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  return false;
98716da88c70c4bdbd97b8482be8b42103a52f22d59buzbee}
98816da88c70c4bdbd97b8482be8b42103a52f22d59buzbee
98916da88c70c4bdbd97b8482be8b42103a52f22d59buzbeevoid oatSpecialMIR2LIR(CompilationUnit* cUnit, SpecialCaseHandler specialCase)
99016da88c70c4bdbd97b8482be8b42103a52f22d59buzbee{
991a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /* Find the first DalvikByteCode block */
992a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  int numReachableBlocks = cUnit->numReachableBlocks;
993a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  const GrowableList *blockList = &cUnit->blockList;
994a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  BasicBlock*bb = NULL;
995a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  for (int idx = 0; idx < numReachableBlocks; idx++) {
996a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    int dfsIndex = cUnit->dfsOrder.elemList[idx];
997a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    bb = (BasicBlock*)oatGrowableListGetElement(blockList, dfsIndex);
998a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    if (bb->blockType == kDalvikByteCode) {
999a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee      break;
100016da88c70c4bdbd97b8482be8b42103a52f22d59buzbee    }
1001a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
1002a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  if (bb == NULL) {
1003a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    return;
1004a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
1005a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  DCHECK_EQ(bb->startOffset, 0);
1006748474146da0c6484fa3dca0a700f612d47550c3Elliott Hughes  DCHECK(bb->firstMIRInsn != NULL);
1007a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
1008a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /* Get the first instruction */
1009a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  MIR* mir = bb->firstMIRInsn;
1010a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
1011a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /* Free temp registers and reset redundant store tracking */
1012a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  oatResetRegPool(cUnit);
1013a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  oatResetDefTracking(cUnit);
1014a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  oatClobberAllRegs(cUnit);
1015a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee
1016a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  genSpecialCase(cUnit, bb, mir, specialCase);
101716da88c70c4bdbd97b8482be8b42103a52f22d59buzbee}
101816da88c70c4bdbd97b8482be8b42103a52f22d59buzbee
1019e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbeevoid oatMethodMIR2LIR(CompilationUnit* cUnit)
1020e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee{
1021a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  /* Used to hold the labels of each block */
1022a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  cUnit->blockLabelList =
1023a1da8a553681d1f7aec305610c8848c26373e0f0buzbee      (LIR*) oatNew(cUnit, sizeof(LIR) * cUnit->numBlocks, true, kAllocLIR);
1024e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
1025a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  oatDataFlowAnalysisDispatcher(cUnit, methodBlockCodeGen,
1026a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee                                kPreOrderDFSTraversal, false /* Iterative */);
1027ab2b55dfcf630fdf8d03b5f506386f114fa2874cIan Rogers
1028a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  handleSuspendLaunchpads(cUnit);
1029e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
1030a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  handleThrowLaunchpads(cUnit);
1031e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
1032a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  handleIntrinsicLaunchpads(cUnit);
1033fc9e6fabed89d948fa8c0e9d673e430076712c60buzbee
1034a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  if (!(cUnit->disableOpt & (1 << kSafeOptimizations))) {
1035a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee    removeRedundantBranches(cUnit);
1036a114add0300b95eeaae7465493f39144e07324e8Bill Buzbee  }
1037e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}
1038e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee
1039e3acd07f28d5625062b599c2817cb5f7a53f54a9buzbee}  // namespace art
1040