Quick compiler: Single .so for all targets
With this CL, all targets can be built into a single .so (but
we're not yet doing so - the compiler driver needs to be reworked).
A new Codgen class is introduced (see compiler/codegen/codegen.h),
along with target-specific sub-classes ArmCodegen, MipsCodegens and
X86Codegen (see compiler/codegen/*/codegen_[Arm|Mips|X86].h).
Additional minor code, comment and format refactoring. Some source
files combined, temporary header files deleted and a few file
renames to better identify their function.
Next up is combining the Quick and Portable .so files.
Note: building all targets into libdvm-compiler.so increases its
size by 140K bytes. I'm inclined to not bother introducing conditional
compilation to limit code to the specific target - the added build and
testing complexity doesn't doesn't seem worth such a modest size savings.
Change-Id: Id9c5b4502ad6b77cdb31f71d3126f51a4f2e9dfe
diff --git a/src/compiler/codegen/gen_invoke.cc b/src/compiler/codegen/gen_invoke.cc
index 91d3db1..41924e2 100644
--- a/src/compiler/codegen/gen_invoke.cc
+++ b/src/compiler/codegen/gen_invoke.cc
@@ -28,6 +28,206 @@
*/
/*
+ * To save scheduling time, helper calls are broken into two parts: generation of
+ * the helper target address, and the actuall call to the helper. Because x86
+ * has a memory call operation, part 1 is a NOP for x86. For other targets,
+ * load arguments between the two parts.
+ */
+int Codegen::CallHelperSetup(CompilationUnit* cu, int helper_offset)
+{
+ return (cu->instruction_set == kX86) ? 0 : LoadHelper(cu, helper_offset);
+}
+
+/* NOTE: if r_tgt is a temp, it will be freed following use */
+LIR* Codegen::CallHelper(CompilationUnit* cu, int r_tgt, int helper_offset, bool safepoint_pc)
+{
+ LIR* call_inst;
+ if (cu->instruction_set == kX86) {
+ call_inst = OpThreadMem(cu, kOpBlx, helper_offset);
+ } else {
+ call_inst = OpReg(cu, kOpBlx, r_tgt);
+ FreeTemp(cu, r_tgt);
+ }
+ if (safepoint_pc) {
+ MarkSafepointPC(cu, call_inst);
+ }
+ return call_inst;
+}
+
+void Codegen::CallRuntimeHelperImm(CompilationUnit* cu, int helper_offset, int arg0,
+ bool safepoint_pc) {
+ int r_tgt = CallHelperSetup(cu, helper_offset);
+ LoadConstant(cu, TargetReg(kArg0), arg0);
+ ClobberCalleeSave(cu);
+ CallHelper(cu, r_tgt, helper_offset, safepoint_pc);
+}
+
+void Codegen::CallRuntimeHelperReg(CompilationUnit* cu, int helper_offset, int arg0,
+ bool safepoint_pc) {
+ int r_tgt = CallHelperSetup(cu, helper_offset);
+ OpRegCopy(cu, TargetReg(kArg0), arg0);
+ ClobberCalleeSave(cu);
+ CallHelper(cu, r_tgt, helper_offset, safepoint_pc);
+}
+
+void Codegen::CallRuntimeHelperRegLocation(CompilationUnit* cu, int helper_offset, RegLocation arg0,
+ bool safepoint_pc) {
+ int r_tgt = CallHelperSetup(cu, helper_offset);
+ if (arg0.wide == 0) {
+ LoadValueDirectFixed(cu, arg0, TargetReg(kArg0));
+ } else {
+ LoadValueDirectWideFixed(cu, arg0, TargetReg(kArg0), TargetReg(kArg1));
+ }
+ ClobberCalleeSave(cu);
+ CallHelper(cu, r_tgt, helper_offset, safepoint_pc);
+}
+
+void Codegen::CallRuntimeHelperImmImm(CompilationUnit* cu, int helper_offset, int arg0, int arg1,
+ bool safepoint_pc) {
+ int r_tgt = CallHelperSetup(cu, helper_offset);
+ LoadConstant(cu, TargetReg(kArg0), arg0);
+ LoadConstant(cu, TargetReg(kArg1), arg1);
+ ClobberCalleeSave(cu);
+ CallHelper(cu, r_tgt, helper_offset, safepoint_pc);
+}
+
+void Codegen::CallRuntimeHelperImmRegLocation(CompilationUnit* cu, int helper_offset, int arg0,
+ RegLocation arg1, bool safepoint_pc) {
+ int r_tgt = CallHelperSetup(cu, helper_offset);
+ if (arg1.wide == 0) {
+ LoadValueDirectFixed(cu, arg1, TargetReg(kArg1));
+ } else {
+ LoadValueDirectWideFixed(cu, arg1, TargetReg(kArg1), TargetReg(kArg2));
+ }
+ LoadConstant(cu, TargetReg(kArg0), arg0);
+ ClobberCalleeSave(cu);
+ CallHelper(cu, r_tgt, helper_offset, safepoint_pc);
+}
+
+void Codegen::CallRuntimeHelperRegLocationImm(CompilationUnit* cu, int helper_offset,
+ RegLocation arg0, int arg1, bool safepoint_pc) {
+ int r_tgt = CallHelperSetup(cu, helper_offset);
+ LoadValueDirectFixed(cu, arg0, TargetReg(kArg0));
+ LoadConstant(cu, TargetReg(kArg1), arg1);
+ ClobberCalleeSave(cu);
+ CallHelper(cu, r_tgt, helper_offset, safepoint_pc);
+}
+
+void Codegen::CallRuntimeHelperImmReg(CompilationUnit* cu, int helper_offset, int arg0, int arg1,
+ bool safepoint_pc) {
+ int r_tgt = CallHelperSetup(cu, helper_offset);
+ OpRegCopy(cu, TargetReg(kArg1), arg1);
+ LoadConstant(cu, TargetReg(kArg0), arg0);
+ ClobberCalleeSave(cu);
+ CallHelper(cu, r_tgt, helper_offset, safepoint_pc);
+}
+
+void Codegen::CallRuntimeHelperRegImm(CompilationUnit* cu, int helper_offset, int arg0, int arg1,
+ bool safepoint_pc) {
+ int r_tgt = CallHelperSetup(cu, helper_offset);
+ OpRegCopy(cu, TargetReg(kArg0), arg0);
+ LoadConstant(cu, TargetReg(kArg1), arg1);
+ ClobberCalleeSave(cu);
+ CallHelper(cu, r_tgt, helper_offset, safepoint_pc);
+}
+
+void Codegen::CallRuntimeHelperImmMethod(CompilationUnit* cu, int helper_offset, int arg0,
+ bool safepoint_pc) {
+ int r_tgt = CallHelperSetup(cu, helper_offset);
+ LoadCurrMethodDirect(cu, TargetReg(kArg1));
+ LoadConstant(cu, TargetReg(kArg0), arg0);
+ ClobberCalleeSave(cu);
+ CallHelper(cu, r_tgt, helper_offset, safepoint_pc);
+}
+
+void Codegen::CallRuntimeHelperRegLocationRegLocation(CompilationUnit* cu, int helper_offset,
+ RegLocation arg0, RegLocation arg1,
+ bool safepoint_pc) {
+ int r_tgt = CallHelperSetup(cu, helper_offset);
+ if (arg0.wide == 0) {
+ LoadValueDirectFixed(cu, arg0, arg0.fp ? TargetReg(kFArg0) : TargetReg(kArg0));
+ if (arg1.wide == 0) {
+ if (cu->instruction_set == kMips) {
+ LoadValueDirectFixed(cu, arg1, arg1.fp ? TargetReg(kFArg2) : TargetReg(kArg1));
+ } else {
+ LoadValueDirectFixed(cu, arg1, TargetReg(kArg1));
+ }
+ } else {
+ if (cu->instruction_set == kMips) {
+ LoadValueDirectWideFixed(cu, arg1, arg1.fp ? TargetReg(kFArg2) : TargetReg(kArg1), arg1.fp ? TargetReg(kFArg3) : TargetReg(kArg2));
+ } else {
+ LoadValueDirectWideFixed(cu, arg1, TargetReg(kArg1), TargetReg(kArg2));
+ }
+ }
+ } else {
+ LoadValueDirectWideFixed(cu, arg0, arg0.fp ? TargetReg(kFArg0) : TargetReg(kArg0), arg0.fp ? TargetReg(kFArg1) : TargetReg(kArg1));
+ if (arg1.wide == 0) {
+ LoadValueDirectFixed(cu, arg1, arg1.fp ? TargetReg(kFArg2) : TargetReg(kArg2));
+ } else {
+ LoadValueDirectWideFixed(cu, arg1, arg1.fp ? TargetReg(kFArg2) : TargetReg(kArg2), arg1.fp ? TargetReg(kFArg3) : TargetReg(kArg3));
+ }
+ }
+ ClobberCalleeSave(cu);
+ CallHelper(cu, r_tgt, helper_offset, safepoint_pc);
+}
+
+void Codegen::CallRuntimeHelperRegReg(CompilationUnit* cu, int helper_offset, int arg0, int arg1,
+ bool safepoint_pc) {
+ int r_tgt = CallHelperSetup(cu, helper_offset);
+ DCHECK_NE(TargetReg(kArg0), arg1); // check copy into arg0 won't clobber arg1
+ OpRegCopy(cu, TargetReg(kArg0), arg0);
+ OpRegCopy(cu, TargetReg(kArg1), arg1);
+ ClobberCalleeSave(cu);
+ CallHelper(cu, r_tgt, helper_offset, safepoint_pc);
+}
+
+void Codegen::CallRuntimeHelperRegRegImm(CompilationUnit* cu, int helper_offset, int arg0, int arg1,
+ int arg2, bool safepoint_pc) {
+ int r_tgt = CallHelperSetup(cu, helper_offset);
+ DCHECK_NE(TargetReg(kArg0), arg1); // check copy into arg0 won't clobber arg1
+ OpRegCopy(cu, TargetReg(kArg0), arg0);
+ OpRegCopy(cu, TargetReg(kArg1), arg1);
+ LoadConstant(cu, TargetReg(kArg2), arg2);
+ ClobberCalleeSave(cu);
+ CallHelper(cu, r_tgt, helper_offset, safepoint_pc);
+}
+
+void Codegen::CallRuntimeHelperImmMethodRegLocation(CompilationUnit* cu, int helper_offset,
+ int arg0, RegLocation arg2, bool safepoint_pc) {
+ int r_tgt = CallHelperSetup(cu, helper_offset);
+ LoadValueDirectFixed(cu, arg2, TargetReg(kArg2));
+ LoadCurrMethodDirect(cu, TargetReg(kArg1));
+ LoadConstant(cu, TargetReg(kArg0), arg0);
+ ClobberCalleeSave(cu);
+ CallHelper(cu, r_tgt, helper_offset, safepoint_pc);
+}
+
+void Codegen::CallRuntimeHelperImmMethodImm(CompilationUnit* cu, int helper_offset, int arg0,
+ int arg2, bool safepoint_pc) {
+ int r_tgt = CallHelperSetup(cu, helper_offset);
+ LoadCurrMethodDirect(cu, TargetReg(kArg1));
+ LoadConstant(cu, TargetReg(kArg2), arg2);
+ LoadConstant(cu, TargetReg(kArg0), arg0);
+ ClobberCalleeSave(cu);
+ CallHelper(cu, r_tgt, helper_offset, safepoint_pc);
+}
+
+void Codegen::CallRuntimeHelperImmRegLocationRegLocation(CompilationUnit* cu, int helper_offset,
+ int arg0, RegLocation arg1,
+ RegLocation arg2, bool safepoint_pc) {
+ int r_tgt = CallHelperSetup(cu, helper_offset);
+ LoadValueDirectFixed(cu, arg1, TargetReg(kArg1));
+ if (arg2.wide == 0) {
+ LoadValueDirectFixed(cu, arg2, TargetReg(kArg2));
+ } else {
+ LoadValueDirectWideFixed(cu, arg2, TargetReg(kArg2), TargetReg(kArg3));
+ }
+ LoadConstant(cu, TargetReg(kArg0), arg0);
+ ClobberCalleeSave(cu);
+ CallHelper(cu, r_tgt, helper_offset, safepoint_pc);
+}
+
+/*
* If there are any ins passed in registers that have not been promoted
* to a callee-save register, flush them to the frame. Perform intial
* assignment of promoted arguments.
@@ -35,7 +235,7 @@
* ArgLocs is an array of location records describing the incoming arguments
* with one location record per word of argument.
*/
-void FlushIns(CompilationUnit* cu, RegLocation* ArgLocs, RegLocation rl_method)
+void Codegen::FlushIns(CompilationUnit* cu, RegLocation* ArgLocs, RegLocation rl_method)
{
/*
* Dummy up a RegLocation for the incoming Method*
@@ -119,6 +319,7 @@
uintptr_t direct_code, uintptr_t direct_method,
InvokeType type)
{
+ Codegen* cg = cu->cg.get();
if (cu->instruction_set != kThumb2) {
// Disable sharpening
direct_code = 0;
@@ -128,26 +329,26 @@
switch (state) {
case 0: // Get the current Method* [sets kArg0]
if (direct_code != static_cast<unsigned int>(-1)) {
- LoadConstant(cu, TargetReg(kInvokeTgt), direct_code);
+ cg->LoadConstant(cu, cg->TargetReg(kInvokeTgt), direct_code);
} else {
LIR* data_target = ScanLiteralPool(cu->code_literal_list, dex_idx, 0);
if (data_target == NULL) {
data_target = AddWordData(cu, &cu->code_literal_list, dex_idx);
data_target->operands[1] = type;
}
- LIR* load_pc_rel = OpPcRelLoad(cu, TargetReg(kInvokeTgt), data_target);
+ LIR* load_pc_rel = cg->OpPcRelLoad(cu, cg->TargetReg(kInvokeTgt), data_target);
AppendLIR(cu, load_pc_rel);
DCHECK_EQ(cu->instruction_set, kThumb2) << reinterpret_cast<void*>(data_target);
}
if (direct_method != static_cast<unsigned int>(-1)) {
- LoadConstant(cu, TargetReg(kArg0), direct_method);
+ cg->LoadConstant(cu, cg->TargetReg(kArg0), direct_method);
} else {
LIR* data_target = ScanLiteralPool(cu->method_literal_list, dex_idx, 0);
if (data_target == NULL) {
data_target = AddWordData(cu, &cu->method_literal_list, dex_idx);
data_target->operands[1] = type;
}
- LIR* load_pc_rel = OpPcRelLoad(cu, TargetReg(kArg0), data_target);
+ LIR* load_pc_rel = cg->OpPcRelLoad(cu, cg->TargetReg(kArg0), data_target);
AppendLIR(cu, load_pc_rel);
DCHECK_EQ(cu->instruction_set, kThumb2) << reinterpret_cast<void*>(data_target);
}
@@ -159,36 +360,37 @@
switch (state) {
case 0: // Get the current Method* [sets kArg0]
// TUNING: we can save a reg copy if Method* has been promoted.
- LoadCurrMethodDirect(cu, TargetReg(kArg0));
+ cg->LoadCurrMethodDirect(cu, cg->TargetReg(kArg0));
break;
case 1: // Get method->dex_cache_resolved_methods_
- LoadWordDisp(cu, TargetReg(kArg0),
- AbstractMethod::DexCacheResolvedMethodsOffset().Int32Value(), TargetReg(kArg0));
+ cg->LoadWordDisp(cu, cg->TargetReg(kArg0),
+ AbstractMethod::DexCacheResolvedMethodsOffset().Int32Value(), cg->TargetReg(kArg0));
// Set up direct code if known.
if (direct_code != 0) {
if (direct_code != static_cast<unsigned int>(-1)) {
- LoadConstant(cu, TargetReg(kInvokeTgt), direct_code);
+ cg->LoadConstant(cu, cg->TargetReg(kInvokeTgt), direct_code);
} else {
LIR* data_target = ScanLiteralPool(cu->code_literal_list, dex_idx, 0);
if (data_target == NULL) {
data_target = AddWordData(cu, &cu->code_literal_list, dex_idx);
data_target->operands[1] = type;
}
- LIR* load_pc_rel = OpPcRelLoad(cu, TargetReg(kInvokeTgt), data_target);
+ LIR* load_pc_rel = cg->OpPcRelLoad(cu, cg->TargetReg(kInvokeTgt), data_target);
AppendLIR(cu, load_pc_rel);
DCHECK_EQ(cu->instruction_set, kThumb2) << reinterpret_cast<void*>(data_target);
}
}
break;
case 2: // Grab target method*
- LoadWordDisp(cu, TargetReg(kArg0),
- Array::DataOffset(sizeof(Object*)).Int32Value() + dex_idx * 4, TargetReg(kArg0));
+ cg->LoadWordDisp(cu, cg->TargetReg(kArg0),
+ Array::DataOffset(sizeof(Object*)).Int32Value() + dex_idx * 4,
+ cg-> TargetReg(kArg0));
break;
case 3: // Grab the code from the method*
if (cu->instruction_set != kX86) {
if (direct_code == 0) {
- LoadWordDisp(cu, TargetReg(kArg0), AbstractMethod::GetCodeOffset().Int32Value(),
- TargetReg(kInvokeTgt));
+ cg->LoadWordDisp(cu, cg->TargetReg(kArg0), AbstractMethod::GetCodeOffset().Int32Value(),
+ cg->TargetReg(kInvokeTgt));
}
break;
}
@@ -211,6 +413,7 @@
int state, uint32_t dex_idx, uint32_t method_idx,
uintptr_t unused, uintptr_t unused2, InvokeType unused3)
{
+ Codegen* cg = cu->cg.get();
/*
* This is the fast path in which the target virtual method is
* fully resolved at compile time.
@@ -218,27 +421,27 @@
switch (state) {
case 0: { // Get "this" [set kArg1]
RegLocation rl_arg = info->args[0];
- LoadValueDirectFixed(cu, rl_arg, TargetReg(kArg1));
+ cg->LoadValueDirectFixed(cu, rl_arg, cg->TargetReg(kArg1));
break;
}
case 1: // Is "this" null? [use kArg1]
- GenNullCheck(cu, info->args[0].s_reg_low, TargetReg(kArg1), info->opt_flags);
+ cg->GenNullCheck(cu, info->args[0].s_reg_low, cg->TargetReg(kArg1), info->opt_flags);
// get this->klass_ [use kArg1, set kInvokeTgt]
- LoadWordDisp(cu, TargetReg(kArg1), Object::ClassOffset().Int32Value(),
- TargetReg(kInvokeTgt));
+ cg->LoadWordDisp(cu, cg->TargetReg(kArg1), Object::ClassOffset().Int32Value(),
+ cg->TargetReg(kInvokeTgt));
break;
case 2: // Get this->klass_->vtable [usr kInvokeTgt, set kInvokeTgt]
- LoadWordDisp(cu, TargetReg(kInvokeTgt), Class::VTableOffset().Int32Value(),
- TargetReg(kInvokeTgt));
+ cg->LoadWordDisp(cu, cg->TargetReg(kInvokeTgt), Class::VTableOffset().Int32Value(),
+ cg->TargetReg(kInvokeTgt));
break;
case 3: // Get target method [use kInvokeTgt, set kArg0]
- LoadWordDisp(cu, TargetReg(kInvokeTgt), (method_idx * 4) +
- Array::DataOffset(sizeof(Object*)).Int32Value(), TargetReg(kArg0));
+ cg->LoadWordDisp(cu, cg->TargetReg(kInvokeTgt), (method_idx * 4) +
+ Array::DataOffset(sizeof(Object*)).Int32Value(), cg->TargetReg(kArg0));
break;
case 4: // Get the compiled code address [uses kArg0, sets kInvokeTgt]
if (cu->instruction_set != kX86) {
- LoadWordDisp(cu, TargetReg(kArg0), AbstractMethod::GetCodeOffset().Int32Value(),
- TargetReg(kInvokeTgt));
+ cg->LoadWordDisp(cu, cg->TargetReg(kArg0), AbstractMethod::GetCodeOffset().Int32Value(),
+ cg->TargetReg(kInvokeTgt));
break;
}
// Intentional fallthrough for X86
@@ -256,6 +459,7 @@
uint32_t dex_idx, uint32_t unused, uintptr_t unused2,
uintptr_t direct_method, InvokeType unused4)
{
+ Codegen* cg = cu->cg.get();
if (cu->instruction_set != kThumb2) {
// Disable sharpening
direct_method = 0;
@@ -267,18 +471,18 @@
switch (state) {
case 0: // Load the trampoline target [sets kInvokeTgt].
if (cu->instruction_set != kX86) {
- LoadWordDisp(cu, TargetReg(kSelf), trampoline, TargetReg(kInvokeTgt));
+ cg->LoadWordDisp(cu, cg->TargetReg(kSelf), trampoline, cg->TargetReg(kInvokeTgt));
}
// Get the interface Method* [sets kArg0]
if (direct_method != static_cast<unsigned int>(-1)) {
- LoadConstant(cu, TargetReg(kArg0), direct_method);
+ cg->LoadConstant(cu, cg->TargetReg(kArg0), direct_method);
} else {
LIR* data_target = ScanLiteralPool(cu->method_literal_list, dex_idx, 0);
if (data_target == NULL) {
data_target = AddWordData(cu, &cu->method_literal_list, dex_idx);
data_target->operands[1] = kInterface;
}
- LIR* load_pc_rel = OpPcRelLoad(cu, TargetReg(kArg0), data_target);
+ LIR* load_pc_rel = cg->OpPcRelLoad(cu, cg->TargetReg(kArg0), data_target);
AppendLIR(cu, load_pc_rel);
DCHECK_EQ(cu->instruction_set, kThumb2) << reinterpret_cast<void*>(data_target);
}
@@ -290,21 +494,21 @@
switch (state) {
case 0:
// Get the current Method* [sets kArg0] - TUNING: remove copy of method if it is promoted.
- LoadCurrMethodDirect(cu, TargetReg(kArg0));
+ cg->LoadCurrMethodDirect(cu, cg->TargetReg(kArg0));
// Load the trampoline target [sets kInvokeTgt].
if (cu->instruction_set != kX86) {
- LoadWordDisp(cu, TargetReg(kSelf), trampoline, TargetReg(kInvokeTgt));
+ cg->LoadWordDisp(cu, cg->TargetReg(kSelf), trampoline, cg->TargetReg(kInvokeTgt));
}
break;
case 1: // Get method->dex_cache_resolved_methods_ [set/use kArg0]
- LoadWordDisp(cu, TargetReg(kArg0),
- AbstractMethod::DexCacheResolvedMethodsOffset().Int32Value(),
- TargetReg(kArg0));
+ cg->LoadWordDisp(cu, cg->TargetReg(kArg0),
+ AbstractMethod::DexCacheResolvedMethodsOffset().Int32Value(),
+ cg->TargetReg(kArg0));
break;
case 2: // Grab target method* [set/use kArg0]
- LoadWordDisp(cu, TargetReg(kArg0),
- Array::DataOffset(sizeof(Object*)).Int32Value() + dex_idx * 4,
- TargetReg(kArg0));
+ cg->LoadWordDisp(cu, cg->TargetReg(kArg0),
+ Array::DataOffset(sizeof(Object*)).Int32Value() + dex_idx * 4,
+ cg->TargetReg(kArg0));
break;
default:
return -1;
@@ -316,6 +520,7 @@
static int NextInvokeInsnSP(CompilationUnit* cu, CallInfo* info, int trampoline,
int state, uint32_t dex_idx, uint32_t method_idx)
{
+ Codegen* cg = cu->cg.get();
/*
* This handles the case in which the base method is not fully
* resolved at compile time, we bail to a runtime helper.
@@ -323,10 +528,10 @@
if (state == 0) {
if (cu->instruction_set != kX86) {
// Load trampoline target
- LoadWordDisp(cu, TargetReg(kSelf), trampoline, TargetReg(kInvokeTgt));
+ cg->LoadWordDisp(cu, cg->TargetReg(kSelf), trampoline, cg->TargetReg(kInvokeTgt));
}
// Load kArg0 with method index
- LoadConstant(cu, TargetReg(kArg0), dex_idx);
+ cg->LoadConstant(cu, cg->TargetReg(kArg0), dex_idx);
return 1;
}
return -1;
@@ -380,8 +585,9 @@
uint32_t method_idx, uintptr_t direct_code,
uintptr_t direct_method, InvokeType type, bool skip_this)
{
- int last_arg_reg = TargetReg(kArg3);
- int next_reg = TargetReg(kArg1);
+ Codegen* cg = cu->cg.get();
+ int last_arg_reg = cg->TargetReg(kArg3);
+ int next_reg = cg->TargetReg(kArg1);
int next_arg = 0;
if (skip_this) {
next_reg++;
@@ -390,13 +596,13 @@
for (; (next_reg <= last_arg_reg) && (next_arg < info->num_arg_words); next_reg++) {
RegLocation rl_arg = info->args[next_arg++];
rl_arg = UpdateRawLoc(cu, rl_arg);
- if (rl_arg.wide && (next_reg <= TargetReg(kArg2))) {
- LoadValueDirectWideFixed(cu, rl_arg, next_reg, next_reg + 1);
+ if (rl_arg.wide && (next_reg <= cg->TargetReg(kArg2))) {
+ cg->LoadValueDirectWideFixed(cu, rl_arg, next_reg, next_reg + 1);
next_reg++;
next_arg++;
} else {
rl_arg.wide = false;
- LoadValueDirectFixed(cu, rl_arg, next_reg);
+ cg->LoadValueDirectFixed(cu, rl_arg, next_reg);
}
call_state = next_call_insn(cu, info, call_state, dex_idx, method_idx,
direct_code, direct_method, type);
@@ -411,12 +617,10 @@
* the target method pointer. Note, this may also be called
* for "range" variants if the number of arguments is 5 or fewer.
*/
-int GenDalvikArgsNoRange(CompilationUnit* cu, CallInfo* info,
- int call_state,
- LIR** pcrLabel, NextCallInsn next_call_insn,
- uint32_t dex_idx, uint32_t method_idx,
- uintptr_t direct_code, uintptr_t direct_method,
- InvokeType type, bool skip_this)
+int Codegen::GenDalvikArgsNoRange(CompilationUnit* cu, CallInfo* info,
+ int call_state, LIR** pcrLabel, NextCallInsn next_call_insn,
+ uint32_t dex_idx, uint32_t method_idx, uintptr_t direct_code,
+ uintptr_t direct_method, InvokeType type, bool skip_this)
{
RegLocation rl_arg;
@@ -512,11 +716,10 @@
* Pass arg0, arg1 & arg2 in kArg1-kArg3
*
*/
-int GenDalvikArgsRange(CompilationUnit* cu, CallInfo* info, int call_state,
- LIR** pcrLabel, NextCallInsn next_call_insn,
- uint32_t dex_idx, uint32_t method_idx,
- uintptr_t direct_code, uintptr_t direct_method,
- InvokeType type, bool skip_this)
+int Codegen::GenDalvikArgsRange(CompilationUnit* cu, CallInfo* info, int call_state,
+ LIR** pcrLabel, NextCallInsn next_call_insn, uint32_t dex_idx,
+ uint32_t method_idx, uintptr_t direct_code, uintptr_t direct_method,
+ InvokeType type, bool skip_this)
{
// If we can treat it as non-range (Jumbo ops will use range form)
@@ -574,14 +777,14 @@
LIR* ld = OpVldm(cu, TargetReg(kArg3), regs_left);
//TUNING: loosen barrier
ld->def_mask = ENCODE_ALL;
- SetMemRefType(ld, true /* is_load */, kDalvikReg);
+ SetMemRefType(cu, ld, true /* is_load */, kDalvikReg);
call_state = next_call_insn(cu, info, call_state, dex_idx, method_idx,
direct_code, direct_method, type);
OpRegRegImm(cu, kOpAdd, TargetReg(kArg3), TargetReg(kSp), 4 /* Method* */ + (3 * 4));
call_state = next_call_insn(cu, info, call_state, dex_idx, method_idx,
direct_code, direct_method, type);
LIR* st = OpVstm(cu, TargetReg(kArg3), regs_left);
- SetMemRefType(st, false /* is_load */, kDalvikReg);
+ SetMemRefType(cu, st, false /* is_load */, kDalvikReg);
st->def_mask = ENCODE_ALL;
call_state = next_call_insn(cu, info, call_state, dex_idx, method_idx,
direct_code, direct_method, type);
@@ -601,7 +804,7 @@
return call_state;
}
-RegLocation InlineTarget(CompilationUnit* cu, CallInfo* info)
+RegLocation Codegen::InlineTarget(CompilationUnit* cu, CallInfo* info)
{
RegLocation res;
if (info->result.location == kLocInvalid) {
@@ -612,7 +815,7 @@
return res;
}
-RegLocation InlineTargetWide(CompilationUnit* cu, CallInfo* info)
+RegLocation Codegen::InlineTargetWide(CompilationUnit* cu, CallInfo* info)
{
RegLocation res;
if (info->result.location == kLocInvalid) {
@@ -623,7 +826,7 @@
return res;
}
-bool GenInlinedCharAt(CompilationUnit* cu, CallInfo* info)
+bool Codegen::GenInlinedCharAt(CompilationUnit* cu, CallInfo* info)
{
if (cu->instruction_set == kMips) {
// TODO - add Mips implementation
@@ -702,8 +905,7 @@
}
// Generates an inlined String.is_empty or String.length.
-bool GenInlinedStringIsEmptyOrLength(CompilationUnit* cu, CallInfo* info,
- bool is_empty)
+bool Codegen::GenInlinedStringIsEmptyOrLength(CompilationUnit* cu, CallInfo* info, bool is_empty)
{
if (cu->instruction_set == kMips) {
// TODO - add Mips implementation
@@ -733,7 +935,7 @@
return true;
}
-bool GenInlinedAbsInt(CompilationUnit *cu, CallInfo* info)
+bool Codegen::GenInlinedAbsInt(CompilationUnit *cu, CallInfo* info)
{
if (cu->instruction_set == kMips) {
// TODO - add Mips implementation
@@ -752,7 +954,7 @@
return true;
}
-bool GenInlinedAbsLong(CompilationUnit *cu, CallInfo* info)
+bool Codegen::GenInlinedAbsLong(CompilationUnit *cu, CallInfo* info)
{
if (cu->instruction_set == kMips) {
// TODO - add Mips implementation
@@ -794,7 +996,7 @@
}
}
-bool GenInlinedFloatCvt(CompilationUnit *cu, CallInfo* info)
+bool Codegen::GenInlinedFloatCvt(CompilationUnit *cu, CallInfo* info)
{
if (cu->instruction_set == kMips) {
// TODO - add Mips implementation
@@ -806,7 +1008,7 @@
return true;
}
-bool GenInlinedDoubleCvt(CompilationUnit *cu, CallInfo* info)
+bool Codegen::GenInlinedDoubleCvt(CompilationUnit *cu, CallInfo* info)
{
if (cu->instruction_set == kMips) {
// TODO - add Mips implementation
@@ -822,8 +1024,7 @@
* Fast string.index_of(I) & (II). Tests for simple case of char <= 0xffff,
* otherwise bails to standard library code.
*/
-bool GenInlinedIndexOf(CompilationUnit* cu, CallInfo* info,
- bool zero_based)
+bool Codegen::GenInlinedIndexOf(CompilationUnit* cu, CallInfo* info, bool zero_based)
{
if (cu->instruction_set == kMips) {
// TODO - add Mips implementation
@@ -867,7 +1068,7 @@
}
/* Fast string.compareTo(Ljava/lang/string;)I. */
-bool GenInlinedStringCompareTo(CompilationUnit* cu, CallInfo* info)
+bool Codegen::GenInlinedStringCompareTo(CompilationUnit* cu, CallInfo* info)
{
if (cu->instruction_set == kMips) {
// TODO - add Mips implementation
@@ -904,7 +1105,7 @@
return true;
}
-bool GenIntrinsic(CompilationUnit* cu, CallInfo* info)
+bool Codegen::GenIntrinsic(CompilationUnit* cu, CallInfo* info)
{
if (info->opt_flags & MIR_INLINED) {
return false;
@@ -982,7 +1183,7 @@
return false;
}
-void GenInvoke(CompilationUnit* cu, CallInfo* info)
+void Codegen::GenInvoke(CompilationUnit* cu, CallInfo* info)
{
if (GenIntrinsic(cu, info)) {
return;
@@ -1109,8 +1310,8 @@
* high-word loc for wide arguments. Also pull up any following
* MOVE_RESULT and incorporate it into the invoke.
*/
-CallInfo* NewMemCallInfo(CompilationUnit* cu, BasicBlock* bb, MIR* mir,
- InvokeType type, bool is_range)
+CallInfo* Codegen::NewMemCallInfo(CompilationUnit* cu, BasicBlock* bb, MIR* mir, InvokeType type,
+ bool is_range)
{
CallInfo* info = static_cast<CallInfo*>(NewMem(cu, sizeof(CallInfo), true, kAllocMisc));
MIR* move_result_mir = FindMoveResult(cu, bb, mir);
@@ -1134,5 +1335,4 @@
return info;
}
-
} // namespace art