GenSpecialCase support for x86
Moved GenSpecialCase from being ARM specific to common code to allow
it to be used by x86 quick as well.
Change-Id: I728733e8f4c4da99af6091ef77e5c76ae0fee850
Signed-off-by: Razvan A Lupusoru <razvan.a.lupusoru@intel.com>
diff --git a/compiler/dex/quick/x86/call_x86.cc b/compiler/dex/quick/x86/call_x86.cc
index 7f646e0..0613cdf 100644
--- a/compiler/dex/quick/x86/call_x86.cc
+++ b/compiler/dex/quick/x86/call_x86.cc
@@ -22,11 +22,6 @@
namespace art {
-void X86Mir2Lir::GenSpecialCase(BasicBlock* bb, MIR* mir,
- const InlineMethod& special) {
- // TODO
-}
-
/*
* The sparse table in the literal pool is an array of <key,displacement>
* pairs.
@@ -255,4 +250,8 @@
NewLIR0(kX86Ret);
}
+void X86Mir2Lir::GenSpecialExitSequence() {
+ NewLIR0(kX86Ret);
+}
+
} // namespace art
diff --git a/compiler/dex/quick/x86/codegen_x86.h b/compiler/dex/quick/x86/codegen_x86.h
index 70263d8..6100a1d 100644
--- a/compiler/dex/quick/x86/codegen_x86.h
+++ b/compiler/dex/quick/x86/codegen_x86.h
@@ -52,6 +52,7 @@
int AllocTypedTempPair(bool fp_hint, int reg_class);
int S2d(int low_reg, int high_reg);
int TargetReg(SpecialTargetRegister reg);
+ int GetArgMappingToPhysicalReg(int arg_num);
RegLocation GetReturnAlt();
RegLocation GetReturnWideAlt();
RegLocation LocCReturn();
@@ -123,6 +124,7 @@
void GenDivZeroCheck(int reg_lo, int reg_hi);
void GenEntrySequence(RegLocation* ArgLocs, RegLocation rl_method);
void GenExitSequence();
+ void GenSpecialExitSequence();
void GenFillArrayData(DexOffset table_offset, RegLocation rl_src);
void GenFusedFPCmpBranch(BasicBlock* bb, MIR* mir, bool gt_bias, bool is_double);
void GenFusedLongCmpBranch(BasicBlock* bb, MIR* mir);
@@ -135,7 +137,7 @@
void GenNegFloat(RegLocation rl_dest, RegLocation rl_src);
void GenPackedSwitch(MIR* mir, DexOffset table_offset, RegLocation rl_src);
void GenSparseSwitch(MIR* mir, DexOffset table_offset, RegLocation rl_src);
- void GenSpecialCase(BasicBlock* bb, MIR* mir, const InlineMethod& special);
+
/*
* @brief Generate a two address long operation with a constant value
* @param rl_dest location of result
diff --git a/compiler/dex/quick/x86/int_x86.cc b/compiler/dex/quick/x86/int_x86.cc
index 9dd6116..9eb112b 100644
--- a/compiler/dex/quick/x86/int_x86.cc
+++ b/compiler/dex/quick/x86/int_x86.cc
@@ -167,7 +167,14 @@
NewLIR2(kX86MovdrxRR, dest_hi, src_lo);
} else {
// Handle overlap
- if (src_hi == dest_lo) {
+ if (src_hi == dest_lo && src_lo == dest_hi) {
+ // Deal with cycles.
+ int temp_reg = AllocTemp();
+ OpRegCopy(temp_reg, dest_hi);
+ OpRegCopy(dest_hi, dest_lo);
+ OpRegCopy(dest_lo, temp_reg);
+ FreeTemp(temp_reg);
+ } else if (src_hi == dest_lo) {
OpRegCopy(dest_hi, src_hi);
OpRegCopy(dest_lo, src_lo);
} else {
diff --git a/compiler/dex/quick/x86/target_x86.cc b/compiler/dex/quick/x86/target_x86.cc
index 1893ffc..8e04e64 100644
--- a/compiler/dex/quick/x86/target_x86.cc
+++ b/compiler/dex/quick/x86/target_x86.cc
@@ -92,6 +92,21 @@
return res;
}
+int X86Mir2Lir::GetArgMappingToPhysicalReg(int arg_num) {
+ // For the 32-bit internal ABI, the first 3 arguments are passed in registers.
+ // TODO: This is not 64-bit compliant and depends on new internal ABI.
+ switch (arg_num) {
+ case 0:
+ return rX86_ARG1;
+ case 1:
+ return rX86_ARG2;
+ case 2:
+ return rX86_ARG3;
+ default:
+ return INVALID_REG;
+ }
+}
+
// Create a double from a pair of singles.
int X86Mir2Lir::S2d(int low_reg, int high_reg) {
return X86_S2D(low_reg, high_reg);