blob: c8c7e349d2c2c678516da27e4f53ebcfd425e720 [file] [log] [blame]
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* This file contains arm-specific codegen factory support.
* It is included by
*
* Codegen-$(TARGET_ARCH_VARIANT).c
*
*/
/*
* Utiltiy to load the current Method*. Broken out
* to allow easy change between placing the current Method* in a
* dedicated register or its home location in the frame.
*/
static void loadCurrMethodDirect(CompilationUnit *cUnit, int rTgt)
{
#if defined(METHOD_IN_REG)
genRegCopy(cUnit, rTgt, rMETHOD);
#else
loadWordDisp(cUnit, rSP, 0, rTgt);
#endif
}
/*
* Perform a "reg cmp imm" operation and jump to the PCR region if condition
* satisfies.
*/
static TGT_LIR* genRegImmCheck(CompilationUnit* cUnit,
ArmConditionCode cond, int reg,
int checkValue, int dOffset,
TGT_LIR* pcrLabel)
{
TGT_LIR* branch = genCmpImmBranch(cUnit, cond, reg, checkValue);
BasicBlock* bb = cUnit->curBlock;
if (bb->taken) {
ArmLIR *exceptionLabel = (ArmLIR* ) cUnit->blockLabelList;
exceptionLabel += bb->taken->id;
branch->generic.target = (LIR* ) exceptionLabel;
return exceptionLabel;
} else {
LOG(FATAL) << "Catch blocks not handled yet";
return NULL; // quiet gcc
}
}
/*
* Perform null-check on a register. sReg is the ssa register being checked,
* and mReg is the machine register holding the actual value. If internal state
* indicates that sReg has been checked before the check request is ignored.
*/
static TGT_LIR* genNullCheck(CompilationUnit* cUnit, int sReg, int mReg,
int dOffset, TGT_LIR* pcrLabel)
{
/* This particular Dalvik register has been null-checked */
UNIMPLEMENTED(WARNING) << "Need null check & throw support";
return pcrLabel;
if (oatIsBitSet(cUnit->regPool->nullCheckedRegs, sReg)) {
return pcrLabel;
}
oatSetBit(cUnit->regPool->nullCheckedRegs, sReg);
return genRegImmCheck(cUnit, kArmCondEq, mReg, 0, dOffset, pcrLabel);
}
/*
* Perform a "reg cmp reg" operation and jump to the PCR region if condition
* satisfies.
*/
static TGT_LIR* genRegRegCheck(CompilationUnit* cUnit,
ArmConditionCode cond,
int reg1, int reg2, int dOffset,
TGT_LIR* pcrLabel)
{
TGT_LIR* res;
res = opRegReg(cUnit, kOpCmp, reg1, reg2);
TGT_LIR* branch = opCondBranch(cUnit, cond);
genCheckCommon(cUnit, dOffset, branch, pcrLabel);
return res;
}
/* Perform bound check on two registers */
static TGT_LIR* genBoundsCheck(CompilationUnit* cUnit, int rIndex,
int rBound, int dOffset, TGT_LIR* pcrLabel)
{
return genRegRegCheck(cUnit, kArmCondCs, rIndex, rBound, dOffset,
pcrLabel);
}