Instruction set features for ARM64, MIPS and X86.
Also, refactor how feature strings are handled so they are additive or
subtractive.
Make MIPS have features for FPU 32-bit and MIPS v2. Use in the quick compiler
rather than #ifdefs that wouldn't have worked in cross-compilation.
Add SIMD features for x86/x86-64 proposed in:
https://android-review.googlesource.com/#/c/112370/
Bug: 18056890
Change-Id: Ic88ff84a714926bd277beb74a430c5c7d5ed7666
diff --git a/compiler/dex/quick/mips/target_mips.cc b/compiler/dex/quick/mips/target_mips.cc
index 4a340ec..185112d 100644
--- a/compiler/dex/quick/mips/target_mips.cc
+++ b/compiler/dex/quick/mips/target_mips.cc
@@ -20,6 +20,7 @@
#include <string>
+#include "arch/mips/instruction_set_features_mips.h"
#include "backend_mips.h"
#include "dex/compiler_internals.h"
#include "dex/quick/mir_to_lir-inl.h"
@@ -34,8 +35,12 @@
static constexpr RegStorage sp_regs_arr[] =
{rs_rF0, rs_rF1, rs_rF2, rs_rF3, rs_rF4, rs_rF5, rs_rF6, rs_rF7, rs_rF8, rs_rF9, rs_rF10,
rs_rF11, rs_rF12, rs_rF13, rs_rF14, rs_rF15};
-static constexpr RegStorage dp_regs_arr[] =
- {rs_rD0, rs_rD1, rs_rD2, rs_rD3, rs_rD4, rs_rD5, rs_rD6, rs_rD7};
+static constexpr RegStorage dp_fr0_regs_arr[] =
+ {rs_rD0_fr0, rs_rD1_fr0, rs_rD2_fr0, rs_rD3_fr0, rs_rD4_fr0, rs_rD5_fr0, rs_rD6_fr0,
+ rs_rD7_fr0};
+static constexpr RegStorage dp_fr1_regs_arr[] =
+ {rs_rD0_fr1, rs_rD1_fr1, rs_rD2_fr1, rs_rD3_fr1, rs_rD4_fr1, rs_rD5_fr1, rs_rD6_fr1,
+ rs_rD7_fr1};
static constexpr RegStorage reserved_regs_arr[] =
{rs_rZERO, rs_rAT, rs_rS0, rs_rS1, rs_rK0, rs_rK1, rs_rGP, rs_rSP, rs_rRA};
static constexpr RegStorage core_temps_arr[] =
@@ -44,17 +49,23 @@
static constexpr RegStorage sp_temps_arr[] =
{rs_rF0, rs_rF1, rs_rF2, rs_rF3, rs_rF4, rs_rF5, rs_rF6, rs_rF7, rs_rF8, rs_rF9, rs_rF10,
rs_rF11, rs_rF12, rs_rF13, rs_rF14, rs_rF15};
-static constexpr RegStorage dp_temps_arr[] =
- {rs_rD0, rs_rD1, rs_rD2, rs_rD3, rs_rD4, rs_rD5, rs_rD6, rs_rD7};
+static constexpr RegStorage dp_fr0_temps_arr[] =
+ {rs_rD0_fr0, rs_rD1_fr0, rs_rD2_fr0, rs_rD3_fr0, rs_rD4_fr0, rs_rD5_fr0, rs_rD6_fr0,
+ rs_rD7_fr0};
+static constexpr RegStorage dp_fr1_temps_arr[] =
+ {rs_rD0_fr1, rs_rD1_fr1, rs_rD2_fr1, rs_rD3_fr1, rs_rD4_fr1, rs_rD5_fr1, rs_rD6_fr1,
+ rs_rD7_fr1};
static constexpr ArrayRef<const RegStorage> empty_pool;
static constexpr ArrayRef<const RegStorage> core_regs(core_regs_arr);
static constexpr ArrayRef<const RegStorage> sp_regs(sp_regs_arr);
-static constexpr ArrayRef<const RegStorage> dp_regs(dp_regs_arr);
+static constexpr ArrayRef<const RegStorage> dp_fr0_regs(dp_fr0_regs_arr);
+static constexpr ArrayRef<const RegStorage> dp_fr1_regs(dp_fr1_regs_arr);
static constexpr ArrayRef<const RegStorage> reserved_regs(reserved_regs_arr);
static constexpr ArrayRef<const RegStorage> core_temps(core_temps_arr);
static constexpr ArrayRef<const RegStorage> sp_temps(sp_temps_arr);
-static constexpr ArrayRef<const RegStorage> dp_temps(dp_temps_arr);
+static constexpr ArrayRef<const RegStorage> dp_fr0_temps(dp_fr0_temps_arr);
+static constexpr ArrayRef<const RegStorage> dp_fr1_temps(dp_fr1_temps_arr);
RegLocation MipsMir2Lir::LocCReturn() {
return mips_loc_c_return;
@@ -129,14 +140,17 @@
* Decode the register id.
*/
ResourceMask MipsMir2Lir::GetRegMaskCommon(const RegStorage& reg) const {
- return reg.IsDouble()
- /* Each double register is equal to a pair of single-precision FP registers */
-#if (FR_BIT == 0)
- ? ResourceMask::TwoBits((reg.GetRegNum() & ~1) + kMipsFPReg0)
-#else
- ? ResourceMask::TwoBits(reg.GetRegNum() * 2 + kMipsFPReg0)
-#endif
- : ResourceMask::Bit(reg.IsSingle() ? reg.GetRegNum() + kMipsFPReg0 : reg.GetRegNum());
+ if (reg.IsDouble()) {
+ if (cu_->GetInstructionSetFeatures()->AsMipsInstructionSetFeatures()->Is32BitFloatingPoint()) {
+ return ResourceMask::TwoBits((reg.GetRegNum() & ~1) + kMipsFPReg0);
+ } else {
+ return ResourceMask::TwoBits(reg.GetRegNum() * 2 + kMipsFPReg0);
+ }
+ } else if (reg.IsSingle()) {
+ return ResourceMask::Bit(reg.GetRegNum() + kMipsFPReg0);
+ } else {
+ return ResourceMask::Bit(reg.GetRegNum());
+ }
}
ResourceMask MipsMir2Lir::GetPCUseDefEncoding() const {
@@ -382,14 +396,25 @@
Clobber(rs_rF13);
Clobber(rs_rF14);
Clobber(rs_rF15);
- Clobber(rs_rD0);
- Clobber(rs_rD1);
- Clobber(rs_rD2);
- Clobber(rs_rD3);
- Clobber(rs_rD4);
- Clobber(rs_rD5);
- Clobber(rs_rD6);
- Clobber(rs_rD7);
+ if (cu_->GetInstructionSetFeatures()->AsMipsInstructionSetFeatures()->Is32BitFloatingPoint()) {
+ Clobber(rs_rD0_fr0);
+ Clobber(rs_rD1_fr0);
+ Clobber(rs_rD2_fr0);
+ Clobber(rs_rD3_fr0);
+ Clobber(rs_rD4_fr0);
+ Clobber(rs_rD5_fr0);
+ Clobber(rs_rD6_fr0);
+ Clobber(rs_rD7_fr0);
+ } else {
+ Clobber(rs_rD0_fr1);
+ Clobber(rs_rD1_fr1);
+ Clobber(rs_rD2_fr1);
+ Clobber(rs_rD3_fr1);
+ Clobber(rs_rD4_fr1);
+ Clobber(rs_rD5_fr1);
+ Clobber(rs_rD6_fr1);
+ Clobber(rs_rD7_fr1);
+ }
}
RegLocation MipsMir2Lir::GetReturnWideAlt() {
@@ -420,33 +445,37 @@
FreeTemp(rs_rMIPS_ARG3);
}
-bool MipsMir2Lir::GenMemBarrier(MemBarrierKind barrier_kind) {
- UNUSED(barrier_kind);
-#if ANDROID_SMP != 0
- NewLIR1(kMipsSync, 0 /* Only stype currently supported */);
- return true;
-#else
- return false;
-#endif
+bool MipsMir2Lir::GenMemBarrier(MemBarrierKind barrier_kind ATTRIBUTE_UNUSED) {
+ if (cu_->GetInstructionSetFeatures()->IsSmp()) {
+ NewLIR1(kMipsSync, 0 /* Only stype currently supported */);
+ return true;
+ } else {
+ return false;
+ }
}
void MipsMir2Lir::CompilerInitializeRegAlloc() {
+ const bool fpu_is_32bit =
+ cu_->GetInstructionSetFeatures()->AsMipsInstructionSetFeatures()->Is32BitFloatingPoint();
reg_pool_.reset(new (arena_) RegisterPool(this, arena_, core_regs, empty_pool /* core64 */,
- sp_regs, dp_regs,
+ sp_regs,
+ fpu_is_32bit ? dp_fr0_regs : dp_fr1_regs,
reserved_regs, empty_pool /* reserved64 */,
core_temps, empty_pool /* core64_temps */,
- sp_temps, dp_temps));
+ sp_temps,
+ fpu_is_32bit ? dp_fr0_temps : dp_fr1_temps));
// Target-specific adjustments.
// Alias single precision floats to appropriate half of overlapping double.
for (RegisterInfo* info : reg_pool_->sp_regs_) {
int sp_reg_num = info->GetReg().GetRegNum();
-#if (FR_BIT == 0)
- int dp_reg_num = sp_reg_num & ~1;
-#else
- int dp_reg_num = sp_reg_num >> 1;
-#endif
+ int dp_reg_num;
+ if (fpu_is_32bit) {
+ dp_reg_num = sp_reg_num & ~1;
+ } else {
+ dp_reg_num = sp_reg_num >> 1;
+ }
RegStorage dp_reg = RegStorage::Solo64(RegStorage::kFloatingPoint | dp_reg_num);
RegisterInfo* dp_reg_info = GetRegInfo(dp_reg);
// Double precision register's master storage should refer to itself.
@@ -465,11 +494,11 @@
// TODO: adjust when we roll to hard float calling convention.
reg_pool_->next_core_reg_ = 2;
reg_pool_->next_sp_reg_ = 2;
-#if (FR_BIT == 0)
- reg_pool_->next_dp_reg_ = 2;
-#else
- reg_pool_->next_dp_reg_ = 1;
-#endif
+ if (fpu_is_32bit) {
+ reg_pool_->next_dp_reg_ = 2;
+ } else {
+ reg_pool_->next_dp_reg_ = 1;
+ }
}
/*