| /* |
| * 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 codegen and support common to all supported |
| * X86 variants. It is included by: |
| * |
| * Codegen-$(TARGET_ARCH_VARIANT).c |
| * |
| * which combines this common code with specific support found in the |
| * applicable directory below this one. |
| */ |
| |
| static int opcodeCoverage[kNumPackedOpcodes]; |
| static intptr_t templateEntryOffsets[TEMPLATE_LAST_MARK]; |
| |
| /* |
| * 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. |
| */ |
| |
| #if 0 |
| static bool handleFmt10t_Fmt20t_Fmt30t(CompilationUnit *cUnit, MIR *mir, |
| BasicBlock *bb, X86LIR *labelList) |
| { |
| /* For OP_GOTO, OP_GOTO_16, and OP_GOTO_32 */ |
| return true; |
| } |
| |
| static bool handleFmt10x(CompilationUnit *cUnit, MIR *mir) |
| { |
| return true; |
| } |
| |
| static bool handleFmt11n_Fmt31i(CompilationUnit *cUnit, MIR *mir) |
| { |
| return true; |
| } |
| |
| static bool handleFmt21h(CompilationUnit *cUnit, MIR *mir) |
| { |
| return true; |
| } |
| |
| static bool handleFmt20bc(CompilationUnit *cUnit, MIR *mir) |
| { |
| return true; |
| } |
| |
| static bool handleFmt21c_Fmt31c(CompilationUnit *cUnit, MIR *mir) |
| { |
| return true; |
| } |
| |
| static bool handleFmt11x(CompilationUnit *cUnit, MIR *mir) |
| { |
| return true; |
| } |
| |
| static bool handleFmt12x(CompilationUnit *cUnit, MIR *mir) |
| { |
| return true; |
| } |
| |
| static bool handleFmt21s(CompilationUnit *cUnit, MIR *mir) |
| { |
| return true; |
| } |
| |
| static bool handleFmt21t(CompilationUnit *cUnit, MIR *mir, BasicBlock *bb, |
| X86LIR *labelList) |
| { |
| return true; |
| } |
| |
| static bool handleFmt22b_Fmt22s(CompilationUnit *cUnit, MIR *mir) |
| { |
| return true; |
| } |
| |
| static bool handleFmt22c(CompilationUnit *cUnit, MIR *mir) |
| { |
| return true; |
| } |
| |
| static bool handleFmt22cs(CompilationUnit *cUnit, MIR *mir) |
| { |
| return true; |
| } |
| |
| static bool handleFmt22t(CompilationUnit *cUnit, MIR *mir, BasicBlock *bb, |
| X86LIR *labelList) |
| { |
| return true; |
| } |
| |
| static bool handleFmt22x_Fmt32x(CompilationUnit *cUnit, MIR *mir) |
| { |
| return true; |
| } |
| |
| static bool handleFmt23x(CompilationUnit *cUnit, MIR *mir) |
| { |
| return true; |
| } |
| |
| static bool handleFmt31t(CompilationUnit *cUnit, MIR *mir) |
| { |
| return true; |
| } |
| |
| static bool handleFmt35c_3rc(CompilationUnit *cUnit, MIR *mir, BasicBlock *bb, |
| X86LIR *labelList) |
| { |
| return true; |
| } |
| |
| static bool handleFmt35ms_3rms(CompilationUnit *cUnit, MIR *mir, |
| BasicBlock *bb, X86LIR *labelList) |
| { |
| return true; |
| } |
| |
| /* |
| * NOTE: Handles both range and non-range versions (arguments |
| * have already been normalized by this point). |
| */ |
| static bool handleExecuteInline(CompilationUnit *cUnit, MIR *mir) |
| { |
| return true; |
| } |
| |
| static bool handleFmt51l(CompilationUnit *cUnit, MIR *mir) |
| { |
| return true; |
| } |
| #endif |
| |
| |
| void dvmCompilerMIR2LIR(CompilationUnit *cUnit) |
| { |
| } |
| |
| /* Accept the work and start compiling */ |
| bool dvmCompilerDoWork(CompilerWorkOrder *work) |
| { |
| bool res; |
| |
| if (gDvmJit.codeCacheFull) { |
| return false; |
| } |
| |
| switch (work->kind) { |
| case kWorkOrderTrace: |
| /* Start compilation with maximally allowed trace length */ |
| res = dvmCompileTrace(work->info, JIT_MAX_TRACE_LEN, &work->result, |
| work->bailPtr, 0 /* no hints */); |
| break; |
| case kWorkOrderTraceDebug: { |
| bool oldPrintMe = gDvmJit.printMe; |
| gDvmJit.printMe = true; |
| /* Start compilation with maximally allowed trace length */ |
| res = dvmCompileTrace(work->info, JIT_MAX_TRACE_LEN, &work->result, |
| work->bailPtr, 0 /* no hints */); |
| gDvmJit.printMe = oldPrintMe; |
| break; |
| } |
| default: |
| res = false; |
| LOGE("Jit: unknown work order type"); |
| assert(0); // Bail if debug build, discard otherwise |
| } |
| return res; |
| } |
| |
| /* Architectural-specific debugging helpers go here */ |
| void dvmCompilerArchDump(void) |
| { |
| /* Print compiled opcode in this VM instance */ |
| int i, start, streak; |
| char buf[1024]; |
| |
| streak = i = 0; |
| buf[0] = 0; |
| while (opcodeCoverage[i] == 0 && i < kNumPackedOpcodes) { |
| i++; |
| } |
| if (i == kNumPackedOpcodes) { |
| return; |
| } |
| for (start = i++, streak = 1; i < kNumPackedOpcodes; i++) { |
| if (opcodeCoverage[i]) { |
| streak++; |
| } else { |
| if (streak == 1) { |
| sprintf(buf+strlen(buf), "%x,", start); |
| } else { |
| sprintf(buf+strlen(buf), "%x-%x,", start, start + streak - 1); |
| } |
| streak = 0; |
| while (opcodeCoverage[i] == 0 && i < kNumPackedOpcodes) { |
| i++; |
| } |
| if (i < kNumPackedOpcodes) { |
| streak = 1; |
| start = i; |
| } |
| } |
| } |
| if (streak) { |
| if (streak == 1) { |
| sprintf(buf+strlen(buf), "%x", start); |
| } else { |
| sprintf(buf+strlen(buf), "%x-%x", start, start + streak - 1); |
| } |
| } |
| if (strlen(buf)) { |
| LOGD("dalvik.vm.jit.op = %s", buf); |
| } |
| } |
| |
| /* Common initialization routine for an architecture family */ |
| bool dvmCompilerArchInit() |
| { |
| return dvmCompilerArchVariantInit(); |
| } |
| |
| void *dvmCompilerGetInterpretTemplate() |
| { |
| return (void*) ((int)gDvmJit.codeCache + |
| templateEntryOffsets[TEMPLATE_INTERPRET]); |
| } |
| |
| void dvmCompilerInitializeRegAlloc(CompilationUnit *cUnit) |
| { |
| } |