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/mips/assemble_mips.cc b/src/compiler/codegen/mips/assemble_mips.cc
index 933cb60..4574a42 100644
--- a/src/compiler/codegen/mips/assemble_mips.cc
+++ b/src/compiler/codegen/mips/assemble_mips.cc
@@ -15,6 +15,7 @@
*/
#include "mips_lir.h"
+#include "codegen_mips.h"
#include "../codegen_util.h"
namespace art {
@@ -80,7 +81,7 @@
* is expanded to include a nop. This scheme should be replaced with
* an assembler pass to fill those slots when possible.
*/
-MipsEncodingMap EncodingMap[kMipsLast] = {
+const MipsEncodingMap MipsCodegen::EncodingMap[kMipsLast] = {
ENCODING_MAP(kMips32BitData, 0x00000000,
kFmtBitBlt, 31, 0, kFmtUnused, -1, -1, kFmtUnused, -1, -1,
kFmtUnused, -1, -1, IS_UNARY_OP,
@@ -305,7 +306,6 @@
kFmtBitBlt, 20, 16, kFmtBitBlt, 25, 21, kFmtBitBlt, 15, 0,
kFmtUnused, -1, -1, IS_TERTIARY_OP | REG_DEF0_USE1,
"xori", "!0r,!1r,0x!2h(!2d)", 4),
-#ifdef __mips_hard_float
ENCODING_MAP(kMipsFadds, 0x46000000,
kFmtSfp, 10, 6, kFmtSfp, 15, 11, kFmtSfp, 20, 16,
kFmtUnused, -1, -1, IS_TERTIARY_OP | REG_DEF0_USE12,
@@ -394,7 +394,6 @@
kFmtBitBlt, 20, 16, kFmtSfp, 15, 11, kFmtUnused, -1, -1,
kFmtUnused, -1, -1, IS_BINARY_OP | REG_USE0 | REG_DEF1,
"mtc1", "!0r,!1s", 4),
-#endif
ENCODING_MAP(kMipsDelta, 0x27e00000,
kFmtBitBlt, 20, 16, kFmtBitBlt, 15, 0, kFmtUnused, 15, 0,
kFmtUnused, -1, -1, IS_QUAD_OP | REG_DEF0 | REG_USE_LR |
@@ -514,8 +513,7 @@
* instruction. In those cases we will try to substitute a new code
* sequence or request that the trace be shortened and retried.
*/
-AssemblerStatus AssembleInstructions(CompilationUnit *cu,
- uintptr_t start_addr)
+AssemblerStatus MipsCodegen::AssembleInstructions(CompilationUnit *cu, uintptr_t start_addr)
{
LIR *lir;
AssemblerStatus res = kSuccess; // Assume success
@@ -710,7 +708,7 @@
return res;
}
-int GetInsnSize(LIR* lir)
+int MipsCodegen::GetInsnSize(LIR* lir)
{
return EncodingMap[lir->opcode].size;
}
@@ -718,7 +716,7 @@
* Target-dependent offset assignment.
* independent.
*/
-int AssignInsnOffsets(CompilationUnit* cu)
+int MipsCodegen::AssignInsnOffsets(CompilationUnit* cu)
{
LIR* mips_lir;
int offset = 0;
diff --git a/src/compiler/codegen/mips/call_mips.cc b/src/compiler/codegen/mips/call_mips.cc
index b25b7e6..f14ebab 100644
--- a/src/compiler/codegen/mips/call_mips.cc
+++ b/src/compiler/codegen/mips/call_mips.cc
@@ -18,13 +18,14 @@
#include "oat/runtime/oat_support_entrypoints.h"
#include "mips_lir.h"
+#include "codegen_mips.h"
#include "../codegen_util.h"
#include "../ralloc_util.h"
namespace art {
-void GenSpecialCase(CompilationUnit* cu, BasicBlock* bb, MIR* mir,
- SpecialCaseHandler special_case)
+void MipsCodegen::GenSpecialCase(CompilationUnit* cu, BasicBlock* bb, MIR* mir,
+ SpecialCaseHandler special_case)
{
// TODO
}
@@ -60,8 +61,7 @@
* done:
*
*/
-void GenSparseSwitch(CompilationUnit* cu, uint32_t table_offset,
- RegLocation rl_src)
+void MipsCodegen::GenSparseSwitch(CompilationUnit* cu, uint32_t table_offset, RegLocation rl_src)
{
const uint16_t* table = cu->insns + cu->current_dalvik_offset + table_offset;
if (cu->verbose) {
@@ -140,8 +140,7 @@
* jr r_RA
* done:
*/
-void GenPackedSwitch(CompilationUnit* cu, uint32_t table_offset,
- RegLocation rl_src)
+void MipsCodegen::GenPackedSwitch(CompilationUnit* cu, uint32_t table_offset, RegLocation rl_src)
{
const uint16_t* table = cu->insns + cu->current_dalvik_offset + table_offset;
if (cu->verbose) {
@@ -224,8 +223,7 @@
*
* Total size is 4+(width * size + 1)/2 16-bit code units.
*/
-void GenFillArrayData(CompilationUnit* cu, uint32_t table_offset,
- RegLocation rl_src)
+void MipsCodegen::GenFillArrayData(CompilationUnit* cu, uint32_t table_offset, RegLocation rl_src)
{
const uint16_t* table = cu->insns + cu->current_dalvik_offset + table_offset;
// Add the table to the list - we'll process it later
@@ -267,7 +265,7 @@
/*
* TODO: implement fast path to short-circuit thin-lock case
*/
-void GenMonitorEnter(CompilationUnit* cu, int opt_flags, RegLocation rl_src)
+void MipsCodegen::GenMonitorEnter(CompilationUnit* cu, int opt_flags, RegLocation rl_src)
{
FlushAllRegs(cu);
LoadValueDirectFixed(cu, rl_src, rMIPS_ARG0); // Get obj
@@ -283,7 +281,7 @@
/*
* TODO: implement fast path to short-circuit thin-lock case
*/
-void GenMonitorExit(CompilationUnit* cu, int opt_flags, RegLocation rl_src)
+void MipsCodegen::GenMonitorExit(CompilationUnit* cu, int opt_flags, RegLocation rl_src)
{
FlushAllRegs(cu);
LoadValueDirectFixed(cu, rl_src, rMIPS_ARG0); // Get obj
@@ -299,7 +297,7 @@
/*
* Mark garbage collection card. Skip if the value we're storing is null.
*/
-void MarkGCCard(CompilationUnit* cu, int val_reg, int tgt_addr_reg)
+void MipsCodegen::MarkGCCard(CompilationUnit* cu, int val_reg, int tgt_addr_reg)
{
int reg_card_base = AllocTemp(cu);
int reg_card_no = AllocTemp(cu);
@@ -313,8 +311,7 @@
FreeTemp(cu, reg_card_base);
FreeTemp(cu, reg_card_no);
}
-void GenEntrySequence(CompilationUnit* cu, RegLocation* ArgLocs,
- RegLocation rl_method)
+void MipsCodegen::GenEntrySequence(CompilationUnit* cu, RegLocation* ArgLocs, RegLocation rl_method)
{
int spill_count = cu->num_core_spills + cu->num_fp_spills;
/*
@@ -361,7 +358,7 @@
FreeTemp(cu, rMIPS_ARG3);
}
-void GenExitSequence(CompilationUnit* cu)
+void MipsCodegen::GenExitSequence(CompilationUnit* cu)
{
/*
* In the exit path, rMIPS_RET0/rMIPS_RET1 are live - make sure they aren't
diff --git a/src/compiler/codegen/mips/codegen_mips.h b/src/compiler/codegen/mips/codegen_mips.h
new file mode 100644
index 0000000..b0ecfce
--- /dev/null
+++ b/src/compiler/codegen/mips/codegen_mips.h
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef ART_SRC_COMPILER_CODEGEN_MIPS_CODEGENMIPS_H_
+#define ART_SRC_COMPILER_CODEGEN_MIPS_CODEGENMIPS_H_
+
+#include "../../compiler_internals.h"
+
+namespace art {
+
+class MipsCodegen : public Codegen {
+ public:
+ // Required for target - codegen utilities.
+ virtual bool SmallLiteralDivide(CompilationUnit* cu, Instruction::Code dalvik_opcode,
+ RegLocation rl_src, RegLocation rl_dest, int lit);
+ virtual int LoadHelper(CompilationUnit* cu, int offset);
+ virtual LIR* LoadBaseDisp(CompilationUnit* cu, int rBase, int displacement, int r_dest,
+ OpSize size, int s_reg);
+ virtual LIR* LoadBaseDispWide(CompilationUnit* cu, int rBase, int displacement, int r_dest_lo,
+ int r_dest_hi, int s_reg);
+ virtual LIR* LoadBaseIndexed(CompilationUnit* cu, int rBase, int r_index, int r_dest, int scale,
+ OpSize size);
+ virtual LIR* LoadBaseIndexedDisp(CompilationUnit *cu, int rBase, int r_index, int scale,
+ int displacement, int r_dest, int r_dest_hi, OpSize size,
+ int s_reg);
+ virtual LIR* LoadConstantNoClobber(CompilationUnit* cu, int r_dest, int value);
+ virtual LIR* LoadConstantValueWide(CompilationUnit* cu, int r_dest_lo, int r_dest_hi,
+ int val_lo, int val_hi);
+ virtual void LoadPair(CompilationUnit* cu, int base, int low_reg, int high_reg);
+ virtual LIR* StoreBaseDisp(CompilationUnit* cu, int rBase, int displacement, int r_src,
+ OpSize size);
+ virtual LIR* StoreBaseDispWide(CompilationUnit* cu, int rBase, int displacement, int r_src_lo,
+ int r_src_hi);
+ virtual LIR* StoreBaseIndexed(CompilationUnit* cu, int rBase, int r_index, int r_src, int scale,
+ OpSize size);
+ virtual LIR* StoreBaseIndexedDisp(CompilationUnit *cu, int rBase, int r_index, int scale,
+ int displacement, int r_src, int r_src_hi, OpSize size,
+ int s_reg);
+ virtual void MarkGCCard(CompilationUnit* cu, int val_reg, int tgt_addr_reg);
+
+ // Required for target - register utilities.
+ virtual bool IsFpReg(int reg);
+ virtual bool SameRegType(int reg1, int reg2);
+ virtual int AllocTypedTemp(CompilationUnit* cu, bool fp_hint, int reg_class);
+ virtual int AllocTypedTempPair(CompilationUnit* cu, bool fp_hint, int reg_class);
+ virtual int S2d(int low_reg, int high_reg);
+ virtual int TargetReg(SpecialTargetRegister reg);
+ virtual RegisterInfo* GetRegInfo(CompilationUnit* cu, int reg);
+ virtual RegLocation GetReturnAlt(CompilationUnit* cu);
+ virtual RegLocation GetReturnWideAlt(CompilationUnit* cu);
+ virtual RegLocation LocCReturn();
+ virtual RegLocation LocCReturnDouble();
+ virtual RegLocation LocCReturnFloat();
+ virtual RegLocation LocCReturnWide();
+ virtual uint32_t FpRegMask();
+ virtual uint64_t GetRegMaskCommon(CompilationUnit* cu, int reg);
+ virtual void AdjustSpillMask(CompilationUnit* cu);
+ virtual void ClobberCalleeSave(CompilationUnit *cu);
+ virtual void FlushReg(CompilationUnit* cu, int reg);
+ virtual void FlushRegWide(CompilationUnit* cu, int reg1, int reg2);
+ virtual void FreeCallTemps(CompilationUnit* cu);
+ virtual void FreeRegLocTemps(CompilationUnit* cu, RegLocation rl_keep, RegLocation rl_free);
+ virtual void LockCallTemps(CompilationUnit* cu);
+ virtual void MarkPreservedSingle(CompilationUnit* cu, int v_reg, int reg);
+ virtual void CompilerInitializeRegAlloc(CompilationUnit* cu);
+
+ // Required for target - miscellaneous.
+ virtual AssemblerStatus AssembleInstructions(CompilationUnit* cu, uintptr_t start_addr);
+ virtual void DumpResourceMask(LIR* lir, uint64_t mask, const char* prefix);
+ virtual void SetupTargetResourceMasks(CompilationUnit* cu, LIR* lir);
+ virtual const char* GetTargetInstFmt(int opcode);
+ virtual const char* GetTargetInstName(int opcode);
+ virtual int AssignInsnOffsets(CompilationUnit* cu);
+ virtual std::string BuildInsnString(const char* fmt, LIR* lir, unsigned char* base_addr);
+ virtual uint64_t GetPCUseDefEncoding();
+ virtual uint64_t GetTargetInstFlags(int opcode);
+ virtual int GetInsnSize(LIR* lir);
+ virtual bool IsUnconditionalBranch(LIR* lir);
+
+ // Required for target - Dalvik-level generators.
+ virtual bool GenAddLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src1,
+ RegLocation rl_src2);
+ virtual bool GenAndLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src1,
+ RegLocation rl_src2);
+ virtual bool GenArithOpDouble(CompilationUnit* cu, Instruction::Code opcode,
+ RegLocation rl_dest, RegLocation rl_src1,
+ RegLocation rl_src2);
+ virtual bool GenArithOpFloat(CompilationUnit *cu, Instruction::Code opcode, RegLocation rl_dest,
+ RegLocation rl_src1, RegLocation rl_src2);
+ virtual bool GenCmpFP(CompilationUnit* cu, Instruction::Code opcode, RegLocation rl_dest,
+ RegLocation rl_src1, RegLocation rl_src2);
+ virtual bool GenConversion(CompilationUnit* cu, Instruction::Code opcode, RegLocation rl_dest,
+ RegLocation rl_src);
+ virtual bool GenInlinedCas32(CompilationUnit* cu, CallInfo* info, bool need_write_barrier);
+ virtual bool GenInlinedMinMaxInt(CompilationUnit *cu, CallInfo* info, bool is_min);
+ virtual bool GenInlinedSqrt(CompilationUnit* cu, CallInfo* info);
+ virtual bool GenNegLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src);
+ virtual bool GenOrLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src1,
+ RegLocation rl_src2);
+ virtual bool GenSubLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src1,
+ RegLocation rl_src2);
+ virtual bool GenXorLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src1,
+ RegLocation rl_src2);
+ virtual LIR* GenRegMemCheck(CompilationUnit* cu, ConditionCode c_code, int reg1, int base,
+ int offset, ThrowKind kind);
+ virtual RegLocation GenDivRem(CompilationUnit* cu, RegLocation rl_dest, int reg_lo, int reg_hi,
+ bool is_div);
+ virtual RegLocation GenDivRemLit(CompilationUnit* cu, RegLocation rl_dest, int reg_lo, int lit,
+ bool is_div);
+ virtual void GenCmpLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src1,
+ RegLocation rl_src2);
+ virtual void GenDivZeroCheck(CompilationUnit* cu, int reg_lo, int reg_hi);
+ virtual void GenEntrySequence(CompilationUnit* cu, RegLocation* ArgLocs,
+ RegLocation rl_method);
+ virtual void GenExitSequence(CompilationUnit* cu);
+ virtual void GenFillArrayData(CompilationUnit* cu, uint32_t table_offset,
+ RegLocation rl_src);
+ virtual void GenFusedFPCmpBranch(CompilationUnit* cu, BasicBlock* bb, MIR* mir, bool gt_bias,
+ bool is_double);
+ virtual void GenFusedLongCmpBranch(CompilationUnit* cu, BasicBlock* bb, MIR* mir);
+ virtual void GenMemBarrier(CompilationUnit* cu, MemBarrierKind barrier_kind);
+ virtual void GenMonitorEnter(CompilationUnit* cu, int opt_flags, RegLocation rl_src);
+ virtual void GenMonitorExit(CompilationUnit* cu, int opt_flags, RegLocation rl_src);
+ virtual void GenMultiplyByTwoBitMultiplier(CompilationUnit* cu, RegLocation rl_src,
+ RegLocation rl_result, int lit, int first_bit,
+ int second_bit);
+ virtual void GenNegDouble(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src);
+ virtual void GenNegFloat(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src);
+ virtual void GenPackedSwitch(CompilationUnit* cu, uint32_t table_offset,
+ RegLocation rl_src);
+ virtual void GenSparseSwitch(CompilationUnit* cu, uint32_t table_offset,
+ RegLocation rl_src);
+ virtual void GenSpecialCase(CompilationUnit* cu, BasicBlock* bb, MIR* mir,
+ SpecialCaseHandler special_case);
+
+ // Required for target - single operation generators.
+ virtual LIR* OpUnconditionalBranch(CompilationUnit* cu, LIR* target);
+ virtual LIR* OpCmpBranch(CompilationUnit* cu, ConditionCode cond, int src1, int src2,
+ LIR* target);
+ virtual LIR* OpCmpImmBranch(CompilationUnit* cu, ConditionCode cond, int reg, int check_value,
+ LIR* target);
+ virtual LIR* OpCondBranch(CompilationUnit* cu, ConditionCode cc, LIR* target);
+ virtual LIR* OpDecAndBranch(CompilationUnit* cu, ConditionCode c_code, int reg,
+ LIR* target);
+ virtual LIR* OpFpRegCopy(CompilationUnit* cu, int r_dest, int r_src);
+ virtual LIR* OpIT(CompilationUnit* cu, ConditionCode cond, const char* guide);
+ virtual LIR* OpMem(CompilationUnit* cu, OpKind op, int rBase, int disp);
+ virtual LIR* OpPcRelLoad(CompilationUnit* cu, int reg, LIR* target);
+ virtual LIR* OpReg(CompilationUnit* cu, OpKind op, int r_dest_src);
+ virtual LIR* OpRegCopy(CompilationUnit* cu, int r_dest, int r_src);
+ virtual LIR* OpRegCopyNoInsert(CompilationUnit* cu, int r_dest, int r_src);
+ virtual LIR* OpRegImm(CompilationUnit* cu, OpKind op, int r_dest_src1, int value);
+ virtual LIR* OpRegMem(CompilationUnit* cu, OpKind op, int r_dest, int rBase, int offset);
+ virtual LIR* OpRegReg(CompilationUnit* cu, OpKind op, int r_dest_src1, int r_src2);
+ virtual LIR* OpRegRegImm(CompilationUnit* cu, OpKind op, int r_dest, int r_src1, int value);
+ virtual LIR* OpRegRegReg(CompilationUnit* cu, OpKind op, int r_dest, int r_src1,
+ int r_src2);
+ virtual LIR* OpTestSuspend(CompilationUnit* cu, LIR* target);
+ virtual LIR* OpThreadMem(CompilationUnit* cu, OpKind op, int thread_offset);
+ virtual LIR* OpVldm(CompilationUnit* cu, int rBase, int count);
+ virtual LIR* OpVstm(CompilationUnit* cu, int rBase, int count);
+ virtual void OpLea(CompilationUnit* cu, int rBase, int reg1, int reg2, int scale,
+ int offset);
+ virtual void OpRegCopyWide(CompilationUnit* cu, int dest_lo, int dest_hi, int src_lo,
+ int src_hi);
+ virtual void OpTlsCmp(CompilationUnit* cu, int offset, int val);
+
+ LIR* LoadBaseDispBody(CompilationUnit* cu, int rBase, int displacement, int r_dest,
+ int r_dest_hi, OpSize size, int s_reg);
+ LIR* StoreBaseDispBody(CompilationUnit* cu, int rBase, int displacement, int r_src,
+ int r_src_hi, OpSize size);
+ void SpillCoreRegs(CompilationUnit* cu);
+ void UnSpillCoreRegs(CompilationUnit* cu);
+ static const MipsEncodingMap EncodingMap[kMipsLast];
+};
+
+} // namespace art
+
+#endif // ART_SRC_COMPILER_CODEGEN_MIPS_CODEGENMIPS_H_
diff --git a/src/compiler/codegen/mips/fp_mips.cc b/src/compiler/codegen/mips/fp_mips.cc
index 8f33dfa..efc4f80 100644
--- a/src/compiler/codegen/mips/fp_mips.cc
+++ b/src/compiler/codegen/mips/fp_mips.cc
@@ -16,15 +16,15 @@
#include "oat/runtime/oat_support_entrypoints.h"
#include "mips_lir.h"
+#include "codegen_mips.h"
#include "../codegen_util.h"
#include "../ralloc_util.h"
namespace art {
-bool GenArithOpFloat(CompilationUnit *cu, Instruction::Code opcode, RegLocation rl_dest,
- RegLocation rl_src1, RegLocation rl_src2)
+bool MipsCodegen::GenArithOpFloat(CompilationUnit *cu, Instruction::Code opcode,
+ RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2)
{
-#ifdef __mips_hard_float
int op = kMipsNop;
RegLocation rl_result;
@@ -64,15 +64,11 @@
StoreValue(cu, rl_dest, rl_result);
return false;
-#else
- return GenArithOpFloatPortable(cu, opcode, rl_dest, rl_src1, rl_src2);
-#endif
}
-bool GenArithOpDouble(CompilationUnit *cu, Instruction::Code opcode,
- RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2)
+bool MipsCodegen::GenArithOpDouble(CompilationUnit *cu, Instruction::Code opcode,
+ RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2)
{
-#ifdef __mips_hard_float
int op = kMipsNop;
RegLocation rl_result;
@@ -112,15 +108,11 @@
S2d(rl_src2.low_reg, rl_src2.high_reg));
StoreValueWide(cu, rl_dest, rl_result);
return false;
-#else
- return GenArithOpDoublePortable(cu, opcode, rl_dest, rl_src1, rl_src2);
-#endif
}
-bool GenConversion(CompilationUnit *cu, Instruction::Code opcode, RegLocation rl_dest,
- RegLocation rl_src)
+bool MipsCodegen::GenConversion(CompilationUnit *cu, Instruction::Code opcode, RegLocation rl_dest,
+ RegLocation rl_src)
{
-#ifdef __mips_hard_float
int op = kMipsNop;
int src_reg;
RegLocation rl_result;
@@ -164,13 +156,10 @@
StoreValue(cu, rl_dest, rl_result);
}
return false;
-#else
- return GenConversionPortable(cu, opcode, rl_dest, rl_src);
-#endif
}
-bool GenCmpFP(CompilationUnit *cu, Instruction::Code opcode, RegLocation rl_dest,
- RegLocation rl_src1, RegLocation rl_src2)
+bool MipsCodegen::GenCmpFP(CompilationUnit *cu, Instruction::Code opcode, RegLocation rl_dest,
+ RegLocation rl_src1, RegLocation rl_src2)
{
bool wide = true;
int offset;
@@ -210,13 +199,13 @@
return false;
}
-void GenFusedFPCmpBranch(CompilationUnit* cu, BasicBlock* bb, MIR* mir,
+void MipsCodegen::GenFusedFPCmpBranch(CompilationUnit* cu, BasicBlock* bb, MIR* mir,
bool gt_bias, bool is_double)
{
UNIMPLEMENTED(FATAL) << "Need codegen for fused fp cmp branch";
}
-void GenNegFloat(CompilationUnit *cu, RegLocation rl_dest, RegLocation rl_src)
+void MipsCodegen::GenNegFloat(CompilationUnit *cu, RegLocation rl_dest, RegLocation rl_src)
{
RegLocation rl_result;
rl_src = LoadValue(cu, rl_src, kCoreReg);
@@ -225,7 +214,7 @@
StoreValue(cu, rl_dest, rl_result);
}
-void GenNegDouble(CompilationUnit *cu, RegLocation rl_dest, RegLocation rl_src)
+void MipsCodegen::GenNegDouble(CompilationUnit *cu, RegLocation rl_dest, RegLocation rl_src)
{
RegLocation rl_result;
rl_src = LoadValueWide(cu, rl_src, kCoreReg);
@@ -235,7 +224,7 @@
StoreValueWide(cu, rl_dest, rl_result);
}
-bool GenInlinedMinMaxInt(CompilationUnit *cu, CallInfo* info, bool is_min)
+bool MipsCodegen::GenInlinedMinMaxInt(CompilationUnit *cu, CallInfo* info, bool is_min)
{
// TODO: need Mips implementation
return false;
diff --git a/src/compiler/codegen/mips/int_mips.cc b/src/compiler/codegen/mips/int_mips.cc
index 273e4bd..bb36dc1 100644
--- a/src/compiler/codegen/mips/int_mips.cc
+++ b/src/compiler/codegen/mips/int_mips.cc
@@ -18,6 +18,7 @@
#include "oat/runtime/oat_support_entrypoints.h"
#include "mips_lir.h"
+#include "codegen_mips.h"
#include "../codegen_util.h"
#include "../ralloc_util.h"
@@ -39,8 +40,8 @@
* finish:
*
*/
-void GenCmpLong(CompilationUnit* cu, RegLocation rl_dest,
- RegLocation rl_src1, RegLocation rl_src2)
+void MipsCodegen::GenCmpLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src1,
+ RegLocation rl_src2)
{
rl_src1 = LoadValueWide(cu, rl_src1, kCoreReg);
rl_src2 = LoadValueWide(cu, rl_src2, kCoreReg);
@@ -61,8 +62,8 @@
StoreValue(cu, rl_dest, rl_result);
}
-LIR* OpCmpBranch(CompilationUnit* cu, ConditionCode cond, int src1,
- int src2, LIR* target)
+LIR* MipsCodegen::OpCmpBranch(CompilationUnit* cu, ConditionCode cond, int src1, int src2,
+ LIR* target)
{
LIR* branch;
MipsOpCode slt_op;
@@ -129,8 +130,8 @@
return branch;
}
-LIR* OpCmpImmBranch(CompilationUnit* cu, ConditionCode cond, int reg,
- int check_value, LIR* target)
+LIR* MipsCodegen::OpCmpImmBranch(CompilationUnit* cu, ConditionCode cond, int reg,
+ int check_value, LIR* target)
{
LIR* branch;
if (check_value != 0) {
@@ -163,12 +164,10 @@
return branch;
}
-LIR* OpRegCopyNoInsert(CompilationUnit *cu, int r_dest, int r_src)
+LIR* MipsCodegen::OpRegCopyNoInsert(CompilationUnit *cu, int r_dest, int r_src)
{
-#ifdef __mips_hard_float
if (MIPS_FPREG(r_dest) || MIPS_FPREG(r_src))
- return FpRegCopy(cu, r_dest, r_src);
-#endif
+ return OpFpRegCopy(cu, r_dest, r_src);
LIR* res = RawLIR(cu, cu->current_dalvik_offset, kMipsMove,
r_dest, r_src);
if (!(cu->disable_opt & (1 << kSafeOptimizations)) && r_dest == r_src) {
@@ -177,17 +176,16 @@
return res;
}
-LIR* OpRegCopy(CompilationUnit *cu, int r_dest, int r_src)
+LIR* MipsCodegen::OpRegCopy(CompilationUnit *cu, int r_dest, int r_src)
{
LIR *res = OpRegCopyNoInsert(cu, r_dest, r_src);
AppendLIR(cu, res);
return res;
}
-void OpRegCopyWide(CompilationUnit *cu, int dest_lo, int dest_hi,
- int src_lo, int src_hi)
+void MipsCodegen::OpRegCopyWide(CompilationUnit *cu, int dest_lo, int dest_hi, int src_lo,
+ int src_hi)
{
-#ifdef __mips_hard_float
bool dest_fp = MIPS_FPREG(dest_lo) && MIPS_FPREG(dest_hi);
bool src_fp = MIPS_FPREG(src_lo) && MIPS_FPREG(src_hi);
assert(MIPS_FPREG(src_lo) == MIPS_FPREG(src_hi));
@@ -215,31 +213,22 @@
}
}
}
-#else
- // Handle overlap
- if (src_hi == dest_lo) {
- OpRegCopy(cu, dest_hi, src_hi);
- OpRegCopy(cu, dest_lo, src_lo);
- } else {
- OpRegCopy(cu, dest_lo, src_lo);
- OpRegCopy(cu, dest_hi, src_hi);
- }
-#endif
}
-void GenFusedLongCmpBranch(CompilationUnit* cu, BasicBlock* bb, MIR* mir)
+void MipsCodegen::GenFusedLongCmpBranch(CompilationUnit* cu, BasicBlock* bb, MIR* mir)
{
UNIMPLEMENTED(FATAL) << "Need codegen for fused long cmp branch";
}
-LIR* GenRegMemCheck(CompilationUnit* cu, ConditionCode c_code,
+LIR* MipsCodegen::GenRegMemCheck(CompilationUnit* cu, ConditionCode c_code,
int reg1, int base, int offset, ThrowKind kind)
{
LOG(FATAL) << "Unexpected use of GenRegMemCheck for Arm";
return NULL;
}
-RegLocation GenDivRem(CompilationUnit* cu, RegLocation rl_dest, int reg1, int reg2, bool is_div)
+RegLocation MipsCodegen::GenDivRem(CompilationUnit* cu, RegLocation rl_dest, int reg1, int reg2,
+ bool is_div)
{
NewLIR4(cu, kMipsDiv, r_HI, r_LO, reg1, reg2);
RegLocation rl_result = EvalLoc(cu, rl_dest, kCoreReg, true);
@@ -251,7 +240,8 @@
return rl_result;
}
-RegLocation GenDivRemLit(CompilationUnit* cu, RegLocation rl_dest, int reg1, int lit, bool is_div)
+RegLocation MipsCodegen::GenDivRemLit(CompilationUnit* cu, RegLocation rl_dest, int reg1, int lit,
+ bool is_div)
{
int t_reg = AllocTemp(cu);
NewLIR3(cu, kMipsAddiu, t_reg, r_ZERO, lit);
@@ -266,46 +256,46 @@
return rl_result;
}
-void OpLea(CompilationUnit* cu, int rBase, int reg1, int reg2, int scale, int offset)
+void MipsCodegen::OpLea(CompilationUnit* cu, int rBase, int reg1, int reg2, int scale, int offset)
{
LOG(FATAL) << "Unexpected use of OpLea for Arm";
}
-void OpTlsCmp(CompilationUnit* cu, int offset, int val)
+void MipsCodegen::OpTlsCmp(CompilationUnit* cu, int offset, int val)
{
LOG(FATAL) << "Unexpected use of OpTlsCmp for Arm";
}
-bool GenInlinedCas32(CompilationUnit* cu, CallInfo* info, bool need_write_barrier) {
+bool MipsCodegen::GenInlinedCas32(CompilationUnit* cu, CallInfo* info, bool need_write_barrier) {
DCHECK_NE(cu->instruction_set, kThumb2);
return false;
}
-bool GenInlinedSqrt(CompilationUnit* cu, CallInfo* info) {
+bool MipsCodegen::GenInlinedSqrt(CompilationUnit* cu, CallInfo* info) {
DCHECK_NE(cu->instruction_set, kThumb2);
return false;
}
-LIR* OpPcRelLoad(CompilationUnit* cu, int reg, LIR* target) {
+LIR* MipsCodegen::OpPcRelLoad(CompilationUnit* cu, int reg, LIR* target) {
LOG(FATAL) << "Unexpected use of OpPcRelLoad for Mips";
return NULL;
}
-LIR* OpVldm(CompilationUnit* cu, int rBase, int count)
+LIR* MipsCodegen::OpVldm(CompilationUnit* cu, int rBase, int count)
{
LOG(FATAL) << "Unexpected use of OpVldm for Mips";
return NULL;
}
-LIR* OpVstm(CompilationUnit* cu, int rBase, int count)
+LIR* MipsCodegen::OpVstm(CompilationUnit* cu, int rBase, int count)
{
LOG(FATAL) << "Unexpected use of OpVstm for Mips";
return NULL;
}
-void GenMultiplyByTwoBitMultiplier(CompilationUnit* cu, RegLocation rl_src,
- RegLocation rl_result, int lit,
- int first_bit, int second_bit)
+void MipsCodegen::GenMultiplyByTwoBitMultiplier(CompilationUnit* cu, RegLocation rl_src,
+ RegLocation rl_result, int lit,
+ int first_bit, int second_bit)
{
int t_reg = AllocTemp(cu);
OpRegRegImm(cu, kOpLsl, t_reg, rl_src.low_reg, second_bit - first_bit);
@@ -316,7 +306,7 @@
}
}
-void GenDivZeroCheck(CompilationUnit* cu, int reg_lo, int reg_hi)
+void MipsCodegen::GenDivZeroCheck(CompilationUnit* cu, int reg_lo, int reg_hi)
{
int t_reg = AllocTemp(cu);
OpRegRegReg(cu, kOpOr, t_reg, reg_lo, reg_hi);
@@ -325,34 +315,34 @@
}
// Test suspend flag, return target of taken suspend branch
-LIR* OpTestSuspend(CompilationUnit* cu, LIR* target)
+LIR* MipsCodegen::OpTestSuspend(CompilationUnit* cu, LIR* target)
{
OpRegImm(cu, kOpSub, rMIPS_SUSPEND, 1);
return OpCmpImmBranch(cu, (target == NULL) ? kCondEq : kCondNe, rMIPS_SUSPEND, 0, target);
}
// Decrement register and branch on condition
-LIR* OpDecAndBranch(CompilationUnit* cu, ConditionCode c_code, int reg, LIR* target)
+LIR* MipsCodegen::OpDecAndBranch(CompilationUnit* cu, ConditionCode c_code, int reg, LIR* target)
{
OpRegImm(cu, kOpSub, reg, 1);
return OpCmpImmBranch(cu, c_code, reg, 0, target);
}
-bool SmallLiteralDivide(CompilationUnit* cu, Instruction::Code dalvik_opcode,
- RegLocation rl_src, RegLocation rl_dest, int lit)
+bool MipsCodegen::SmallLiteralDivide(CompilationUnit* cu, Instruction::Code dalvik_opcode,
+ RegLocation rl_src, RegLocation rl_dest, int lit)
{
LOG(FATAL) << "Unexpected use of smallLiteralDive in Mips";
return false;
}
-LIR* OpIT(CompilationUnit* cu, ArmConditionCode cond, const char* guide)
+LIR* MipsCodegen::OpIT(CompilationUnit* cu, ConditionCode cond, const char* guide)
{
LOG(FATAL) << "Unexpected use of OpIT in Mips";
return NULL;
}
-bool GenAddLong(CompilationUnit* cu, RegLocation rl_dest,
- RegLocation rl_src1, RegLocation rl_src2)
+bool MipsCodegen::GenAddLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src1,
+ RegLocation rl_src2)
{
rl_src1 = LoadValueWide(cu, rl_src1, kCoreReg);
rl_src2 = LoadValueWide(cu, rl_src2, kCoreReg);
@@ -375,8 +365,8 @@
return false;
}
-bool GenSubLong(CompilationUnit* cu, RegLocation rl_dest,
- RegLocation rl_src1, RegLocation rl_src2)
+bool MipsCodegen::GenSubLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src1,
+ RegLocation rl_src2)
{
rl_src1 = LoadValueWide(cu, rl_src1, kCoreReg);
rl_src2 = LoadValueWide(cu, rl_src2, kCoreReg);
@@ -399,8 +389,7 @@
return false;
}
-bool GenNegLong(CompilationUnit* cu, RegLocation rl_dest,
- RegLocation rl_src)
+bool MipsCodegen::GenNegLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
{
rl_src = LoadValueWide(cu, rl_src, kCoreReg);
RegLocation rl_result = EvalLoc(cu, rl_dest, kCoreReg, true);
@@ -422,22 +411,22 @@
return false;
}
-bool GenAndLong(CompilationUnit* cu, RegLocation rl_dest,
- RegLocation rl_src1, RegLocation rl_src2)
+bool MipsCodegen::GenAndLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src1,
+ RegLocation rl_src2)
{
LOG(FATAL) << "Unexpected use of GenAndLong for Mips";
return false;
}
-bool GenOrLong(CompilationUnit* cu, RegLocation rl_dest,
- RegLocation rl_src1, RegLocation rl_src2)
+bool MipsCodegen::GenOrLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src1,
+ RegLocation rl_src2)
{
LOG(FATAL) << "Unexpected use of GenOrLong for Mips";
return false;
}
-bool GenXorLong(CompilationUnit* cu, RegLocation rl_dest,
- RegLocation rl_src1, RegLocation rl_src2)
+bool MipsCodegen::GenXorLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src1,
+ RegLocation rl_src2)
{
LOG(FATAL) << "Unexpected use of GenXorLong for Mips";
return false;
diff --git a/src/compiler/codegen/mips/mips_lir.h b/src/compiler/codegen/mips/mips_lir.h
index e3d9b62..cecd4ab 100644
--- a/src/compiler/codegen/mips/mips_lir.h
+++ b/src/compiler/codegen/mips/mips_lir.h
@@ -86,13 +86,13 @@
* +========================+
*/
-/* Offset to distingish FP regs */
+// Offset to distingish FP regs.
#define MIPS_FP_REG_OFFSET 32
-/* Offset to distinguish DP FP regs */
+// Offset to distinguish DP FP regs.
#define MIPS_FP_DOUBLE 64
-/* Offset to distingish the extra regs */
+// Offset to distingish the extra regs.
#define MIPS_EXTRA_REG_OFFSET 128
-/* Reg types */
+// Reg types.
#define MIPS_REGTYPE(x) (x & (MIPS_FP_REG_OFFSET | MIPS_FP_DOUBLE))
#define MIPS_FPREG(x) ((x & MIPS_FP_REG_OFFSET) == MIPS_FP_REG_OFFSET)
#define MIPS_EXTRAREG(x) ((x & MIPS_EXTRA_REG_OFFSET) == MIPS_EXTRA_REG_OFFSET)
@@ -106,7 +106,7 @@
* code that reg locations always describe doubles as a pair of singles.
*/
#define MIPS_S2D(x,y) ((x) | MIPS_FP_DOUBLE)
-/* Mask to strip off fp flags */
+// Mask to strip off fp flags.
#define MIPS_FP_REG_MASK (MIPS_FP_REG_OFFSET-1)
#ifdef HAVE_LITTLE_ENDIAN
@@ -129,7 +129,7 @@
#define r_RESULT1 r_V0
#endif
-/* These are the same for both big and little endian. */
+// These are the same for both big and little endian.
#define r_FARG0 r_F12
#define r_FARG1 r_F13
#define r_FARG2 r_F14
@@ -137,11 +137,11 @@
#define r_FRESULT0 r_F0
#define r_FRESULT1 r_F1
-/* Regs not used for Mips */
+// Regs not used for Mips.
#define rMIPS_LR INVALID_REG
#define rMIPS_PC INVALID_REG
-/* RegisterLocation templates return values (r_V0, or r_V0/r_V1) */
+// RegisterLocation templates return values (r_V0, or r_V0/r_V1).
#define MIPS_LOC_C_RETURN {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1, r_V0, INVALID_REG, \
INVALID_SREG, INVALID_SREG}
#define MIPS_LOC_C_RETURN_FLOAT {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1, r_FRESULT0, \
@@ -155,7 +155,7 @@
kMipsGPReg0 = 0,
kMipsRegSP = 29,
kMipsRegLR = 31,
- kMipsFPReg0 = 32, /* only 16 fp regs supported currently */
+ kMipsFPReg0 = 32, // only 16 fp regs supported currently.
kMipsFPRegEnd = 48,
kMipsRegHI = kMipsFPRegEnd,
kMipsRegLO,
@@ -168,10 +168,6 @@
#define ENCODE_MIPS_REG_LR (1ULL << kMipsRegLR)
#define ENCODE_MIPS_REG_PC (1ULL << kMipsRegPC)
-/*
- * Annotate special-purpose core registers:
- */
-
enum MipsNativeRegisterPool {
r_ZERO = 0,
r_AT = 1,
@@ -222,7 +218,11 @@
r_F13,
r_F14,
r_F15,
-#if 0 /* only 16 fp regs supported currently */
+#if 0
+ /*
+ * TODO: The shared resource mask doesn't have enough bit positions to describe all
+ * MIPS registers. Expand it and enable use of fp registers 16 through 31.
+ */
r_F16,
r_F17,
r_F18,
@@ -248,7 +248,7 @@
r_DF5 = r_F10 + MIPS_FP_DOUBLE,
r_DF6 = r_F12 + MIPS_FP_DOUBLE,
r_DF7 = r_F14 + MIPS_FP_DOUBLE,
-#if 0 /* only 16 fp regs supported currently */
+#if 0 // TODO: expand resource mask to enable use of all MIPS fp registers.
r_DF8 = r_F16 + MIPS_FP_DOUBLE,
r_DF9 = r_F18 + MIPS_FP_DOUBLE,
r_DF10 = r_F20 + MIPS_FP_DOUBLE,
@@ -263,10 +263,6 @@
r_PC,
};
-/*
- * Target-independent aliases
- */
-
#define rMIPS_SUSPEND r_S0
#define rMIPS_SELF r_S1
#define rMIPS_SP r_SP
@@ -283,7 +279,6 @@
#define rMIPS_INVOKE_TGT r_T9
#define rMIPS_COUNT INVALID_REG
-/* Shift encodings */
enum MipsShiftEncodings {
kMipsLsl = 0x0,
kMipsLsr = 0x1,
@@ -291,7 +286,7 @@
kMipsRor = 0x3
};
-// MIPS sync kinds (Note: support for kinds other than kSYNC0 may not exist)
+// MIPS sync kinds (Note: support for kinds other than kSYNC0 may not exist).
#define kSYNC0 0x00
#define kSYNC_WMB 0x04
#define kSYNC_MB 0x01
@@ -299,7 +294,7 @@
#define kSYNC_RELEASE 0x12
#define kSYNC_RMB 0x13
-// TODO: Use smaller hammer when appropriate for target CPU
+// TODO: Use smaller hammer when appropriate for target CPU.
#define kST kSYNC0
#define kSY kSYNC0
@@ -310,103 +305,99 @@
*/
enum MipsOpCode {
kMipsFirst = 0,
- kMips32BitData = kMipsFirst, /* data [31..0] */
- kMipsAddiu, /* addiu t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] */
- kMipsAddu, /* add d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100001] */
- kMipsAnd, /* and d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100100] */
- kMipsAndi, /* andi t,s,imm16 [001100] s[25..21] t[20..16] imm16[15..0] */
- kMipsB, /* b o [0001000000000000] o[15..0] */
- kMipsBal, /* bal o [0000010000010001] o[15..0] */
- /* NOTE: the code tests the range kMipsBeq thru kMipsBne, so
- adding an instruction in this range may require updates */
- kMipsBeq, /* beq s,t,o [000100] s[25..21] t[20..16] o[15..0] */
- kMipsBeqz, /* beqz s,o [000100] s[25..21] [00000] o[15..0] */
- kMipsBgez, /* bgez s,o [000001] s[25..21] [00001] o[15..0] */
- kMipsBgtz, /* bgtz s,o [000111] s[25..21] [00000] o[15..0] */
- kMipsBlez, /* blez s,o [000110] s[25..21] [00000] o[15..0] */
- kMipsBltz, /* bltz s,o [000001] s[25..21] [00000] o[15..0] */
- kMipsBnez, /* bnez s,o [000101] s[25..21] [00000] o[15..0] */
- kMipsBne, /* bne s,t,o [000101] s[25..21] t[20..16] o[15..0] */
- kMipsDiv, /* div s,t [000000] s[25..21] t[20..16] [0000000000011010] */
+ kMips32BitData = kMipsFirst, // data [31..0].
+ kMipsAddiu, // addiu t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0].
+ kMipsAddu, // add d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100001].
+ kMipsAnd, // and d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100100].
+ kMipsAndi, // andi t,s,imm16 [001100] s[25..21] t[20..16] imm16[15..0].
+ kMipsB, // b o [0001000000000000] o[15..0].
+ kMipsBal, // bal o [0000010000010001] o[15..0].
+ // NOTE: the code tests the range kMipsBeq thru kMipsBne, so adding an instruction in this
+ // range may require updates.
+ kMipsBeq, // beq s,t,o [000100] s[25..21] t[20..16] o[15..0].
+ kMipsBeqz, // beqz s,o [000100] s[25..21] [00000] o[15..0].
+ kMipsBgez, // bgez s,o [000001] s[25..21] [00001] o[15..0].
+ kMipsBgtz, // bgtz s,o [000111] s[25..21] [00000] o[15..0].
+ kMipsBlez, // blez s,o [000110] s[25..21] [00000] o[15..0].
+ kMipsBltz, // bltz s,o [000001] s[25..21] [00000] o[15..0].
+ kMipsBnez, // bnez s,o [000101] s[25..21] [00000] o[15..0].
+ kMipsBne, // bne s,t,o [000101] s[25..21] t[20..16] o[15..0].
+ kMipsDiv, // div s,t [000000] s[25..21] t[20..16] [0000000000011010].
#if __mips_isa_rev>=2
- kMipsExt, /* ext t,s,p,z [011111] s[25..21] t[20..16] z[15..11] p[10..6] [000000] */
+ kMipsExt, // ext t,s,p,z [011111] s[25..21] t[20..16] z[15..11] p[10..6] [000000].
#endif
- kMipsJal, /* jal t [000011] t[25..0] */
- kMipsJalr, /* jalr d,s [000000] s[25..21] [00000] d[15..11]
- hint[10..6] [001001] */
- kMipsJr, /* jr s [000000] s[25..21] [0000000000] hint[10..6] [001000] */
- kMipsLahi, /* lui t,imm16 [00111100000] t[20..16] imm16[15..0] load addr hi */
- kMipsLalo, /* ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] load addr lo */
- kMipsLui, /* lui t,imm16 [00111100000] t[20..16] imm16[15..0] */
- kMipsLb, /* lb t,o(b) [100000] b[25..21] t[20..16] o[15..0] */
- kMipsLbu, /* lbu t,o(b) [100100] b[25..21] t[20..16] o[15..0] */
- kMipsLh, /* lh t,o(b) [100001] b[25..21] t[20..16] o[15..0] */
- kMipsLhu, /* lhu t,o(b) [100101] b[25..21] t[20..16] o[15..0] */
- kMipsLw, /* lw t,o(b) [100011] b[25..21] t[20..16] o[15..0] */
- kMipsMfhi, /* mfhi d [0000000000000000] d[15..11] [00000010000] */
- kMipsMflo, /* mflo d [0000000000000000] d[15..11] [00000010010] */
- kMipsMove, /* move d,s [000000] s[25..21] [00000] d[15..11] [00000100101] */
- kMipsMovz, /* movz d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000001010] */
- kMipsMul, /* mul d,s,t [011100] s[25..21] t[20..16] d[15..11] [00000000010] */
- kMipsNop, /* nop [00000000000000000000000000000000] */
- kMipsNor, /* nor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100111] */
- kMipsOr, /* or d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100101] */
- kMipsOri, /* ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] */
- kMipsPref, /* pref h,o(b) [101011] b[25..21] h[20..16] o[15..0] */
- kMipsSb, /* sb t,o(b) [101000] b[25..21] t[20..16] o[15..0] */
+ kMipsJal, // jal t [000011] t[25..0].
+ kMipsJalr, // jalr d,s [000000] s[25..21] [00000] d[15..11] hint[10..6] [001001].
+ kMipsJr, // jr s [000000] s[25..21] [0000000000] hint[10..6] [001000].
+ kMipsLahi, // lui t,imm16 [00111100000] t[20..16] imm16[15..0] load addr hi.
+ kMipsLalo, // ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] load addr lo.
+ kMipsLui, // lui t,imm16 [00111100000] t[20..16] imm16[15..0].
+ kMipsLb, // lb t,o(b) [100000] b[25..21] t[20..16] o[15..0].
+ kMipsLbu, // lbu t,o(b) [100100] b[25..21] t[20..16] o[15..0].
+ kMipsLh, // lh t,o(b) [100001] b[25..21] t[20..16] o[15..0].
+ kMipsLhu, // lhu t,o(b) [100101] b[25..21] t[20..16] o[15..0].
+ kMipsLw, // lw t,o(b) [100011] b[25..21] t[20..16] o[15..0].
+ kMipsMfhi, // mfhi d [0000000000000000] d[15..11] [00000010000].
+ kMipsMflo, // mflo d [0000000000000000] d[15..11] [00000010010].
+ kMipsMove, // move d,s [000000] s[25..21] [00000] d[15..11] [00000100101].
+ kMipsMovz, // movz d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000001010].
+ kMipsMul, // mul d,s,t [011100] s[25..21] t[20..16] d[15..11] [00000000010].
+ kMipsNop, // nop [00000000000000000000000000000000].
+ kMipsNor, // nor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100111].
+ kMipsOr, // or d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100101].
+ kMipsOri, // ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0].
+ kMipsPref, // pref h,o(b) [101011] b[25..21] h[20..16] o[15..0].
+ kMipsSb, // sb t,o(b) [101000] b[25..21] t[20..16] o[15..0].
#if __mips_isa_rev>=2
- kMipsSeb, /* seb d,t [01111100000] t[20..16] d[15..11] [10000100000] */
- kMipsSeh, /* seh d,t [01111100000] t[20..16] d[15..11] [11000100000] */
+ kMipsSeb, // seb d,t [01111100000] t[20..16] d[15..11] [10000100000].
+ kMipsSeh, // seh d,t [01111100000] t[20..16] d[15..11] [11000100000].
#endif
- kMipsSh, /* sh t,o(b) [101001] b[25..21] t[20..16] o[15..0] */
- kMipsSll, /* sll d,t,a [00000000000] t[20..16] d[15..11] a[10..6] [000000] */
- kMipsSllv, /* sllv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000100] */
- kMipsSlt, /* slt d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101010] */
- kMipsSlti, /* slti t,s,imm16 [001010] s[25..21] t[20..16] imm16[15..0] */
- kMipsSltu, /* sltu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101011] */
- kMipsSra, /* sra d,s,imm5 [00000000000] t[20..16] d[15..11] imm5[10..6] [000011] */
- kMipsSrav, /* srav d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000111] */
- kMipsSrl, /* srl d,t,a [00000000000] t[20..16] d[20..16] a[10..6] [000010] */
- kMipsSrlv, /* srlv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000110] */
- kMipsSubu, /* subu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100011] */
- kMipsSw, /* sw t,o(b) [101011] b[25..21] t[20..16] o[15..0] */
- kMipsXor, /* xor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100110] */
- kMipsXori, /* xori t,s,imm16 [001110] s[25..21] t[20..16] imm16[15..0] */
-#ifdef __mips_hard_float
- kMipsFadds, /* add.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000000] */
- kMipsFsubs, /* sub.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000001] */
- kMipsFmuls, /* mul.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000010] */
- kMipsFdivs, /* div.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000011] */
- kMipsFaddd, /* add.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000000] */
- kMipsFsubd, /* sub.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000001] */
- kMipsFmuld, /* mul.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000010] */
- kMipsFdivd, /* div.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000011] */
- kMipsFcvtsd,/* cvt.s.d d,s [01000110001] [00000] s[15..11] d[10..6] [100000] */
- kMipsFcvtsw,/* cvt.s.w d,s [01000110100] [00000] s[15..11] d[10..6] [100000] */
- kMipsFcvtds,/* cvt.d.s d,s [01000110000] [00000] s[15..11] d[10..6] [100001] */
- kMipsFcvtdw,/* cvt.d.w d,s [01000110100] [00000] s[15..11] d[10..6] [100001] */
- kMipsFcvtws,/* cvt.w.d d,s [01000110000] [00000] s[15..11] d[10..6] [100100] */
- kMipsFcvtwd,/* cvt.w.d d,s [01000110001] [00000] s[15..11] d[10..6] [100100] */
- kMipsFmovs, /* mov.s d,s [01000110000] [00000] s[15..11] d[10..6] [000110] */
- kMipsFmovd, /* mov.d d,s [01000110001] [00000] s[15..11] d[10..6] [000110] */
- kMipsFlwc1, /* lwc1 t,o(b) [110001] b[25..21] t[20..16] o[15..0] */
- kMipsFldc1, /* ldc1 t,o(b) [110101] b[25..21] t[20..16] o[15..0] */
- kMipsFswc1, /* swc1 t,o(b) [111001] b[25..21] t[20..16] o[15..0] */
- kMipsFsdc1, /* sdc1 t,o(b) [111101] b[25..21] t[20..16] o[15..0] */
- kMipsMfc1, /* mfc1 t,s [01000100000] t[20..16] s[15..11] [00000000000] */
- kMipsMtc1, /* mtc1 t,s [01000100100] t[20..16] s[15..11] [00000000000] */
-#endif
- kMipsDelta, /* Psuedo for ori t, s, <label>-<label> */
- kMipsDeltaHi, /* Pseudo for lui t, high16(<label>-<label>) */
- kMipsDeltaLo, /* Pseudo for ori t, s, low16(<label>-<label>) */
- kMipsCurrPC, /* jal to .+8 to materialize pc */
- kMipsSync, /* sync kind [000000] [0000000000000000] s[10..6] [001111] */
- kMipsUndefined, /* undefined [011001xxxxxxxxxxxxxxxx] */
+ kMipsSh, // sh t,o(b) [101001] b[25..21] t[20..16] o[15..0].
+ kMipsSll, // sll d,t,a [00000000000] t[20..16] d[15..11] a[10..6] [000000].
+ kMipsSllv, // sllv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000100].
+ kMipsSlt, // slt d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101010].
+ kMipsSlti, // slti t,s,imm16 [001010] s[25..21] t[20..16] imm16[15..0].
+ kMipsSltu, // sltu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101011].
+ kMipsSra, // sra d,s,imm5 [00000000000] t[20..16] d[15..11] imm5[10..6] [000011].
+ kMipsSrav, // srav d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000111].
+ kMipsSrl, // srl d,t,a [00000000000] t[20..16] d[20..16] a[10..6] [000010].
+ kMipsSrlv, // srlv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000110].
+ kMipsSubu, // subu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100011].
+ kMipsSw, // sw t,o(b) [101011] b[25..21] t[20..16] o[15..0].
+ kMipsXor, // xor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100110].
+ kMipsXori, // xori t,s,imm16 [001110] s[25..21] t[20..16] imm16[15..0].
+ kMipsFadds, // add.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000000].
+ kMipsFsubs, // sub.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000001].
+ kMipsFmuls, // mul.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000010].
+ kMipsFdivs, // div.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000011].
+ kMipsFaddd, // add.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000000].
+ kMipsFsubd, // sub.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000001].
+ kMipsFmuld, // mul.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000010].
+ kMipsFdivd, // div.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000011].
+ kMipsFcvtsd,// cvt.s.d d,s [01000110001] [00000] s[15..11] d[10..6] [100000].
+ kMipsFcvtsw,// cvt.s.w d,s [01000110100] [00000] s[15..11] d[10..6] [100000].
+ kMipsFcvtds,// cvt.d.s d,s [01000110000] [00000] s[15..11] d[10..6] [100001].
+ kMipsFcvtdw,// cvt.d.w d,s [01000110100] [00000] s[15..11] d[10..6] [100001].
+ kMipsFcvtws,// cvt.w.d d,s [01000110000] [00000] s[15..11] d[10..6] [100100].
+ kMipsFcvtwd,// cvt.w.d d,s [01000110001] [00000] s[15..11] d[10..6] [100100].
+ kMipsFmovs, // mov.s d,s [01000110000] [00000] s[15..11] d[10..6] [000110].
+ kMipsFmovd, // mov.d d,s [01000110001] [00000] s[15..11] d[10..6] [000110].
+ kMipsFlwc1, // lwc1 t,o(b) [110001] b[25..21] t[20..16] o[15..0].
+ kMipsFldc1, // ldc1 t,o(b) [110101] b[25..21] t[20..16] o[15..0].
+ kMipsFswc1, // swc1 t,o(b) [111001] b[25..21] t[20..16] o[15..0].
+ kMipsFsdc1, // sdc1 t,o(b) [111101] b[25..21] t[20..16] o[15..0].
+ kMipsMfc1, // mfc1 t,s [01000100000] t[20..16] s[15..11] [00000000000].
+ kMipsMtc1, // mtc1 t,s [01000100100] t[20..16] s[15..11] [00000000000].
+ kMipsDelta, // Psuedo for ori t, s, <label>-<label>.
+ kMipsDeltaHi, // Pseudo for lui t, high16(<label>-<label>).
+ kMipsDeltaLo, // Pseudo for ori t, s, low16(<label>-<label>).
+ kMipsCurrPC, // jal to .+8 to materialize pc.
+ kMipsSync, // sync kind [000000] [0000000000000000] s[10..6] [001111].
+ kMipsUndefined, // undefined [011001xxxxxxxxxxxxxxxx].
kMipsLast
};
-/* Bit flags describing the behavior of each native opcode */
-/* Instruction assembly field_loc kind */
+// Instruction assembly field_loc kind.
enum MipsEncodingKind {
kFmtUnused,
kFmtBitBlt, /* Bit string using end/start */
@@ -415,26 +406,26 @@
kFmtBlt5_2, /* Same 5-bit field to 2 locations */
};
-/* Struct used to define the snippet positions for each MIPS opcode */
+// Struct used to define the snippet positions for each MIPS opcode.
struct MipsEncodingMap {
uint32_t skeleton;
struct {
MipsEncodingKind kind;
- int end; /* end for kFmtBitBlt, 1-bit slice end for FP regs */
- int start; /* start for kFmtBitBlt, 4-bit slice end for FP regs */
+ int end; // end for kFmtBitBlt, 1-bit slice end for FP regs.
+ int start; // start for kFmtBitBlt, 4-bit slice end for FP regs.
} field_loc[4];
MipsOpCode opcode;
uint64_t flags;
const char *name;
const char* fmt;
- int size; /* Size in bytes */
+ int size; // Note: size is in bytes.
};
extern MipsEncodingMap EncodingMap[kMipsLast];
#define IS_UIMM16(v) ((0 <= (v)) && ((v) <= 65535))
#define IS_SIMM16(v) ((-32768 <= (v)) && ((v) <= 32766))
-#define IS_SIMM16_2WORD(v) ((-32764 <= (v)) && ((v) <= 32763)) /* 2 offsets must fit */
+#define IS_SIMM16_2WORD(v) ((-32764 <= (v)) && ((v) <= 32763)) // 2 offsets must fit.
} // namespace art
diff --git a/src/compiler/codegen/mips/target_mips.cc b/src/compiler/codegen/mips/target_mips.cc
index b9159ed..ed884b2 100644
--- a/src/compiler/codegen/mips/target_mips.cc
+++ b/src/compiler/codegen/mips/target_mips.cc
@@ -16,6 +16,7 @@
#include "../../compiler_internals.h"
#include "mips_lir.h"
+#include "codegen_mips.h"
#include "../ralloc_util.h"
#include "../codegen_util.h"
@@ -31,39 +32,37 @@
r_RA};
static int core_temps[] = {r_V0, r_V1, r_A0, r_A1, r_A2, r_A3, r_T0, r_T1, r_T2,
r_T3, r_T4, r_T5, r_T6, r_T7, r_T8};
-#ifdef __mips_hard_float
static int FpRegs[] = {r_F0, r_F1, r_F2, r_F3, r_F4, r_F5, r_F6, r_F7,
r_F8, r_F9, r_F10, r_F11, r_F12, r_F13, r_F14, r_F15};
static int fp_temps[] = {r_F0, r_F1, r_F2, r_F3, r_F4, r_F5, r_F6, r_F7,
r_F8, r_F9, r_F10, r_F11, r_F12, r_F13, r_F14, r_F15};
-#endif
-RegLocation LocCReturn()
+RegLocation MipsCodegen::LocCReturn()
{
RegLocation res = MIPS_LOC_C_RETURN;
return res;
}
-RegLocation LocCReturnWide()
+RegLocation MipsCodegen::LocCReturnWide()
{
RegLocation res = MIPS_LOC_C_RETURN_WIDE;
return res;
}
-RegLocation LocCReturnFloat()
+RegLocation MipsCodegen::LocCReturnFloat()
{
RegLocation res = MIPS_LOC_C_RETURN_FLOAT;
return res;
}
-RegLocation LocCReturnDouble()
+RegLocation MipsCodegen::LocCReturnDouble()
{
RegLocation res = MIPS_LOC_C_RETURN_DOUBLE;
return res;
}
// Return a target-dependent special register.
-int TargetReg(SpecialTargetRegister reg) {
+int MipsCodegen::TargetReg(SpecialTargetRegister reg) {
int res = INVALID_REG;
switch (reg) {
case kSelf: res = rMIPS_SELF; break;
@@ -88,37 +87,19 @@
}
// Create a double from a pair of singles.
-int S2d(int low_reg, int high_reg)
+int MipsCodegen::S2d(int low_reg, int high_reg)
{
return MIPS_S2D(low_reg, high_reg);
}
-// Is reg a single or double?
-bool FpReg(int reg)
-{
- return MIPS_FPREG(reg);
-}
-
-// Is reg a single?
-bool SingleReg(int reg)
-{
- return MIPS_SINGLEREG(reg);
-}
-
-// Is reg a double?
-bool DoubleReg(int reg)
-{
- return MIPS_DOUBLEREG(reg);
-}
-
// Return mask to strip off fp reg flags and bias.
-uint32_t FpRegMask()
+uint32_t MipsCodegen::FpRegMask()
{
return MIPS_FP_REG_MASK;
}
// True if both regs single, both core or both double.
-bool SameRegType(int reg1, int reg2)
+bool MipsCodegen::SameRegType(int reg1, int reg2)
{
return (MIPS_REGTYPE(reg1) == MIPS_REGTYPE(reg2));
}
@@ -126,7 +107,7 @@
/*
* Decode the register id.
*/
-uint64_t GetRegMaskCommon(CompilationUnit* cu, int reg)
+uint64_t MipsCodegen::GetRegMaskCommon(CompilationUnit* cu, int reg)
{
uint64_t seed;
int shift;
@@ -143,18 +124,18 @@
return (seed << shift);
}
-uint64_t GetPCUseDefEncoding()
+uint64_t MipsCodegen::GetPCUseDefEncoding()
{
return ENCODE_MIPS_REG_PC;
}
-void SetupTargetResourceMasks(CompilationUnit* cu, LIR* lir)
+void MipsCodegen::SetupTargetResourceMasks(CompilationUnit* cu, LIR* lir)
{
DCHECK_EQ(cu->instruction_set, kMips);
// Mips-specific resource map setup here.
- uint64_t flags = EncodingMap[lir->opcode].flags;
+ uint64_t flags = MipsCodegen::EncodingMap[lir->opcode].flags;
if (flags & REG_DEF_SP) {
lir->def_mask |= ENCODE_MIPS_REG_SP;
@@ -182,7 +163,7 @@
* Interpret a format string and build a string no longer than size
* See format key in Assemble.c.
*/
-std::string BuildInsnString(const char *fmt, LIR *lir, unsigned char* base_addr)
+std::string MipsCodegen::BuildInsnString(const char *fmt, LIR *lir, unsigned char* base_addr)
{
std::string buf;
int i;
@@ -275,7 +256,7 @@
}
// FIXME: need to redo resource maps for MIPS - fix this at that time
-void DumpResourceMask(LIR *mips_lir, uint64_t mask, const char *prefix)
+void MipsCodegen::DumpResourceMask(LIR *mips_lir, uint64_t mask, const char *prefix)
{
char buf[256];
buf[0] = 0;
@@ -326,7 +307,7 @@
* machinery is in place, always spill lr.
*/
-void AdjustSpillMask(CompilationUnit* cu)
+void MipsCodegen::AdjustSpillMask(CompilationUnit* cu)
{
cu->core_spill_mask |= (1 << r_RA);
cu->num_core_spills++;
@@ -338,12 +319,12 @@
* include any holes in the mask. Associate holes with
* Dalvik register INVALID_VREG (0xFFFFU).
*/
-void MarkPreservedSingle(CompilationUnit* cu, int s_reg, int reg)
+void MipsCodegen::MarkPreservedSingle(CompilationUnit* cu, int s_reg, int reg)
{
LOG(FATAL) << "No support yet for promoted FP regs";
}
-void FlushRegWide(CompilationUnit* cu, int reg1, int reg2)
+void MipsCodegen::FlushRegWide(CompilationUnit* cu, int reg1, int reg2)
{
RegisterInfo* info1 = GetRegInfo(cu, reg1);
RegisterInfo* info2 = GetRegInfo(cu, reg2);
@@ -365,7 +346,7 @@
}
}
-void FlushReg(CompilationUnit* cu, int reg)
+void MipsCodegen::FlushReg(CompilationUnit* cu, int reg)
{
RegisterInfo* info = GetRegInfo(cu, reg);
if (info->live && info->dirty) {
@@ -376,12 +357,12 @@
}
/* Give access to the target-dependent FP register encoding to common code */
-bool IsFpReg(int reg) {
+bool MipsCodegen::IsFpReg(int reg) {
return MIPS_FPREG(reg);
}
/* Clobber all regs that might be used by an external C call */
-void ClobberCalleeSave(CompilationUnit *cu)
+void MipsCodegen::ClobberCalleeSave(CompilationUnit *cu)
{
Clobber(cu, r_ZERO);
Clobber(cu, r_AT);
@@ -424,28 +405,28 @@
Clobber(cu, r_F15);
}
-RegLocation GetReturnWideAlt(CompilationUnit* cu)
+RegLocation MipsCodegen::GetReturnWideAlt(CompilationUnit* cu)
{
UNIMPLEMENTED(FATAL) << "No GetReturnWideAlt for MIPS";
RegLocation res = LocCReturnWide();
return res;
}
-RegLocation GetReturnAlt(CompilationUnit* cu)
+RegLocation MipsCodegen::GetReturnAlt(CompilationUnit* cu)
{
UNIMPLEMENTED(FATAL) << "No GetReturnAlt for MIPS";
RegLocation res = LocCReturn();
return res;
}
-RegisterInfo* GetRegInfo(CompilationUnit* cu, int reg)
+RegisterInfo* MipsCodegen::GetRegInfo(CompilationUnit* cu, int reg)
{
return MIPS_FPREG(reg) ? &cu->reg_pool->FPRegs[reg & MIPS_FP_REG_MASK]
: &cu->reg_pool->core_regs[reg];
}
/* To be used when explicitly managing register use */
-void LockCallTemps(CompilationUnit* cu)
+void MipsCodegen::LockCallTemps(CompilationUnit* cu)
{
LockTemp(cu, rMIPS_ARG0);
LockTemp(cu, rMIPS_ARG1);
@@ -454,7 +435,7 @@
}
/* To be used when explicitly managing register use */
-void FreeCallTemps(CompilationUnit* cu)
+void MipsCodegen::FreeCallTemps(CompilationUnit* cu)
{
FreeTemp(cu, rMIPS_ARG0);
FreeTemp(cu, rMIPS_ARG1);
@@ -462,13 +443,7 @@
FreeTemp(cu, rMIPS_ARG3);
}
-/* Architecture-specific initializations and checks go here */
-bool ArchVariantInit(void)
-{
- return true;
-}
-
-void GenMemBarrier(CompilationUnit *cu, MemBarrierKind barrier_kind)
+void MipsCodegen::GenMemBarrier(CompilationUnit *cu, MemBarrierKind barrier_kind)
{
#if ANDROID_SMP != 0
NewLIR1(cu, kMipsSync, 0 /* Only stype currently supported */);
@@ -479,21 +454,19 @@
* Alloc a pair of core registers, or a double. Low reg in low byte,
* high reg in next byte.
*/
-int AllocTypedTempPair(CompilationUnit *cu, bool fp_hint,
+int MipsCodegen::AllocTypedTempPair(CompilationUnit *cu, bool fp_hint,
int reg_class)
{
int high_reg;
int low_reg;
int res = 0;
-#ifdef __mips_hard_float
if (((reg_class == kAnyReg) && fp_hint) || (reg_class == kFPReg)) {
low_reg = AllocTempDouble(cu);
high_reg = low_reg + 1;
res = (low_reg & 0xff) | ((high_reg & 0xff) << 8);
return res;
}
-#endif
low_reg = AllocTemp(cu);
high_reg = AllocTemp(cu);
@@ -501,29 +474,22 @@
return res;
}
-int AllocTypedTemp(CompilationUnit *cu, bool fp_hint, int reg_class)
+int MipsCodegen::AllocTypedTemp(CompilationUnit *cu, bool fp_hint, int reg_class)
{
-#ifdef __mips_hard_float
if (((reg_class == kAnyReg) && fp_hint) || (reg_class == kFPReg))
{
return AllocTempFloat(cu);
}
-#endif
return AllocTemp(cu);
}
-void CompilerInitializeRegAlloc(CompilationUnit* cu)
+void MipsCodegen::CompilerInitializeRegAlloc(CompilationUnit* cu)
{
int num_regs = sizeof(core_regs)/sizeof(*core_regs);
int num_reserved = sizeof(ReservedRegs)/sizeof(*ReservedRegs);
int num_temps = sizeof(core_temps)/sizeof(*core_temps);
-#ifdef __mips_hard_float
int num_fp_regs = sizeof(FpRegs)/sizeof(*FpRegs);
int num_fp_temps = sizeof(fp_temps)/sizeof(*fp_temps);
-#else
- int num_fp_regs = 0;
- int num_fp_temps = 0;
-#endif
RegisterPool *pool =
static_cast<RegisterPool*>(NewMem(cu, sizeof(*pool), true, kAllocRegAlloc));
cu->reg_pool = pool;
@@ -568,8 +534,7 @@
}
}
-void FreeRegLocTemps(CompilationUnit* cu, RegLocation rl_keep,
- RegLocation rl_free)
+void MipsCodegen::FreeRegLocTemps(CompilationUnit* cu, RegLocation rl_keep, RegLocation rl_free)
{
if ((rl_free.low_reg != rl_keep.low_reg) && (rl_free.low_reg != rl_keep.high_reg) &&
(rl_free.high_reg != rl_keep.low_reg) && (rl_free.high_reg != rl_keep.high_reg)) {
@@ -584,13 +549,13 @@
* ensure that all branch instructions can be restarted if
* there is a trap in the shadow. Allocate a temp register.
*/
-int LoadHelper(CompilationUnit* cu, int offset)
+int MipsCodegen::LoadHelper(CompilationUnit* cu, int offset)
{
LoadWordDisp(cu, rMIPS_SELF, offset, r_T9);
return r_T9;
}
-void SpillCoreRegs(CompilationUnit* cu)
+void MipsCodegen::SpillCoreRegs(CompilationUnit* cu)
{
if (cu->num_core_spills == 0) {
return;
@@ -606,7 +571,7 @@
}
}
-void UnSpillCoreRegs(CompilationUnit* cu)
+void MipsCodegen::UnSpillCoreRegs(CompilationUnit* cu)
{
if (cu->num_core_spills == 0) {
return;
@@ -622,39 +587,38 @@
OpRegImm(cu, kOpAdd, rMIPS_SP, cu->frame_size);
}
-bool BranchUnconditional(LIR* lir)
+bool MipsCodegen::IsUnconditionalBranch(LIR* lir)
{
return (lir->opcode == kMipsB);
}
/* Common initialization routine for an architecture family */
-bool ArchInit()
+bool InitMipsCodegen(CompilationUnit* cu)
{
- int i;
-
- for (i = 0; i < kMipsLast; i++) {
- if (EncodingMap[i].opcode != i) {
- LOG(FATAL) << "Encoding order for " << EncodingMap[i].name <<
- " is wrong: expecting " << i << ", seeing " << static_cast<int>(EncodingMap[i].opcode);
+ cu->cg.reset(new MipsCodegen());
+ for (int i = 0; i < kMipsLast; i++) {
+ if (MipsCodegen::EncodingMap[i].opcode != i) {
+ LOG(FATAL) << "Encoding order for " << MipsCodegen::EncodingMap[i].name
+ << " is wrong: expecting " << i << ", seeing "
+ << static_cast<int>(MipsCodegen::EncodingMap[i].opcode);
}
}
-
- return ArchVariantInit();
+ return true;
}
-uint64_t GetTargetInstFlags(int opcode)
+uint64_t MipsCodegen::GetTargetInstFlags(int opcode)
{
- return EncodingMap[opcode].flags;
+ return MipsCodegen::EncodingMap[opcode].flags;
}
-const char* GetTargetInstName(int opcode)
+const char* MipsCodegen::GetTargetInstName(int opcode)
{
- return EncodingMap[opcode].name;
+ return MipsCodegen::EncodingMap[opcode].name;
}
-const char* GetTargetInstFmt(int opcode)
+const char* MipsCodegen::GetTargetInstFmt(int opcode)
{
- return EncodingMap[opcode].fmt;
+ return MipsCodegen::EncodingMap[opcode].fmt;
}
} // namespace art
diff --git a/src/compiler/codegen/mips/utility_mips.cc b/src/compiler/codegen/mips/utility_mips.cc
index 168b462..44d75d1 100644
--- a/src/compiler/codegen/mips/utility_mips.cc
+++ b/src/compiler/codegen/mips/utility_mips.cc
@@ -15,23 +15,14 @@
*/
#include "mips_lir.h"
+#include "codegen_mips.h"
#include "../codegen_util.h"
#include "../ralloc_util.h"
namespace art {
/* This file contains codegen for the MIPS32 ISA. */
-
-void GenBarrier(CompilationUnit *cu);
-void LoadPair(CompilationUnit *cu, int base, int low_reg, int high_reg);
-LIR *LoadWordDisp(CompilationUnit *cu, int rBase, int displacement,
- int r_dest);
-LIR *StoreWordDisp(CompilationUnit *cu, int rBase,
- int displacement, int r_src);
-LIR *LoadConstant(CompilationUnit *cu, int r_dest, int value);
-
-#ifdef __mips_hard_float
-LIR *FpRegCopy(CompilationUnit *cu, int r_dest, int r_src)
+LIR* MipsCodegen::OpFpRegCopy(CompilationUnit *cu, int r_dest, int r_src)
{
int opcode;
/* must be both DOUBLE or both not DOUBLE */
@@ -60,7 +51,6 @@
}
return res;
}
-#endif
/*
* Load a immediate using a shortcut if possible; otherwise
@@ -71,18 +61,16 @@
* 1) r_dest is freshly returned from AllocTemp or
* 2) The codegen is under fixed register usage
*/
-LIR *LoadConstantNoClobber(CompilationUnit *cu, int r_dest, int value)
+LIR* MipsCodegen::LoadConstantNoClobber(CompilationUnit *cu, int r_dest, int value)
{
LIR *res;
-#ifdef __mips_hard_float
int r_dest_save = r_dest;
int is_fp_reg = MIPS_FPREG(r_dest);
if (is_fp_reg) {
DCHECK(MIPS_SINGLEREG(r_dest));
r_dest = AllocTemp(cu);
}
-#endif
/* See if the value can be constructed cheaply */
if (value == 0) {
@@ -97,25 +85,22 @@
NewLIR3(cu, kMipsOri, r_dest, r_dest, value);
}
-#ifdef __mips_hard_float
if (is_fp_reg) {
NewLIR2(cu, kMipsMtc1, r_dest, r_dest_save);
FreeTemp(cu, r_dest);
}
-#endif
return res;
}
-LIR *OpBranchUnconditional(CompilationUnit *cu, OpKind op)
+LIR* MipsCodegen::OpUnconditionalBranch(CompilationUnit* cu, LIR* target)
{
- DCHECK_EQ(op, kOpUncondBr);
- return NewLIR1(cu, kMipsB, 0 /* offset to be patched */ );
+ LIR* res = NewLIR1(cu, kMipsB, 0 /* offset to be patched during assembly*/ );
+ res->target = target;
+ return res;
}
-LIR *LoadMultiple(CompilationUnit *cu, int rBase, int r_mask);
-
-LIR *OpReg(CompilationUnit *cu, OpKind op, int r_dest_src)
+LIR* MipsCodegen::OpReg(CompilationUnit *cu, OpKind op, int r_dest_src)
{
MipsOpCode opcode = kMipsNop;
switch (op) {
@@ -131,9 +116,7 @@
return NewLIR2(cu, opcode, r_RA, r_dest_src);
}
-LIR *OpRegRegImm(CompilationUnit *cu, OpKind op, int r_dest,
- int r_src1, int value);
-LIR *OpRegImm(CompilationUnit *cu, OpKind op, int r_dest_src1,
+LIR* MipsCodegen::OpRegImm(CompilationUnit *cu, OpKind op, int r_dest_src1,
int value)
{
LIR *res;
@@ -165,8 +148,7 @@
return res;
}
-LIR *OpRegRegReg(CompilationUnit *cu, OpKind op, int r_dest,
- int r_src1, int r_src2)
+LIR* MipsCodegen::OpRegRegReg(CompilationUnit *cu, OpKind op, int r_dest, int r_src1, int r_src2)
{
MipsOpCode opcode = kMipsNop;
switch (op) {
@@ -208,8 +190,7 @@
return NewLIR3(cu, opcode, r_dest, r_src1, r_src2);
}
-LIR *OpRegRegImm(CompilationUnit *cu, OpKind op, int r_dest,
- int r_src1, int value)
+LIR* MipsCodegen::OpRegRegImm(CompilationUnit *cu, OpKind op, int r_dest, int r_src1, int value)
{
LIR *res;
MipsOpCode opcode = kMipsNop;
@@ -298,7 +279,7 @@
return res;
}
-LIR *OpRegReg(CompilationUnit *cu, OpKind op, int r_dest_src1, int r_src2)
+LIR* MipsCodegen::OpRegReg(CompilationUnit *cu, OpKind op, int r_dest_src1, int r_src2)
{
MipsOpCode opcode = kMipsNop;
LIR *res;
@@ -342,8 +323,8 @@
return NewLIR2(cu, opcode, r_dest_src1, r_src2);
}
-LIR *LoadConstantValueWide(CompilationUnit *cu, int r_dest_lo,
- int r_dest_hi, int val_lo, int val_hi)
+LIR* MipsCodegen::LoadConstantValueWide(CompilationUnit *cu, int r_dest_lo, int r_dest_hi,
+ int val_lo, int val_hi)
{
LIR *res;
res = LoadConstantNoClobber(cu, r_dest_lo, val_lo);
@@ -352,15 +333,14 @@
}
/* Load value from base + scaled index. */
-LIR *LoadBaseIndexed(CompilationUnit *cu, int rBase,
- int r_index, int r_dest, int scale, OpSize size)
+LIR* MipsCodegen::LoadBaseIndexed(CompilationUnit *cu, int rBase, int r_index, int r_dest,
+ int scale, OpSize size)
{
LIR *first = NULL;
LIR *res;
MipsOpCode opcode = kMipsNop;
int t_reg = AllocTemp(cu);
-#ifdef __mips_hard_float
if (MIPS_FPREG(r_dest)) {
DCHECK(MIPS_SINGLEREG(r_dest));
DCHECK((size == kWord) || (size == kSingle));
@@ -369,7 +349,6 @@
if (size == kSingle)
size = kWord;
}
-#endif
if (!scale) {
first = NewLIR3(cu, kMipsAddu, t_reg , rBase, r_index);
@@ -379,11 +358,9 @@
}
switch (size) {
-#ifdef __mips_hard_float
case kSingle:
opcode = kMipsFlwc1;
break;
-#endif
case kWord:
opcode = kMipsLw;
break;
@@ -409,15 +386,14 @@
}
/* store value base base + scaled index. */
-LIR *StoreBaseIndexed(CompilationUnit *cu, int rBase,
- int r_index, int r_src, int scale, OpSize size)
+LIR* MipsCodegen::StoreBaseIndexed(CompilationUnit *cu, int rBase, int r_index, int r_src,
+ int scale, OpSize size)
{
LIR *first = NULL;
MipsOpCode opcode = kMipsNop;
int r_new_index = r_index;
int t_reg = AllocTemp(cu);
-#ifdef __mips_hard_float
if (MIPS_FPREG(r_src)) {
DCHECK(MIPS_SINGLEREG(r_src));
DCHECK((size == kWord) || (size == kSingle));
@@ -426,7 +402,6 @@
if (size == kSingle)
size = kWord;
}
-#endif
if (!scale) {
first = NewLIR3(cu, kMipsAddu, t_reg , rBase, r_index);
@@ -436,11 +411,9 @@
}
switch (size) {
-#ifdef __mips_hard_float
case kSingle:
opcode = kMipsFswc1;
break;
-#endif
case kWord:
opcode = kMipsSw;
break;
@@ -460,53 +433,8 @@
return first;
}
-LIR *LoadMultiple(CompilationUnit *cu, int rBase, int r_mask)
-{
- int i;
- int load_cnt = 0;
- LIR *res = NULL ;
- GenBarrier(cu);
-
- for (i = 0; i < 8; i++, r_mask >>= 1) {
- if (r_mask & 0x1) { /* map r0 to MIPS r_A0 */
- NewLIR3(cu, kMipsLw, i+r_A0, load_cnt*4, rBase);
- load_cnt++;
- }
- }
-
- if (load_cnt) {/* increment after */
- NewLIR3(cu, kMipsAddiu, rBase, rBase, load_cnt*4);
- }
-
- GenBarrier(cu);
- return res; /* NULL always returned which should be ok since no callers use it */
-}
-
-LIR *StoreMultiple(CompilationUnit *cu, int rBase, int r_mask)
-{
- int i;
- int store_cnt = 0;
- LIR *res = NULL ;
- GenBarrier(cu);
-
- for (i = 0; i < 8; i++, r_mask >>= 1) {
- if (r_mask & 0x1) { /* map r0 to MIPS r_A0 */
- NewLIR3(cu, kMipsSw, i+r_A0, store_cnt*4, rBase);
- store_cnt++;
- }
- }
-
- if (store_cnt) { /* increment after */
- NewLIR3(cu, kMipsAddiu, rBase, rBase, store_cnt*4);
- }
-
- GenBarrier(cu);
- return res; /* NULL always returned which should be ok since no callers use it */
-}
-
-LIR *LoadBaseDispBody(CompilationUnit *cu, int rBase,
- int displacement, int r_dest, int r_dest_hi,
- OpSize size, int s_reg)
+LIR* MipsCodegen::LoadBaseDispBody(CompilationUnit *cu, int rBase, int displacement, int r_dest,
+ int r_dest_hi, OpSize size, int s_reg)
/*
* Load value from base + displacement. Optionally perform null check
* on base (which must have an associated s_reg and MIR). If not
@@ -528,7 +456,6 @@
case kDouble:
pair = true;
opcode = kMipsLw;
-#ifdef __mips_hard_float
if (MIPS_FPREG(r_dest)) {
opcode = kMipsFlwc1;
if (MIPS_DOUBLEREG(r_dest)) {
@@ -539,19 +466,16 @@
}
r_dest_hi = r_dest + 1;
}
-#endif
short_form = IS_SIMM16_2WORD(displacement);
DCHECK_EQ((displacement & 0x3), 0);
break;
case kWord:
case kSingle:
opcode = kMipsLw;
-#ifdef __mips_hard_float
if (MIPS_FPREG(r_dest)) {
opcode = kMipsFlwc1;
DCHECK(MIPS_SINGLEREG(r_dest));
}
-#endif
DCHECK_EQ((displacement & 0x3), 0);
break;
case kUnsignedHalf:
@@ -598,33 +522,31 @@
}
if (rBase == rMIPS_SP) {
- AnnotateDalvikRegAccess(load,
- (displacement + (pair ? LOWORD_OFFSET : 0)) >> 2,
+ AnnotateDalvikRegAccess(cu, load, (displacement + (pair ? LOWORD_OFFSET : 0)) >> 2,
true /* is_load */, pair /* is64bit */);
if (pair) {
- AnnotateDalvikRegAccess(load2, (displacement + HIWORD_OFFSET) >> 2,
+ AnnotateDalvikRegAccess(cu, load2, (displacement + HIWORD_OFFSET) >> 2,
true /* is_load */, pair /* is64bit */);
}
}
return load;
}
-LIR *LoadBaseDisp(CompilationUnit *cu, int rBase,
- int displacement, int r_dest, OpSize size, int s_reg)
+LIR* MipsCodegen::LoadBaseDisp(CompilationUnit *cu, int rBase, int displacement, int r_dest,
+ OpSize size, int s_reg)
{
return LoadBaseDispBody(cu, rBase, displacement, r_dest, -1,
size, s_reg);
}
-LIR *LoadBaseDispWide(CompilationUnit *cu, int rBase,
- int displacement, int r_dest_lo, int r_dest_hi, int s_reg)
+LIR* MipsCodegen::LoadBaseDispWide(CompilationUnit *cu, int rBase, int displacement,
+ int r_dest_lo, int r_dest_hi, int s_reg)
{
- return LoadBaseDispBody(cu, rBase, displacement, r_dest_lo, r_dest_hi,
- kLong, s_reg);
+ return LoadBaseDispBody(cu, rBase, displacement, r_dest_lo, r_dest_hi, kLong, s_reg);
}
-LIR *StoreBaseDispBody(CompilationUnit *cu, int rBase,
- int displacement, int r_src, int r_src_hi, OpSize size)
+LIR* MipsCodegen::StoreBaseDispBody(CompilationUnit *cu, int rBase, int displacement,
+ int r_src, int r_src_hi, OpSize size)
{
LIR *res;
LIR *store = NULL;
@@ -638,7 +560,6 @@
case kDouble:
pair = true;
opcode = kMipsSw;
-#ifdef __mips_hard_float
if (MIPS_FPREG(r_src)) {
opcode = kMipsFswc1;
if (MIPS_DOUBLEREG(r_src)) {
@@ -649,19 +570,16 @@
}
r_src_hi = r_src + 1;
}
-#endif
short_form = IS_SIMM16_2WORD(displacement);
DCHECK_EQ((displacement & 0x3), 0);
break;
case kWord:
case kSingle:
opcode = kMipsSw;
-#ifdef __mips_hard_float
if (MIPS_FPREG(r_src)) {
opcode = kMipsFswc1;
DCHECK(MIPS_SINGLEREG(r_src));
}
-#endif
DCHECK_EQ((displacement & 0x3), 0);
break;
case kUnsignedHalf:
@@ -699,10 +617,10 @@
}
if (rBase == rMIPS_SP) {
- AnnotateDalvikRegAccess(store, (displacement + (pair ? LOWORD_OFFSET : 0))
- >> 2, false /* is_load */, pair /* is64bit */);
+ AnnotateDalvikRegAccess(cu, store, (displacement + (pair ? LOWORD_OFFSET : 0)) >> 2,
+ false /* is_load */, pair /* is64bit */);
if (pair) {
- AnnotateDalvikRegAccess(store2, (displacement + HIWORD_OFFSET) >> 2,
+ AnnotateDalvikRegAccess(cu, store2, (displacement + HIWORD_OFFSET) >> 2,
false /* is_load */, pair /* is64bit */);
}
}
@@ -710,37 +628,37 @@
return res;
}
-LIR *StoreBaseDisp(CompilationUnit *cu, int rBase,
- int displacement, int r_src, OpSize size)
+LIR* MipsCodegen::StoreBaseDisp(CompilationUnit *cu, int rBase, int displacement, int r_src,
+ OpSize size)
{
return StoreBaseDispBody(cu, rBase, displacement, r_src, -1, size);
}
-LIR *StoreBaseDispWide(CompilationUnit *cu, int rBase,
- int displacement, int r_src_lo, int r_src_hi)
+LIR* MipsCodegen::StoreBaseDispWide(CompilationUnit *cu, int rBase, int displacement,
+ int r_src_lo, int r_src_hi)
{
return StoreBaseDispBody(cu, rBase, displacement, r_src_lo, r_src_hi, kLong);
}
-void LoadPair(CompilationUnit *cu, int base, int low_reg, int high_reg)
+void MipsCodegen::LoadPair(CompilationUnit *cu, int base, int low_reg, int high_reg)
{
LoadWordDisp(cu, base, LOWORD_OFFSET , low_reg);
LoadWordDisp(cu, base, HIWORD_OFFSET , high_reg);
}
-LIR* OpThreadMem(CompilationUnit* cu, OpKind op, int thread_offset)
+LIR* MipsCodegen::OpThreadMem(CompilationUnit* cu, OpKind op, int thread_offset)
{
LOG(FATAL) << "Unexpected use of OpThreadMem for MIPS";
return NULL;
}
-LIR* OpMem(CompilationUnit* cu, OpKind op, int rBase, int disp)
+LIR* MipsCodegen::OpMem(CompilationUnit* cu, OpKind op, int rBase, int disp)
{
LOG(FATAL) << "Unexpected use of OpMem for MIPS";
return NULL;
}
-LIR* StoreBaseIndexedDisp(CompilationUnit *cu,
+LIR* MipsCodegen::StoreBaseIndexedDisp(CompilationUnit *cu,
int rBase, int r_index, int scale, int displacement,
int r_src, int r_src_hi,
OpSize size, int s_reg)
@@ -749,14 +667,14 @@
return NULL;
}
-LIR* OpRegMem(CompilationUnit *cu, OpKind op, int r_dest, int rBase,
+LIR* MipsCodegen::OpRegMem(CompilationUnit *cu, OpKind op, int r_dest, int rBase,
int offset)
{
LOG(FATAL) << "Unexpected use of OpRegMem for MIPS";
return NULL;
}
-LIR* LoadBaseIndexedDisp(CompilationUnit *cu,
+LIR* MipsCodegen::LoadBaseIndexedDisp(CompilationUnit *cu,
int rBase, int r_index, int scale, int displacement,
int r_dest, int r_dest_hi,
OpSize size, int s_reg)
@@ -765,7 +683,7 @@
return NULL;
}
-LIR* OpCondBranch(CompilationUnit* cu, ConditionCode cc, LIR* target)
+LIR* MipsCodegen::OpCondBranch(CompilationUnit* cu, ConditionCode cc, LIR* target)
{
LOG(FATAL) << "Unexpected use of OpCondBranch for MIPS";
return NULL;