aboutsummaryrefslogtreecommitdiff
path: root/vm/compiler/codegen/x86/CodegenDriver.c
diff options
context:
space:
mode:
authorbuzbee <buzbee@google.com>2010-12-13 15:33:46 -0800
committerAndroid (Google) Code Review <android-gerrit@google.com>2010-12-13 15:33:46 -0800
commit823a87840e570ad06c4426537477a21243474a1c (patch)
tree7f0b30ca78f0241da3510159a4de249cff227cc4 /vm/compiler/codegen/x86/CodegenDriver.c
parent199873ed768a8a7b0fd5525ca24407583d593345 (diff)
parentdfd1bbf07d98c82a6072182f705f64a30ebf480b (diff)
Merge "Experimental x86 Jit trace selection" into dalvik-dev
Diffstat (limited to 'vm/compiler/codegen/x86/CodegenDriver.c')
-rw-r--r--vm/compiler/codegen/x86/CodegenDriver.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/vm/compiler/codegen/x86/CodegenDriver.c b/vm/compiler/codegen/x86/CodegenDriver.c
index 69f637ed7..4a5d481b9 100644
--- a/vm/compiler/codegen/x86/CodegenDriver.c
+++ b/vm/compiler/codegen/x86/CodegenDriver.c
@@ -24,10 +24,63 @@
* applicable directory below this one.
*/
+extern X86LIR *loadConstant(CompilationUnit *cUnit, int rDest, int value);
+extern X86LIR *loadWordDisp(CompilationUnit *cUnit, int rBase,
+ int displacement, int rDest);
+extern void dvmCompilerFlushAllRegs(CompilationUnit *cUnit);
+extern void storeWordDisp(CompilationUnit *cUnit, int rBase,
+ int displacement, int rSrc);
+extern X86LIR *opReg(CompilationUnit *cUnit, OpKind op, int rDestSrc);
+
static int opcodeCoverage[kNumPackedOpcodes];
static intptr_t templateEntryOffsets[TEMPLATE_LAST_MARK];
/*
+ * Bail to the interpreter. Will not return to this trace.
+ * On entry, rPC must be set correctly.
+ */
+static void genPuntToInterp(CompilationUnit *cUnit, unsigned int offset)
+{
+ dvmCompilerFlushAllRegs(cUnit);
+ loadConstant(cUnit, rPC, (int)(cUnit->method->insns + offset));
+ loadWordDisp(cUnit, rEBP, 0, rECX); // Get glue
+ loadWordDisp(cUnit, rECX,
+ offsetof(InterpState, jitToInterpEntries.dvmJitToInterpPunt),
+ rEAX);
+ opReg(cUnit, kOpUncondBr, rEAX);
+}
+
+static void genInterpSingleStep(CompilationUnit *cUnit, MIR *mir)
+{
+ int flags = dexGetFlagsFromOpcode(mir->dalvikInsn.opcode);
+ int flagsToCheck = kInstrCanBranch | kInstrCanSwitch | kInstrCanReturn |
+ kInstrCanThrow;
+
+ //If already optimized out, just ignore
+ if (mir->dalvikInsn.opcode == OP_NOP)
+ return;
+
+ //Ugly, but necessary. Flush all Dalvik regs so Interp can find them
+ dvmCompilerFlushAllRegs(cUnit);
+
+ if ((mir->next == NULL) || (flags & flagsToCheck)) {
+ genPuntToInterp(cUnit, mir->offset);
+ return;
+ }
+ int entryAddr = offsetof(InterpState,
+ jitToInterpEntries.dvmJitToInterpSingleStep);
+ loadWordDisp(cUnit, rEBP, 0, rECX); // Get glue
+ loadWordDisp(cUnit, rECX, entryAddr, rEAX); // rEAX<- entry address
+ /* rPC = dalvik pc */
+ loadConstant(cUnit, rPC, (int) (cUnit->method->insns + mir->offset));
+ /* rECX = dalvik pc of following instruction */
+ loadConstant(cUnit, rECX, (int) (cUnit->method->insns + mir->next->offset));
+ /* Pass on the stack */
+ storeWordDisp(cUnit, rESP, OUT_ARG0, rECX);
+ opReg(cUnit, kOpCall, rEAX);
+}
+
+/*
* The following are the first-level codegen routines that analyze the format
* of each bytecode then either dispatch special purpose codegen routines
* or produce corresponding Thumb instructions directly.