summaryrefslogtreecommitdiffstats
path: root/vm/compiler/codegen/arm/ArchFactory.cpp
diff options
context:
space:
mode:
authorCarl Shapiro <cshapiro@google.com>2011-04-19 17:34:24 -0700
committerCarl Shapiro <cshapiro@google.com>2011-04-19 17:34:24 -0700
commit5d5b94c8d14b166af580d5dd5906db4f9527d6ca (patch)
tree3316231983154784835b1d8b056e233727ee42c5 /vm/compiler/codegen/arm/ArchFactory.cpp
parent6f430bb050987ca4e0be70e9c6aea5a11b4a7f84 (diff)
downloadandroid_dalvik-5d5b94c8d14b166af580d5dd5906db4f9527d6ca.tar.gz
android_dalvik-5d5b94c8d14b166af580d5dd5906db4f9527d6ca.tar.bz2
android_dalvik-5d5b94c8d14b166af580d5dd5906db4f9527d6ca.zip
Move the compiler into C++.
Change-Id: Idffbdb02c29e2be03a75f5a0a664603f2299504a
Diffstat (limited to 'vm/compiler/codegen/arm/ArchFactory.cpp')
-rw-r--r--vm/compiler/codegen/arm/ArchFactory.cpp123
1 files changed, 123 insertions, 0 deletions
diff --git a/vm/compiler/codegen/arm/ArchFactory.cpp b/vm/compiler/codegen/arm/ArchFactory.cpp
new file mode 100644
index 000000000..5a03b17ad
--- /dev/null
+++ b/vm/compiler/codegen/arm/ArchFactory.cpp
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2010 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
+ *
+ */
+
+/*
+ * 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);
+ if (cUnit->jitMode == kJitMethod) {
+ BasicBlock *bb = cUnit->curBlock;
+ if (bb->taken) {
+ ArmLIR *exceptionLabel = (ArmLIR *) cUnit->blockLabelList;
+ exceptionLabel += bb->taken->id;
+ branch->generic.target = (LIR *) exceptionLabel;
+ return exceptionLabel;
+ } else {
+ LOGE("Catch blocks not handled yet");
+ dvmAbort();
+ return NULL;
+ }
+ } else {
+ return genCheckCommon(cUnit, dOffset, branch, pcrLabel);
+ }
+}
+
+/*
+ * 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 */
+ if (dvmIsBitSet(cUnit->regPool->nullCheckedRegs, sReg)) {
+ return pcrLabel;
+ }
+ dvmSetBit(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 zero-check on a register. Similar to genNullCheck but the value being
+ * checked does not have a corresponding Dalvik register.
+ */
+static TGT_LIR *genZeroCheck(CompilationUnit *cUnit, int mReg,
+ int dOffset, TGT_LIR *pcrLabel)
+{
+ return genRegImmCheck(cUnit, kArmCondEq, mReg, 0, dOffset, pcrLabel);
+}
+
+/* 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);
+}
+
+/*
+ * Jump to the out-of-line handler in ARM mode to finish executing the
+ * remaining of more complex instructions.
+ */
+static void genDispatchToHandler(CompilationUnit *cUnit, TemplateOpcode opcode)
+{
+ /*
+ * NOTE - In practice BLX only needs one operand, but since the assembler
+ * may abort itself and retry due to other out-of-range conditions we
+ * cannot really use operand[0] to store the absolute target address since
+ * it may get clobbered by the final relative offset. Therefore,
+ * we fake BLX_1 is a two operand instruction and the absolute target
+ * address is stored in operand[1].
+ */
+ dvmCompilerClobberHandlerRegs(cUnit);
+ newLIR2(cUnit, kThumbBlx1,
+ (int) gDvmJit.codeCache + templateEntryOffsets[opcode],
+ (int) gDvmJit.codeCache + templateEntryOffsets[opcode]);
+ newLIR2(cUnit, kThumbBlx2,
+ (int) gDvmJit.codeCache + templateEntryOffsets[opcode],
+ (int) gDvmJit.codeCache + templateEntryOffsets[opcode]);
+}