diff options
-rw-r--r-- | compiler/optimizing/code_generator_mips64.cc | 277 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_mips64.h | 4 | ||||
-rw-r--r-- | compiler/utils/mips64/assembler_mips64.cc | 68 | ||||
-rw-r--r-- | compiler/utils/mips64/assembler_mips64.h | 112 |
4 files changed, 316 insertions, 145 deletions
diff --git a/compiler/optimizing/code_generator_mips64.cc b/compiler/optimizing/code_generator_mips64.cc index d4fcaf9321..5f014397d9 100644 --- a/compiler/optimizing/code_generator_mips64.cc +++ b/compiler/optimizing/code_generator_mips64.cc @@ -16,13 +16,13 @@ #include "code_generator_mips64.h" +#include "art_method.h" +#include "code_generator_utils.h" #include "entrypoints/quick/quick_entrypoints.h" #include "entrypoints/quick/quick_entrypoints_enum.h" #include "gc/accounting/card_table.h" #include "intrinsics.h" #include "intrinsics_mips64.h" -#include "art_method.h" -#include "code_generator_utils.h" #include "mirror/array-inl.h" #include "mirror/class-inl.h" #include "offsets.h" @@ -1902,6 +1902,252 @@ void InstructionCodeGeneratorMIPS64::VisitCondition(HCondition* instruction) { } } +void InstructionCodeGeneratorMIPS64::DivRemOneOrMinusOne(HBinaryOperation* instruction) { + DCHECK(instruction->IsDiv() || instruction->IsRem()); + Primitive::Type type = instruction->GetResultType(); + + LocationSummary* locations = instruction->GetLocations(); + Location second = locations->InAt(1); + DCHECK(second.IsConstant()); + + GpuRegister out = locations->Out().AsRegister<GpuRegister>(); + GpuRegister dividend = locations->InAt(0).AsRegister<GpuRegister>(); + int64_t imm = Int64FromConstant(second.GetConstant()); + DCHECK(imm == 1 || imm == -1); + + if (instruction->IsRem()) { + __ Move(out, ZERO); + } else { + if (imm == -1) { + if (type == Primitive::kPrimInt) { + __ Subu(out, ZERO, dividend); + } else { + DCHECK_EQ(type, Primitive::kPrimLong); + __ Dsubu(out, ZERO, dividend); + } + } else if (out != dividend) { + __ Move(out, dividend); + } + } +} + +void InstructionCodeGeneratorMIPS64::DivRemByPowerOfTwo(HBinaryOperation* instruction) { + DCHECK(instruction->IsDiv() || instruction->IsRem()); + Primitive::Type type = instruction->GetResultType(); + + LocationSummary* locations = instruction->GetLocations(); + Location second = locations->InAt(1); + DCHECK(second.IsConstant()); + + GpuRegister out = locations->Out().AsRegister<GpuRegister>(); + GpuRegister dividend = locations->InAt(0).AsRegister<GpuRegister>(); + int64_t imm = Int64FromConstant(second.GetConstant()); + uint64_t abs_imm = static_cast<uint64_t>(std::abs(imm)); + DCHECK(IsPowerOfTwo(abs_imm)); + int ctz_imm = CTZ(abs_imm); + + if (instruction->IsDiv()) { + if (type == Primitive::kPrimInt) { + if (ctz_imm == 1) { + // Fast path for division by +/-2, which is very common. + __ Srl(TMP, dividend, 31); + } else { + __ Sra(TMP, dividend, 31); + __ Srl(TMP, TMP, 32 - ctz_imm); + } + __ Addu(out, dividend, TMP); + __ Sra(out, out, ctz_imm); + if (imm < 0) { + __ Subu(out, ZERO, out); + } + } else { + DCHECK_EQ(type, Primitive::kPrimLong); + if (ctz_imm == 1) { + // Fast path for division by +/-2, which is very common. + __ Dsrl32(TMP, dividend, 31); + } else { + __ Dsra32(TMP, dividend, 31); + if (ctz_imm > 32) { + __ Dsrl(TMP, TMP, 64 - ctz_imm); + } else { + __ Dsrl32(TMP, TMP, 32 - ctz_imm); + } + } + __ Daddu(out, dividend, TMP); + if (ctz_imm < 32) { + __ Dsra(out, out, ctz_imm); + } else { + __ Dsra32(out, out, ctz_imm - 32); + } + if (imm < 0) { + __ Dsubu(out, ZERO, out); + } + } + } else { + if (type == Primitive::kPrimInt) { + if (ctz_imm == 1) { + // Fast path for modulo +/-2, which is very common. + __ Sra(TMP, dividend, 31); + __ Subu(out, dividend, TMP); + __ Andi(out, out, 1); + __ Addu(out, out, TMP); + } else { + __ Sra(TMP, dividend, 31); + __ Srl(TMP, TMP, 32 - ctz_imm); + __ Addu(out, dividend, TMP); + if (IsUint<16>(abs_imm - 1)) { + __ Andi(out, out, abs_imm - 1); + } else { + __ Sll(out, out, 32 - ctz_imm); + __ Srl(out, out, 32 - ctz_imm); + } + __ Subu(out, out, TMP); + } + } else { + DCHECK_EQ(type, Primitive::kPrimLong); + if (ctz_imm == 1) { + // Fast path for modulo +/-2, which is very common. + __ Dsra32(TMP, dividend, 31); + __ Dsubu(out, dividend, TMP); + __ Andi(out, out, 1); + __ Daddu(out, out, TMP); + } else { + __ Dsra32(TMP, dividend, 31); + if (ctz_imm > 32) { + __ Dsrl(TMP, TMP, 64 - ctz_imm); + } else { + __ Dsrl32(TMP, TMP, 32 - ctz_imm); + } + __ Daddu(out, dividend, TMP); + if (IsUint<16>(abs_imm - 1)) { + __ Andi(out, out, abs_imm - 1); + } else { + if (ctz_imm > 32) { + __ Dsll(out, out, 64 - ctz_imm); + __ Dsrl(out, out, 64 - ctz_imm); + } else { + __ Dsll32(out, out, 32 - ctz_imm); + __ Dsrl32(out, out, 32 - ctz_imm); + } + } + __ Dsubu(out, out, TMP); + } + } + } +} + +void InstructionCodeGeneratorMIPS64::GenerateDivRemWithAnyConstant(HBinaryOperation* instruction) { + DCHECK(instruction->IsDiv() || instruction->IsRem()); + + LocationSummary* locations = instruction->GetLocations(); + Location second = locations->InAt(1); + DCHECK(second.IsConstant()); + + GpuRegister out = locations->Out().AsRegister<GpuRegister>(); + GpuRegister dividend = locations->InAt(0).AsRegister<GpuRegister>(); + int64_t imm = Int64FromConstant(second.GetConstant()); + + Primitive::Type type = instruction->GetResultType(); + DCHECK(type == Primitive::kPrimInt || type == Primitive::kPrimLong) << type; + + int64_t magic; + int shift; + CalculateMagicAndShiftForDivRem(imm, + (type == Primitive::kPrimLong), + &magic, + &shift); + + if (type == Primitive::kPrimInt) { + __ LoadConst32(TMP, magic); + __ MuhR6(TMP, dividend, TMP); + + if (imm > 0 && magic < 0) { + __ Addu(TMP, TMP, dividend); + } else if (imm < 0 && magic > 0) { + __ Subu(TMP, TMP, dividend); + } + + if (shift != 0) { + __ Sra(TMP, TMP, shift); + } + + if (instruction->IsDiv()) { + __ Sra(out, TMP, 31); + __ Subu(out, TMP, out); + } else { + __ Sra(AT, TMP, 31); + __ Subu(AT, TMP, AT); + __ LoadConst32(TMP, imm); + __ MulR6(TMP, AT, TMP); + __ Subu(out, dividend, TMP); + } + } else { + __ LoadConst64(TMP, magic); + __ Dmuh(TMP, dividend, TMP); + + if (imm > 0 && magic < 0) { + __ Daddu(TMP, TMP, dividend); + } else if (imm < 0 && magic > 0) { + __ Dsubu(TMP, TMP, dividend); + } + + if (shift >= 32) { + __ Dsra32(TMP, TMP, shift - 32); + } else if (shift > 0) { + __ Dsra(TMP, TMP, shift); + } + + if (instruction->IsDiv()) { + __ Dsra32(out, TMP, 31); + __ Dsubu(out, TMP, out); + } else { + __ Dsra32(AT, TMP, 31); + __ Dsubu(AT, TMP, AT); + __ LoadConst64(TMP, imm); + __ Dmul(TMP, AT, TMP); + __ Dsubu(out, dividend, TMP); + } + } +} + +void InstructionCodeGeneratorMIPS64::GenerateDivRemIntegral(HBinaryOperation* instruction) { + DCHECK(instruction->IsDiv() || instruction->IsRem()); + Primitive::Type type = instruction->GetResultType(); + DCHECK(type == Primitive::kPrimInt || type == Primitive::kPrimLong) << type; + + LocationSummary* locations = instruction->GetLocations(); + GpuRegister out = locations->Out().AsRegister<GpuRegister>(); + Location second = locations->InAt(1); + + if (second.IsConstant()) { + int64_t imm = Int64FromConstant(second.GetConstant()); + if (imm == 0) { + // Do not generate anything. DivZeroCheck would prevent any code to be executed. + } else if (imm == 1 || imm == -1) { + DivRemOneOrMinusOne(instruction); + } else if (IsPowerOfTwo(std::abs(imm))) { + DivRemByPowerOfTwo(instruction); + } else { + DCHECK(imm <= -2 || imm >= 2); + GenerateDivRemWithAnyConstant(instruction); + } + } else { + GpuRegister dividend = locations->InAt(0).AsRegister<GpuRegister>(); + GpuRegister divisor = second.AsRegister<GpuRegister>(); + if (instruction->IsDiv()) { + if (type == Primitive::kPrimInt) + __ DivR6(out, dividend, divisor); + else + __ Ddiv(out, dividend, divisor); + } else { + if (type == Primitive::kPrimInt) + __ ModR6(out, dividend, divisor); + else + __ Dmod(out, dividend, divisor); + } + } +} + void LocationsBuilderMIPS64::VisitDiv(HDiv* div) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(div, LocationSummary::kNoCall); @@ -1909,7 +2155,7 @@ void LocationsBuilderMIPS64::VisitDiv(HDiv* div) { case Primitive::kPrimInt: case Primitive::kPrimLong: locations->SetInAt(0, Location::RequiresRegister()); - locations->SetInAt(1, Location::RequiresRegister()); + locations->SetInAt(1, Location::RegisterOrConstant(div->InputAt(1))); locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); break; @@ -1931,16 +2177,9 @@ void InstructionCodeGeneratorMIPS64::VisitDiv(HDiv* instruction) { switch (type) { case Primitive::kPrimInt: - case Primitive::kPrimLong: { - GpuRegister dst = locations->Out().AsRegister<GpuRegister>(); - GpuRegister lhs = locations->InAt(0).AsRegister<GpuRegister>(); - GpuRegister rhs = locations->InAt(1).AsRegister<GpuRegister>(); - if (type == Primitive::kPrimInt) - __ DivR6(dst, lhs, rhs); - else - __ Ddiv(dst, lhs, rhs); + case Primitive::kPrimLong: + GenerateDivRemIntegral(instruction); break; - } case Primitive::kPrimFloat: case Primitive::kPrimDouble: { FpuRegister dst = locations->Out().AsFpuRegister<FpuRegister>(); @@ -3112,7 +3351,7 @@ void LocationsBuilderMIPS64::VisitRem(HRem* rem) { case Primitive::kPrimInt: case Primitive::kPrimLong: locations->SetInAt(0, Location::RequiresRegister()); - locations->SetInAt(1, Location::RequiresRegister()); + locations->SetInAt(1, Location::RegisterOrConstant(rem->InputAt(1))); locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); break; @@ -3132,20 +3371,12 @@ void LocationsBuilderMIPS64::VisitRem(HRem* rem) { void InstructionCodeGeneratorMIPS64::VisitRem(HRem* instruction) { Primitive::Type type = instruction->GetType(); - LocationSummary* locations = instruction->GetLocations(); switch (type) { case Primitive::kPrimInt: - case Primitive::kPrimLong: { - GpuRegister dst = locations->Out().AsRegister<GpuRegister>(); - GpuRegister lhs = locations->InAt(0).AsRegister<GpuRegister>(); - GpuRegister rhs = locations->InAt(1).AsRegister<GpuRegister>(); - if (type == Primitive::kPrimInt) - __ ModR6(dst, lhs, rhs); - else - __ Dmod(dst, lhs, rhs); + case Primitive::kPrimLong: + GenerateDivRemIntegral(instruction); break; - } case Primitive::kPrimFloat: case Primitive::kPrimDouble: { diff --git a/compiler/optimizing/code_generator_mips64.h b/compiler/optimizing/code_generator_mips64.h index 4f91c7179f..58c6e0fa83 100644 --- a/compiler/optimizing/code_generator_mips64.h +++ b/compiler/optimizing/code_generator_mips64.h @@ -230,6 +230,10 @@ class InstructionCodeGeneratorMIPS64 : public HGraphVisitor { Label* true_target, Label* false_target, Label* always_true_target); + void DivRemOneOrMinusOne(HBinaryOperation* instruction); + void DivRemByPowerOfTwo(HBinaryOperation* instruction); + void GenerateDivRemWithAnyConstant(HBinaryOperation* instruction); + void GenerateDivRemIntegral(HBinaryOperation* instruction); void HandleGoto(HInstruction* got, HBasicBlock* successor); Mips64Assembler* const assembler_; diff --git a/compiler/utils/mips64/assembler_mips64.cc b/compiler/utils/mips64/assembler_mips64.cc index 00e8995bff..8e9b509e30 100644 --- a/compiler/utils/mips64/assembler_mips64.cc +++ b/compiler/utils/mips64/assembler_mips64.cc @@ -117,14 +117,6 @@ void Mips64Assembler::EmitFI(int opcode, int fmt, FpuRegister ft, uint16_t imm) Emit(encoding); } -void Mips64Assembler::Add(GpuRegister rd, GpuRegister rs, GpuRegister rt) { - EmitR(0, rs, rt, rd, 0, 0x20); -} - -void Mips64Assembler::Addi(GpuRegister rt, GpuRegister rs, uint16_t imm16) { - EmitI(0x8, rs, rt, imm16); -} - void Mips64Assembler::Addu(GpuRegister rd, GpuRegister rs, GpuRegister rt) { EmitR(0, rs, rt, rd, 0, 0x21); } @@ -141,10 +133,6 @@ void Mips64Assembler::Daddiu(GpuRegister rt, GpuRegister rs, uint16_t imm16) { EmitI(0x19, rs, rt, imm16); } -void Mips64Assembler::Sub(GpuRegister rd, GpuRegister rs, GpuRegister rt) { - EmitR(0, rs, rt, rd, 0, 0x22); -} - void Mips64Assembler::Subu(GpuRegister rd, GpuRegister rs, GpuRegister rt) { EmitR(0, rs, rt, rd, 0, 0x23); } @@ -153,50 +141,14 @@ void Mips64Assembler::Dsubu(GpuRegister rd, GpuRegister rs, GpuRegister rt) { EmitR(0, rs, rt, rd, 0, 0x2f); } -void Mips64Assembler::MultR2(GpuRegister rs, GpuRegister rt) { - EmitR(0, rs, rt, static_cast<GpuRegister>(0), 0, 0x18); -} - -void Mips64Assembler::MultuR2(GpuRegister rs, GpuRegister rt) { - EmitR(0, rs, rt, static_cast<GpuRegister>(0), 0, 0x19); -} - -void Mips64Assembler::DivR2(GpuRegister rs, GpuRegister rt) { - EmitR(0, rs, rt, static_cast<GpuRegister>(0), 0, 0x1a); -} - -void Mips64Assembler::DivuR2(GpuRegister rs, GpuRegister rt) { - EmitR(0, rs, rt, static_cast<GpuRegister>(0), 0, 0x1b); -} - -void Mips64Assembler::MulR2(GpuRegister rd, GpuRegister rs, GpuRegister rt) { - EmitR(0x1c, rs, rt, rd, 0, 2); -} - -void Mips64Assembler::DivR2(GpuRegister rd, GpuRegister rs, GpuRegister rt) { - DivR2(rs, rt); - Mflo(rd); -} - -void Mips64Assembler::ModR2(GpuRegister rd, GpuRegister rs, GpuRegister rt) { - DivR2(rs, rt); - Mfhi(rd); -} - -void Mips64Assembler::DivuR2(GpuRegister rd, GpuRegister rs, GpuRegister rt) { - DivuR2(rs, rt); - Mflo(rd); -} - -void Mips64Assembler::ModuR2(GpuRegister rd, GpuRegister rs, GpuRegister rt) { - DivuR2(rs, rt); - Mfhi(rd); -} - void Mips64Assembler::MulR6(GpuRegister rd, GpuRegister rs, GpuRegister rt) { EmitR(0, rs, rt, rd, 2, 0x18); } +void Mips64Assembler::MuhR6(GpuRegister rd, GpuRegister rs, GpuRegister rt) { + EmitR(0, rs, rt, rd, 3, 0x18); +} + void Mips64Assembler::DivR6(GpuRegister rd, GpuRegister rs, GpuRegister rt) { EmitR(0, rs, rt, rd, 2, 0x1a); } @@ -217,6 +169,10 @@ void Mips64Assembler::Dmul(GpuRegister rd, GpuRegister rs, GpuRegister rt) { EmitR(0, rs, rt, rd, 2, 0x1c); } +void Mips64Assembler::Dmuh(GpuRegister rd, GpuRegister rs, GpuRegister rt) { + EmitR(0, rs, rt, rd, 3, 0x1c); +} + void Mips64Assembler::Ddiv(GpuRegister rd, GpuRegister rs, GpuRegister rt) { EmitR(0, rs, rt, rd, 2, 0x1e); } @@ -440,14 +396,6 @@ void Mips64Assembler::Sync(uint32_t stype) { static_cast<GpuRegister>(0), stype & 0x1f, 0xf); } -void Mips64Assembler::Mfhi(GpuRegister rd) { - EmitR(0, static_cast<GpuRegister>(0), static_cast<GpuRegister>(0), rd, 0, 0x10); -} - -void Mips64Assembler::Mflo(GpuRegister rd) { - EmitR(0, static_cast<GpuRegister>(0), static_cast<GpuRegister>(0), rd, 0, 0x12); -} - void Mips64Assembler::Sb(GpuRegister rt, GpuRegister rs, uint16_t imm16) { EmitI(0x28, rs, rt, imm16); } diff --git a/compiler/utils/mips64/assembler_mips64.h b/compiler/utils/mips64/assembler_mips64.h index 33f22d2c2d..42962bca20 100644 --- a/compiler/utils/mips64/assembler_mips64.h +++ b/compiler/utils/mips64/assembler_mips64.h @@ -66,35 +66,25 @@ class Mips64Assembler FINAL : public Assembler { virtual ~Mips64Assembler() {} // Emit Machine Instructions. - void Add(GpuRegister rd, GpuRegister rs, GpuRegister rt); - void Addi(GpuRegister rt, GpuRegister rs, uint16_t imm16); void Addu(GpuRegister rd, GpuRegister rs, GpuRegister rt); void Addiu(GpuRegister rt, GpuRegister rs, uint16_t imm16); void Daddu(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64 void Daddiu(GpuRegister rt, GpuRegister rs, uint16_t imm16); // MIPS64 - void Sub(GpuRegister rd, GpuRegister rs, GpuRegister rt); void Subu(GpuRegister rd, GpuRegister rs, GpuRegister rt); void Dsubu(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64 - void MultR2(GpuRegister rs, GpuRegister rt); // R2 - void MultuR2(GpuRegister rs, GpuRegister rt); // R2 - void DivR2(GpuRegister rs, GpuRegister rt); // R2 - void DivuR2(GpuRegister rs, GpuRegister rt); // R2 - void MulR2(GpuRegister rd, GpuRegister rs, GpuRegister rt); // R2 - void DivR2(GpuRegister rd, GpuRegister rs, GpuRegister rt); // R2 - void ModR2(GpuRegister rd, GpuRegister rs, GpuRegister rt); // R2 - void DivuR2(GpuRegister rd, GpuRegister rs, GpuRegister rt); // R2 - void ModuR2(GpuRegister rd, GpuRegister rs, GpuRegister rt); // R2 - void MulR6(GpuRegister rd, GpuRegister rs, GpuRegister rt); // R6 - void DivR6(GpuRegister rd, GpuRegister rs, GpuRegister rt); // R6 - void ModR6(GpuRegister rd, GpuRegister rs, GpuRegister rt); // R6 - void DivuR6(GpuRegister rd, GpuRegister rs, GpuRegister rt); // R6 - void ModuR6(GpuRegister rd, GpuRegister rs, GpuRegister rt); // R6 - void Dmul(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64 R6 - void Ddiv(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64 R6 - void Dmod(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64 R6 - void Ddivu(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64 R6 - void Dmodu(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64 R6 + void MulR6(GpuRegister rd, GpuRegister rs, GpuRegister rt); + void MuhR6(GpuRegister rd, GpuRegister rs, GpuRegister rt); + void DivR6(GpuRegister rd, GpuRegister rs, GpuRegister rt); + void ModR6(GpuRegister rd, GpuRegister rs, GpuRegister rt); + void DivuR6(GpuRegister rd, GpuRegister rs, GpuRegister rt); + void ModuR6(GpuRegister rd, GpuRegister rs, GpuRegister rt); + void Dmul(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64 + void Dmuh(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64 + void Ddiv(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64 + void Dmod(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64 + void Ddivu(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64 + void Dmodu(GpuRegister rd, GpuRegister rs, GpuRegister rt); // MIPS64 void And(GpuRegister rd, GpuRegister rs, GpuRegister rt); void Andi(GpuRegister rt, GpuRegister rs, uint16_t imm16); @@ -104,12 +94,12 @@ class Mips64Assembler FINAL : public Assembler { void Xori(GpuRegister rt, GpuRegister rs, uint16_t imm16); void Nor(GpuRegister rd, GpuRegister rs, GpuRegister rt); - void Bitswap(GpuRegister rd, GpuRegister rt); // R6 - void Dbitswap(GpuRegister rd, GpuRegister rt); // R6 - void Seb(GpuRegister rd, GpuRegister rt); // R2+ - void Seh(GpuRegister rd, GpuRegister rt); // R2+ - void Dsbh(GpuRegister rd, GpuRegister rt); // R2+ - void Dshd(GpuRegister rd, GpuRegister rt); // R2+ + void Bitswap(GpuRegister rd, GpuRegister rt); + void Dbitswap(GpuRegister rd, GpuRegister rt); + void Seb(GpuRegister rd, GpuRegister rt); + void Seh(GpuRegister rd, GpuRegister rt); + void Dsbh(GpuRegister rd, GpuRegister rt); + void Dshd(GpuRegister rd, GpuRegister rt); void Dext(GpuRegister rs, GpuRegister rt, int pos, int size_less_one); // MIPS64 void Wsbh(GpuRegister rd, GpuRegister rt); void Sc(GpuRegister rt, GpuRegister base, int16_t imm9 = 0); @@ -146,11 +136,9 @@ class Mips64Assembler FINAL : public Assembler { void Lhu(GpuRegister rt, GpuRegister rs, uint16_t imm16); void Lwu(GpuRegister rt, GpuRegister rs, uint16_t imm16); // MIPS64 void Lui(GpuRegister rt, uint16_t imm16); - void Dahi(GpuRegister rs, uint16_t imm16); // MIPS64 R6 - void Dati(GpuRegister rs, uint16_t imm16); // MIPS64 R6 + void Dahi(GpuRegister rs, uint16_t imm16); // MIPS64 + void Dati(GpuRegister rs, uint16_t imm16); // MIPS64 void Sync(uint32_t stype); - void Mfhi(GpuRegister rd); // R2 - void Mflo(GpuRegister rd); // R2 void Sb(GpuRegister rt, GpuRegister rs, uint16_t imm16); void Sh(GpuRegister rt, GpuRegister rs, uint16_t imm16); @@ -175,21 +163,21 @@ class Mips64Assembler FINAL : public Assembler { void Jalr(GpuRegister rd, GpuRegister rs); void Jalr(GpuRegister rs); void Jr(GpuRegister rs); - void Auipc(GpuRegister rs, uint16_t imm16); // R6 - void Jic(GpuRegister rt, uint16_t imm16); // R6 - void Jialc(GpuRegister rt, uint16_t imm16); // R6 - void Bltc(GpuRegister rs, GpuRegister rt, uint16_t imm16); // R6 - void Bltzc(GpuRegister rt, uint16_t imm16); // R6 - void Bgtzc(GpuRegister rt, uint16_t imm16); // R6 - void Bgec(GpuRegister rs, GpuRegister rt, uint16_t imm16); // R6 - void Bgezc(GpuRegister rt, uint16_t imm16); // R6 - void Blezc(GpuRegister rt, uint16_t imm16); // R6 - void Bltuc(GpuRegister rs, GpuRegister rt, uint16_t imm16); // R6 - void Bgeuc(GpuRegister rs, GpuRegister rt, uint16_t imm16); // R6 - void Beqc(GpuRegister rs, GpuRegister rt, uint16_t imm16); // R6 - void Bnec(GpuRegister rs, GpuRegister rt, uint16_t imm16); // R6 - void Beqzc(GpuRegister rs, uint32_t imm21); // R6 - void Bnezc(GpuRegister rs, uint32_t imm21); // R6 + void Auipc(GpuRegister rs, uint16_t imm16); + void Jic(GpuRegister rt, uint16_t imm16); + void Jialc(GpuRegister rt, uint16_t imm16); + void Bltc(GpuRegister rs, GpuRegister rt, uint16_t imm16); + void Bltzc(GpuRegister rt, uint16_t imm16); + void Bgtzc(GpuRegister rt, uint16_t imm16); + void Bgec(GpuRegister rs, GpuRegister rt, uint16_t imm16); + void Bgezc(GpuRegister rt, uint16_t imm16); + void Blezc(GpuRegister rt, uint16_t imm16); + void Bltuc(GpuRegister rs, GpuRegister rt, uint16_t imm16); + void Bgeuc(GpuRegister rs, GpuRegister rt, uint16_t imm16); + void Beqc(GpuRegister rs, GpuRegister rt, uint16_t imm16); + void Bnec(GpuRegister rs, GpuRegister rt, uint16_t imm16); + void Beqzc(GpuRegister rs, uint32_t imm21); + void Bnezc(GpuRegister rs, uint32_t imm21); void AddS(FpuRegister fd, FpuRegister fs, FpuRegister ft); void SubS(FpuRegister fd, FpuRegister fs, FpuRegister ft); @@ -259,25 +247,25 @@ class Mips64Assembler FINAL : public Assembler { void Addiu32(GpuRegister rt, GpuRegister rs, int32_t value, GpuRegister rtmp = AT); void Daddiu64(GpuRegister rt, GpuRegister rs, int64_t value, GpuRegister rtmp = AT); // MIPS64 - void Bind(Label* label) OVERRIDE; // R6 + void Bind(Label* label) OVERRIDE; void Jump(Label* label) OVERRIDE { B(label); } - void B(Label* label); // R6 - void Jalr(Label* label, GpuRegister indirect_reg = RA); // R6 + void B(Label* label); + void Jalr(Label* label, GpuRegister indirect_reg = RA); // TODO: implement common for R6 and non-R6 interface for conditional branches? - void Bltc(GpuRegister rs, GpuRegister rt, Label* label); // R6 - void Bltzc(GpuRegister rt, Label* label); // R6 - void Bgtzc(GpuRegister rt, Label* label); // R6 - void Bgec(GpuRegister rs, GpuRegister rt, Label* label); // R6 - void Bgezc(GpuRegister rt, Label* label); // R6 - void Blezc(GpuRegister rt, Label* label); // R6 - void Bltuc(GpuRegister rs, GpuRegister rt, Label* label); // R6 - void Bgeuc(GpuRegister rs, GpuRegister rt, Label* label); // R6 - void Beqc(GpuRegister rs, GpuRegister rt, Label* label); // R6 - void Bnec(GpuRegister rs, GpuRegister rt, Label* label); // R6 - void Beqzc(GpuRegister rs, Label* label); // R6 - void Bnezc(GpuRegister rs, Label* label); // R6 + void Bltc(GpuRegister rs, GpuRegister rt, Label* label); + void Bltzc(GpuRegister rt, Label* label); + void Bgtzc(GpuRegister rt, Label* label); + void Bgec(GpuRegister rs, GpuRegister rt, Label* label); + void Bgezc(GpuRegister rt, Label* label); + void Blezc(GpuRegister rt, Label* label); + void Bltuc(GpuRegister rs, GpuRegister rt, Label* label); + void Bgeuc(GpuRegister rs, GpuRegister rt, Label* label); + void Beqc(GpuRegister rs, GpuRegister rt, Label* label); + void Bnec(GpuRegister rs, GpuRegister rt, Label* label); + void Beqzc(GpuRegister rs, Label* label); + void Bnezc(GpuRegister rs, Label* label); void EmitLoad(ManagedRegister m_dst, GpuRegister src_register, int32_t src_offset, size_t size); void LoadFromOffset(LoadOperandType type, GpuRegister reg, GpuRegister base, int32_t offset); |