diff options
Diffstat (limited to 'compiler/utils')
| -rw-r--r-- | compiler/utils/mips64/assembler_mips64.cc | 124 | ||||
| -rw-r--r-- | compiler/utils/mips64/assembler_mips64.h | 22 | ||||
| -rw-r--r-- | compiler/utils/mips64/assembler_mips64_test.cc | 696 |
3 files changed, 799 insertions, 43 deletions
diff --git a/compiler/utils/mips64/assembler_mips64.cc b/compiler/utils/mips64/assembler_mips64.cc index f9ff2df8bb..ab480cafd5 100644 --- a/compiler/utils/mips64/assembler_mips64.cc +++ b/compiler/utils/mips64/assembler_mips64.cc @@ -300,10 +300,17 @@ void Mips64Assembler::Dshd(GpuRegister rd, GpuRegister rt) { EmitRtd(0x1f, rt, rd, 0x5, 0x24); } -void Mips64Assembler::Dext(GpuRegister rt, GpuRegister rs, int pos, int size_less_one) { - DCHECK(0 <= pos && pos < 32) << pos; - DCHECK(0 <= size_less_one && size_less_one < 32) << size_less_one; - EmitR(0x1f, rs, rt, static_cast<GpuRegister>(size_less_one), pos, 3); +void Mips64Assembler::Dext(GpuRegister rt, GpuRegister rs, int pos, int size) { + CHECK(IsUint<5>(pos)) << pos; + CHECK(IsUint<5>(size - 1)) << size; + EmitR(0x1f, rs, rt, static_cast<GpuRegister>(size - 1), pos, 0x3); +} + +void Mips64Assembler::Dinsu(GpuRegister rt, GpuRegister rs, int pos, int size) { + CHECK(IsUint<5>(pos - 32)) << pos; + CHECK(IsUint<5>(size - 1)) << size; + CHECK(IsUint<5>(pos + size - 33)) << pos << " + " << size; + EmitR(0x1f, rs, rt, static_cast<GpuRegister>(pos + size - 33), pos - 32, 0x6); } void Mips64Assembler::Wsbh(GpuRegister rd, GpuRegister rt) { @@ -311,22 +318,22 @@ void Mips64Assembler::Wsbh(GpuRegister rd, GpuRegister rt) { } void Mips64Assembler::Sc(GpuRegister rt, GpuRegister base, int16_t imm9) { - DCHECK((-256 <= imm9) && (imm9 < 256)); + CHECK(IsInt<9>(imm9)); EmitI(0x1f, base, rt, ((imm9 & 0x1FF) << 7) | 0x26); } void Mips64Assembler::Scd(GpuRegister rt, GpuRegister base, int16_t imm9) { - DCHECK((-256 <= imm9) && (imm9 < 256)); + CHECK(IsInt<9>(imm9)); EmitI(0x1f, base, rt, ((imm9 & 0x1FF) << 7) | 0x27); } void Mips64Assembler::Ll(GpuRegister rt, GpuRegister base, int16_t imm9) { - DCHECK((-256 <= imm9) && (imm9 < 256)); + CHECK(IsInt<9>(imm9)); EmitI(0x1f, base, rt, ((imm9 & 0x1FF) << 7) | 0x36); } void Mips64Assembler::Lld(GpuRegister rt, GpuRegister base, int16_t imm9) { - DCHECK((-256 <= imm9) && (imm9 < 256)); + CHECK(IsInt<9>(imm9)); EmitI(0x1f, base, rt, ((imm9 & 0x1FF) << 7) | 0x37); } @@ -967,10 +974,18 @@ void Mips64Assembler::Mfc1(GpuRegister rt, FpuRegister fs) { EmitFR(0x11, 0x00, static_cast<FpuRegister>(rt), fs, static_cast<FpuRegister>(0), 0x0); } +void Mips64Assembler::Mfhc1(GpuRegister rt, FpuRegister fs) { + EmitFR(0x11, 0x03, static_cast<FpuRegister>(rt), fs, static_cast<FpuRegister>(0), 0x0); +} + void Mips64Assembler::Mtc1(GpuRegister rt, FpuRegister fs) { EmitFR(0x11, 0x04, static_cast<FpuRegister>(rt), fs, static_cast<FpuRegister>(0), 0x0); } +void Mips64Assembler::Mthc1(GpuRegister rt, FpuRegister fs) { + EmitFR(0x11, 0x07, static_cast<FpuRegister>(rt), fs, static_cast<FpuRegister>(0), 0x0); +} + void Mips64Assembler::Dmfc1(GpuRegister rt, FpuRegister fs) { EmitFR(0x11, 0x01, static_cast<FpuRegister>(rt), fs, static_cast<FpuRegister>(0), 0x0); } @@ -1787,11 +1802,13 @@ void Mips64Assembler::Bc1nez(FpuRegister ft, Mips64Label* label) { void Mips64Assembler::LoadFromOffset(LoadOperandType type, GpuRegister reg, GpuRegister base, int32_t offset) { - if (!IsInt<16>(offset)) { - LoadConst32(AT, offset); + if (!IsInt<16>(offset) || + (type == kLoadDoubleword && !IsAligned<kMips64DoublewordSize>(offset) && + !IsInt<16>(static_cast<int32_t>(offset + kMips64WordSize)))) { + LoadConst32(AT, offset & ~(kMips64DoublewordSize - 1)); Daddu(AT, AT, base); base = AT; - offset = 0; + offset &= (kMips64DoublewordSize - 1); } switch (type) { @@ -1808,32 +1825,51 @@ void Mips64Assembler::LoadFromOffset(LoadOperandType type, GpuRegister reg, GpuR Lhu(reg, base, offset); break; case kLoadWord: + CHECK_ALIGNED(offset, kMips64WordSize); Lw(reg, base, offset); break; case kLoadUnsignedWord: + CHECK_ALIGNED(offset, kMips64WordSize); Lwu(reg, base, offset); break; case kLoadDoubleword: - Ld(reg, base, offset); + if (!IsAligned<kMips64DoublewordSize>(offset)) { + CHECK_ALIGNED(offset, kMips64WordSize); + Lwu(reg, base, offset); + Lwu(TMP2, base, offset + kMips64WordSize); + Dinsu(reg, TMP2, 32, 32); + } else { + Ld(reg, base, offset); + } break; } } void Mips64Assembler::LoadFpuFromOffset(LoadOperandType type, FpuRegister reg, GpuRegister base, int32_t offset) { - if (!IsInt<16>(offset)) { - LoadConst32(AT, offset); + if (!IsInt<16>(offset) || + (type == kLoadDoubleword && !IsAligned<kMips64DoublewordSize>(offset) && + !IsInt<16>(static_cast<int32_t>(offset + kMips64WordSize)))) { + LoadConst32(AT, offset & ~(kMips64DoublewordSize - 1)); Daddu(AT, AT, base); base = AT; - offset = 0; + offset &= (kMips64DoublewordSize - 1); } switch (type) { case kLoadWord: + CHECK_ALIGNED(offset, kMips64WordSize); Lwc1(reg, base, offset); break; case kLoadDoubleword: - Ldc1(reg, base, offset); + if (!IsAligned<kMips64DoublewordSize>(offset)) { + CHECK_ALIGNED(offset, kMips64WordSize); + Lwc1(reg, base, offset); + Lw(TMP2, base, offset + kMips64WordSize); + Mthc1(TMP2, reg); + } else { + Ldc1(reg, base, offset); + } break; default: LOG(FATAL) << "UNREACHABLE"; @@ -1869,11 +1905,13 @@ void Mips64Assembler::EmitLoad(ManagedRegister m_dst, GpuRegister src_register, void Mips64Assembler::StoreToOffset(StoreOperandType type, GpuRegister reg, GpuRegister base, int32_t offset) { - if (!IsInt<16>(offset)) { - LoadConst32(AT, offset); + if (!IsInt<16>(offset) || + (type == kStoreDoubleword && !IsAligned<kMips64DoublewordSize>(offset) && + !IsInt<16>(static_cast<int32_t>(offset + kMips64WordSize)))) { + LoadConst32(AT, offset & ~(kMips64DoublewordSize - 1)); Daddu(AT, AT, base); base = AT; - offset = 0; + offset &= (kMips64DoublewordSize - 1); } switch (type) { @@ -1884,10 +1922,18 @@ void Mips64Assembler::StoreToOffset(StoreOperandType type, GpuRegister reg, GpuR Sh(reg, base, offset); break; case kStoreWord: + CHECK_ALIGNED(offset, kMips64WordSize); Sw(reg, base, offset); break; case kStoreDoubleword: - Sd(reg, base, offset); + if (!IsAligned<kMips64DoublewordSize>(offset)) { + CHECK_ALIGNED(offset, kMips64WordSize); + Sw(reg, base, offset); + Dsrl32(TMP2, reg, 0); + Sw(TMP2, base, offset + kMips64WordSize); + } else { + Sd(reg, base, offset); + } break; default: LOG(FATAL) << "UNREACHABLE"; @@ -1896,19 +1942,29 @@ void Mips64Assembler::StoreToOffset(StoreOperandType type, GpuRegister reg, GpuR void Mips64Assembler::StoreFpuToOffset(StoreOperandType type, FpuRegister reg, GpuRegister base, int32_t offset) { - if (!IsInt<16>(offset)) { - LoadConst32(AT, offset); + if (!IsInt<16>(offset) || + (type == kStoreDoubleword && !IsAligned<kMips64DoublewordSize>(offset) && + !IsInt<16>(static_cast<int32_t>(offset + kMips64WordSize)))) { + LoadConst32(AT, offset & ~(kMips64DoublewordSize - 1)); Daddu(AT, AT, base); base = AT; - offset = 0; + offset &= (kMips64DoublewordSize - 1); } switch (type) { case kStoreWord: + CHECK_ALIGNED(offset, kMips64WordSize); Swc1(reg, base, offset); break; case kStoreDoubleword: - Sdc1(reg, base, offset); + if (!IsAligned<kMips64DoublewordSize>(offset)) { + CHECK_ALIGNED(offset, kMips64WordSize); + Mfhc1(TMP2, reg); + Swc1(reg, base, offset); + Sw(TMP2, base, offset + kMips64WordSize); + } else { + Sdc1(reg, base, offset); + } break; default: LOG(FATAL) << "UNREACHABLE"; @@ -2053,7 +2109,7 @@ void Mips64Assembler::StoreImmediateToFrame(FrameOffset dest, uint32_t imm, StoreToOffset(kStoreWord, scratch.AsGpuRegister(), SP, dest.Int32Value()); } -void Mips64Assembler::StoreStackOffsetToThread64(ThreadOffset<kMipsDoublewordSize> thr_offs, +void Mips64Assembler::StoreStackOffsetToThread64(ThreadOffset<kMips64DoublewordSize> thr_offs, FrameOffset fr_offs, ManagedRegister mscratch) { Mips64ManagedRegister scratch = mscratch.AsMips64(); @@ -2062,7 +2118,7 @@ void Mips64Assembler::StoreStackOffsetToThread64(ThreadOffset<kMipsDoublewordSiz StoreToOffset(kStoreDoubleword, scratch.AsGpuRegister(), S1, thr_offs.Int32Value()); } -void Mips64Assembler::StoreStackPointerToThread64(ThreadOffset<kMipsDoublewordSize> thr_offs) { +void Mips64Assembler::StoreStackPointerToThread64(ThreadOffset<kMips64DoublewordSize> thr_offs) { StoreToOffset(kStoreDoubleword, SP, S1, thr_offs.Int32Value()); } @@ -2080,7 +2136,7 @@ void Mips64Assembler::Load(ManagedRegister mdest, FrameOffset src, size_t size) } void Mips64Assembler::LoadFromThread64(ManagedRegister mdest, - ThreadOffset<kMipsDoublewordSize> src, + ThreadOffset<kMips64DoublewordSize> src, size_t size) { return EmitLoad(mdest, S1, src.Int32Value(), size); } @@ -2102,7 +2158,7 @@ void Mips64Assembler::LoadRef(ManagedRegister mdest, ManagedRegister base, Membe // Negate the 32-bit ref Dsubu(dest.AsGpuRegister(), ZERO, dest.AsGpuRegister()); // And constrain it to 32 bits (zero-extend into bits 32 through 63) as on Arm64 and x86/64 - Dext(dest.AsGpuRegister(), dest.AsGpuRegister(), 0, 31); + Dext(dest.AsGpuRegister(), dest.AsGpuRegister(), 0, 32); } } @@ -2115,7 +2171,7 @@ void Mips64Assembler::LoadRawPtr(ManagedRegister mdest, ManagedRegister base, } void Mips64Assembler::LoadRawPtrFromThread64(ManagedRegister mdest, - ThreadOffset<kMipsDoublewordSize> offs) { + ThreadOffset<kMips64DoublewordSize> offs) { Mips64ManagedRegister dest = mdest.AsMips64(); CHECK(dest.IsGpuRegister()); LoadFromOffset(kLoadDoubleword, dest.AsGpuRegister(), S1, offs.Int32Value()); @@ -2160,7 +2216,7 @@ void Mips64Assembler::CopyRef(FrameOffset dest, FrameOffset src, } void Mips64Assembler::CopyRawPtrFromThread64(FrameOffset fr_offs, - ThreadOffset<kMipsDoublewordSize> thr_offs, + ThreadOffset<kMips64DoublewordSize> thr_offs, ManagedRegister mscratch) { Mips64ManagedRegister scratch = mscratch.AsMips64(); CHECK(scratch.IsGpuRegister()) << scratch; @@ -2168,7 +2224,7 @@ void Mips64Assembler::CopyRawPtrFromThread64(FrameOffset fr_offs, StoreToOffset(kStoreDoubleword, scratch.AsGpuRegister(), SP, fr_offs.Int32Value()); } -void Mips64Assembler::CopyRawPtrToThread64(ThreadOffset<kMipsDoublewordSize> thr_offs, +void Mips64Assembler::CopyRawPtrToThread64(ThreadOffset<kMips64DoublewordSize> thr_offs, FrameOffset fr_offs, ManagedRegister mscratch) { Mips64ManagedRegister scratch = mscratch.AsMips64(); @@ -2372,7 +2428,7 @@ void Mips64Assembler::Call(FrameOffset base, Offset offset, ManagedRegister mscr // TODO: place reference map on call } -void Mips64Assembler::CallFromThread64(ThreadOffset<kMipsDoublewordSize> offset ATTRIBUTE_UNUSED, +void Mips64Assembler::CallFromThread64(ThreadOffset<kMips64DoublewordSize> offset ATTRIBUTE_UNUSED, ManagedRegister mscratch ATTRIBUTE_UNUSED) { UNIMPLEMENTED(FATAL) << "No MIPS64 implementation"; } @@ -2392,7 +2448,7 @@ void Mips64Assembler::ExceptionPoll(ManagedRegister mscratch, size_t stack_adjus LoadFromOffset(kLoadDoubleword, scratch.AsGpuRegister(), S1, - Thread::ExceptionOffset<kMipsDoublewordSize>().Int32Value()); + Thread::ExceptionOffset<kMips64DoublewordSize>().Int32Value()); Bnezc(scratch.AsGpuRegister(), exception_blocks_.back().Entry()); } @@ -2409,7 +2465,7 @@ void Mips64Assembler::EmitExceptionPoll(Mips64ExceptionSlowPath* exception) { LoadFromOffset(kLoadDoubleword, T9, S1, - QUICK_ENTRYPOINT_OFFSET(kMipsDoublewordSize, pDeliverException).Int32Value()); + QUICK_ENTRYPOINT_OFFSET(kMips64DoublewordSize, pDeliverException).Int32Value()); Jr(T9); Nop(); diff --git a/compiler/utils/mips64/assembler_mips64.h b/compiler/utils/mips64/assembler_mips64.h index 3262640ce7..71f5e00166 100644 --- a/compiler/utils/mips64/assembler_mips64.h +++ b/compiler/utils/mips64/assembler_mips64.h @@ -31,7 +31,8 @@ namespace art { namespace mips64 { -static constexpr size_t kMipsDoublewordSize = 8; +static constexpr size_t kMips64WordSize = 4; +static constexpr size_t kMips64DoublewordSize = 8; enum LoadOperandType { kLoadSignedByte, @@ -151,7 +152,8 @@ class Mips64Assembler FINAL : public Assembler { 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 Dext(GpuRegister rs, GpuRegister rt, int pos, int size); // MIPS64 + void Dinsu(GpuRegister rt, GpuRegister rs, int pos, int size); // MIPS64 void Wsbh(GpuRegister rd, GpuRegister rt); void Sc(GpuRegister rt, GpuRegister base, int16_t imm9 = 0); void Scd(GpuRegister rt, GpuRegister base, int16_t imm9 = 0); @@ -301,7 +303,9 @@ class Mips64Assembler FINAL : public Assembler { void Cvtdl(FpuRegister fd, FpuRegister fs); void Mfc1(GpuRegister rt, FpuRegister fs); + void Mfhc1(GpuRegister rt, FpuRegister fs); void Mtc1(GpuRegister rt, FpuRegister fs); + void Mthc1(GpuRegister rt, FpuRegister fs); void Dmfc1(GpuRegister rt, FpuRegister fs); // MIPS64 void Dmtc1(GpuRegister rt, FpuRegister fs); // MIPS64 void Lwc1(FpuRegister ft, GpuRegister rs, uint16_t imm16); @@ -378,10 +382,10 @@ class Mips64Assembler FINAL : public Assembler { void StoreImmediateToFrame(FrameOffset dest, uint32_t imm, ManagedRegister mscratch) OVERRIDE; - void StoreStackOffsetToThread64(ThreadOffset<kMipsDoublewordSize> thr_offs, FrameOffset fr_offs, + void StoreStackOffsetToThread64(ThreadOffset<kMips64DoublewordSize> thr_offs, FrameOffset fr_offs, ManagedRegister mscratch) OVERRIDE; - void StoreStackPointerToThread64(ThreadOffset<kMipsDoublewordSize> thr_offs) OVERRIDE; + void StoreStackPointerToThread64(ThreadOffset<kMips64DoublewordSize> thr_offs) OVERRIDE; void StoreSpanning(FrameOffset dest, ManagedRegister msrc, FrameOffset in_off, ManagedRegister mscratch) OVERRIDE; @@ -390,7 +394,7 @@ class Mips64Assembler FINAL : public Assembler { void Load(ManagedRegister mdest, FrameOffset src, size_t size) OVERRIDE; void LoadFromThread64(ManagedRegister mdest, - ThreadOffset<kMipsDoublewordSize> src, + ThreadOffset<kMips64DoublewordSize> src, size_t size) OVERRIDE; void LoadRef(ManagedRegister dest, FrameOffset src) OVERRIDE; @@ -401,15 +405,15 @@ class Mips64Assembler FINAL : public Assembler { void LoadRawPtr(ManagedRegister mdest, ManagedRegister base, Offset offs) OVERRIDE; void LoadRawPtrFromThread64(ManagedRegister mdest, - ThreadOffset<kMipsDoublewordSize> offs) OVERRIDE; + ThreadOffset<kMips64DoublewordSize> offs) OVERRIDE; // Copying routines. void Move(ManagedRegister mdest, ManagedRegister msrc, size_t size) OVERRIDE; - void CopyRawPtrFromThread64(FrameOffset fr_offs, ThreadOffset<kMipsDoublewordSize> thr_offs, + void CopyRawPtrFromThread64(FrameOffset fr_offs, ThreadOffset<kMips64DoublewordSize> thr_offs, ManagedRegister mscratch) OVERRIDE; - void CopyRawPtrToThread64(ThreadOffset<kMipsDoublewordSize> thr_offs, FrameOffset fr_offs, + void CopyRawPtrToThread64(ThreadOffset<kMips64DoublewordSize> thr_offs, FrameOffset fr_offs, ManagedRegister mscratch) OVERRIDE; void CopyRef(FrameOffset dest, FrameOffset src, ManagedRegister mscratch) OVERRIDE; @@ -466,7 +470,7 @@ class Mips64Assembler FINAL : public Assembler { // Call to address held at [base+offset]. void Call(ManagedRegister base, Offset offset, ManagedRegister mscratch) OVERRIDE; void Call(FrameOffset base, Offset offset, ManagedRegister mscratch) OVERRIDE; - void CallFromThread64(ThreadOffset<kMipsDoublewordSize> offset, + void CallFromThread64(ThreadOffset<kMips64DoublewordSize> offset, ManagedRegister mscratch) OVERRIDE; // Generate code to check if Thread::Current()->exception_ is non-null diff --git a/compiler/utils/mips64/assembler_mips64_test.cc b/compiler/utils/mips64/assembler_mips64_test.cc index 7d79be2731..b758d64c1e 100644 --- a/compiler/utils/mips64/assembler_mips64_test.cc +++ b/compiler/utils/mips64/assembler_mips64_test.cc @@ -543,6 +543,30 @@ TEST_F(AssemblerMIPS64Test, TruncLD) { DriverStr(RepeatFF(&mips64::Mips64Assembler::TruncLD, "trunc.l.d ${reg1}, ${reg2}"), "trunc.l.d"); } +TEST_F(AssemblerMIPS64Test, Mfc1) { + DriverStr(RepeatRF(&mips64::Mips64Assembler::Mfc1, "mfc1 ${reg1}, ${reg2}"), "Mfc1"); +} + +TEST_F(AssemblerMIPS64Test, Mfhc1) { + DriverStr(RepeatRF(&mips64::Mips64Assembler::Mfhc1, "mfhc1 ${reg1}, ${reg2}"), "Mfhc1"); +} + +TEST_F(AssemblerMIPS64Test, Mtc1) { + DriverStr(RepeatRF(&mips64::Mips64Assembler::Mtc1, "mtc1 ${reg1}, ${reg2}"), "Mtc1"); +} + +TEST_F(AssemblerMIPS64Test, Mthc1) { + DriverStr(RepeatRF(&mips64::Mips64Assembler::Mthc1, "mthc1 ${reg1}, ${reg2}"), "Mthc1"); +} + +TEST_F(AssemblerMIPS64Test, Dmfc1) { + DriverStr(RepeatRF(&mips64::Mips64Assembler::Dmfc1, "dmfc1 ${reg1}, ${reg2}"), "Dmfc1"); +} + +TEST_F(AssemblerMIPS64Test, Dmtc1) { + DriverStr(RepeatRF(&mips64::Mips64Assembler::Dmtc1, "dmtc1 ${reg1}, ${reg2}"), "Dmtc1"); +} + //////////////// // CALL / JMP // //////////////// @@ -827,6 +851,44 @@ TEST_F(AssemblerMIPS64Test, Dshd) { DriverStr(RepeatRR(&mips64::Mips64Assembler::Dshd, "dshd ${reg1}, ${reg2}"), "dshd"); } +TEST_F(AssemblerMIPS64Test, Dext) { + std::vector<mips64::GpuRegister*> reg1_registers = GetRegisters(); + std::vector<mips64::GpuRegister*> reg2_registers = GetRegisters(); + WarnOnCombinations(reg1_registers.size() * reg2_registers.size() * 33 * 16); + std::ostringstream expected; + for (mips64::GpuRegister* reg1 : reg1_registers) { + for (mips64::GpuRegister* reg2 : reg2_registers) { + for (int32_t pos = 0; pos < 32; pos++) { + for (int32_t size = 1; size <= 32; size++) { + __ Dext(*reg1, *reg2, pos, size); + expected << "dext $" << *reg1 << ", $" << *reg2 << ", " << pos << ", " << size << "\n"; + } + } + } + } + + DriverStr(expected.str(), "Dext"); +} + +TEST_F(AssemblerMIPS64Test, Dinsu) { + std::vector<mips64::GpuRegister*> reg1_registers = GetRegisters(); + std::vector<mips64::GpuRegister*> reg2_registers = GetRegisters(); + WarnOnCombinations(reg1_registers.size() * reg2_registers.size() * 33 * 16); + std::ostringstream expected; + for (mips64::GpuRegister* reg1 : reg1_registers) { + for (mips64::GpuRegister* reg2 : reg2_registers) { + for (int32_t pos = 32; pos < 64; pos++) { + for (int32_t size = 1; pos + size <= 64; size++) { + __ Dinsu(*reg1, *reg2, pos, size); + expected << "dinsu $" << *reg1 << ", $" << *reg2 << ", " << pos << ", " << size << "\n"; + } + } + } + } + + DriverStr(expected.str(), "Dinsu"); +} + TEST_F(AssemblerMIPS64Test, Wsbh) { DriverStr(RepeatRR(&mips64::Mips64Assembler::Wsbh, "wsbh ${reg1}, ${reg2}"), "wsbh"); } @@ -942,4 +1004,638 @@ TEST_F(AssemblerMIPS64Test, Dclo) { DriverStr(RepeatRR(&mips64::Mips64Assembler::Dclo, "dclo ${reg1}, ${reg2}"), "dclo"); } +TEST_F(AssemblerMIPS64Test, LoadFromOffset) { + __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A0, 0); + __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 0); + __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 1); + __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 256); + __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 1000); + __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 0x7FFF); + __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 0x8000); + __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 0x8001); + __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 0x10000); + __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 0x12345678); + __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, -256); + __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, -32768); + __ LoadFromOffset(mips64::kLoadSignedByte, mips64::A0, mips64::A1, 0xABCDEF00); + + __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A0, 0); + __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 0); + __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 1); + __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 256); + __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 1000); + __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 0x7FFF); + __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 0x8000); + __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 0x8001); + __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 0x10000); + __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 0x12345678); + __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, -256); + __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, -32768); + __ LoadFromOffset(mips64::kLoadUnsignedByte, mips64::A0, mips64::A1, 0xABCDEF00); + + __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A0, 0); + __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 0); + __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 2); + __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 256); + __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 1000); + __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 0x7FFE); + __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 0x8000); + __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 0x8002); + __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 0x10000); + __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 0x12345678); + __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, -256); + __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, -32768); + __ LoadFromOffset(mips64::kLoadSignedHalfword, mips64::A0, mips64::A1, 0xABCDEF00); + + __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A0, 0); + __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 0); + __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 2); + __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 256); + __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 1000); + __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 0x7FFE); + __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 0x8000); + __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 0x8002); + __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 0x10000); + __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 0x12345678); + __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, -256); + __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, -32768); + __ LoadFromOffset(mips64::kLoadUnsignedHalfword, mips64::A0, mips64::A1, 0xABCDEF00); + + __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A0, 0); + __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 0); + __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 4); + __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 256); + __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 1000); + __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 0x7FFC); + __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 0x8000); + __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 0x8004); + __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 0x10000); + __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 0x12345678); + __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, -256); + __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, -32768); + __ LoadFromOffset(mips64::kLoadWord, mips64::A0, mips64::A1, 0xABCDEF00); + + __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A0, 0); + __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 0); + __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 4); + __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 256); + __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 1000); + __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 0x7FFC); + __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 0x8000); + __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 0x8004); + __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 0x10000); + __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 0x12345678); + __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, -256); + __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, -32768); + __ LoadFromOffset(mips64::kLoadUnsignedWord, mips64::A0, mips64::A1, 0xABCDEF00); + + __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A0, 0); + __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 0); + __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 4); + __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 256); + __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 1000); + __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 0x7FFC); + __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 0x8000); + __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 0x8004); + __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 0x10000); + __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 0x12345678); + __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, -256); + __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, -32768); + __ LoadFromOffset(mips64::kLoadDoubleword, mips64::A0, mips64::A1, 0xABCDEF00); + + const char* expected = + "lb $a0, 0($a0)\n" + "lb $a0, 0($a1)\n" + "lb $a0, 1($a1)\n" + "lb $a0, 256($a1)\n" + "lb $a0, 1000($a1)\n" + "lb $a0, 0x7FFF($a1)\n" + "ori $at, $zero, 0x8000\n" + "daddu $at, $at, $a1\n" + "lb $a0, 0($at)\n" + "ori $at, $zero, 0x8000\n" + "daddu $at, $at, $a1\n" + "lb $a0, 1($at)\n" + "lui $at, 1\n" + "daddu $at, $at, $a1\n" + "lb $a0, 0($at)\n" + "lui $at, 0x1234\n" + "ori $at, 0x5678\n" + "daddu $at, $at, $a1\n" + "lb $a0, 0($at)\n" + "lb $a0, -256($a1)\n" + "lb $a0, -32768($a1)\n" + "lui $at, 0xABCD\n" + "ori $at, 0xEF00\n" + "daddu $at, $at, $a1\n" + "lb $a0, 0($at)\n" + + "lbu $a0, 0($a0)\n" + "lbu $a0, 0($a1)\n" + "lbu $a0, 1($a1)\n" + "lbu $a0, 256($a1)\n" + "lbu $a0, 1000($a1)\n" + "lbu $a0, 0x7FFF($a1)\n" + "ori $at, $zero, 0x8000\n" + "daddu $at, $at, $a1\n" + "lbu $a0, 0($at)\n" + "ori $at, $zero, 0x8000\n" + "daddu $at, $at, $a1\n" + "lbu $a0, 1($at)\n" + "lui $at, 1\n" + "daddu $at, $at, $a1\n" + "lbu $a0, 0($at)\n" + "lui $at, 0x1234\n" + "ori $at, 0x5678\n" + "daddu $at, $at, $a1\n" + "lbu $a0, 0($at)\n" + "lbu $a0, -256($a1)\n" + "lbu $a0, -32768($a1)\n" + "lui $at, 0xABCD\n" + "ori $at, 0xEF00\n" + "daddu $at, $at, $a1\n" + "lbu $a0, 0($at)\n" + + "lh $a0, 0($a0)\n" + "lh $a0, 0($a1)\n" + "lh $a0, 2($a1)\n" + "lh $a0, 256($a1)\n" + "lh $a0, 1000($a1)\n" + "lh $a0, 0x7FFE($a1)\n" + "ori $at, $zero, 0x8000\n" + "daddu $at, $at, $a1\n" + "lh $a0, 0($at)\n" + "ori $at, $zero, 0x8000\n" + "daddu $at, $at, $a1\n" + "lh $a0, 2($at)\n" + "lui $at, 1\n" + "daddu $at, $at, $a1\n" + "lh $a0, 0($at)\n" + "lui $at, 0x1234\n" + "ori $at, 0x5678\n" + "daddu $at, $at, $a1\n" + "lh $a0, 0($at)\n" + "lh $a0, -256($a1)\n" + "lh $a0, -32768($a1)\n" + "lui $at, 0xABCD\n" + "ori $at, 0xEF00\n" + "daddu $at, $at, $a1\n" + "lh $a0, 0($at)\n" + + "lhu $a0, 0($a0)\n" + "lhu $a0, 0($a1)\n" + "lhu $a0, 2($a1)\n" + "lhu $a0, 256($a1)\n" + "lhu $a0, 1000($a1)\n" + "lhu $a0, 0x7FFE($a1)\n" + "ori $at, $zero, 0x8000\n" + "daddu $at, $at, $a1\n" + "lhu $a0, 0($at)\n" + "ori $at, $zero, 0x8000\n" + "daddu $at, $at, $a1\n" + "lhu $a0, 2($at)\n" + "lui $at, 1\n" + "daddu $at, $at, $a1\n" + "lhu $a0, 0($at)\n" + "lui $at, 0x1234\n" + "ori $at, 0x5678\n" + "daddu $at, $at, $a1\n" + "lhu $a0, 0($at)\n" + "lhu $a0, -256($a1)\n" + "lhu $a0, -32768($a1)\n" + "lui $at, 0xABCD\n" + "ori $at, 0xEF00\n" + "daddu $at, $at, $a1\n" + "lhu $a0, 0($at)\n" + + "lw $a0, 0($a0)\n" + "lw $a0, 0($a1)\n" + "lw $a0, 4($a1)\n" + "lw $a0, 256($a1)\n" + "lw $a0, 1000($a1)\n" + "lw $a0, 0x7FFC($a1)\n" + "ori $at, $zero, 0x8000\n" + "daddu $at, $at, $a1\n" + "lw $a0, 0($at)\n" + "ori $at, $zero, 0x8000\n" + "daddu $at, $at, $a1\n" + "lw $a0, 4($at)\n" + "lui $at, 1\n" + "daddu $at, $at, $a1\n" + "lw $a0, 0($at)\n" + "lui $at, 0x1234\n" + "ori $at, 0x5678\n" + "daddu $at, $at, $a1\n" + "lw $a0, 0($at)\n" + "lw $a0, -256($a1)\n" + "lw $a0, -32768($a1)\n" + "lui $at, 0xABCD\n" + "ori $at, 0xEF00\n" + "daddu $at, $at, $a1\n" + "lw $a0, 0($at)\n" + + "lwu $a0, 0($a0)\n" + "lwu $a0, 0($a1)\n" + "lwu $a0, 4($a1)\n" + "lwu $a0, 256($a1)\n" + "lwu $a0, 1000($a1)\n" + "lwu $a0, 0x7FFC($a1)\n" + "ori $at, $zero, 0x8000\n" + "daddu $at, $at, $a1\n" + "lwu $a0, 0($at)\n" + "ori $at, $zero, 0x8000\n" + "daddu $at, $at, $a1\n" + "lwu $a0, 4($at)\n" + "lui $at, 1\n" + "daddu $at, $at, $a1\n" + "lwu $a0, 0($at)\n" + "lui $at, 0x1234\n" + "ori $at, 0x5678\n" + "daddu $at, $at, $a1\n" + "lwu $a0, 0($at)\n" + "lwu $a0, -256($a1)\n" + "lwu $a0, -32768($a1)\n" + "lui $at, 0xABCD\n" + "ori $at, 0xEF00\n" + "daddu $at, $at, $a1\n" + "lwu $a0, 0($at)\n" + + "ld $a0, 0($a0)\n" + "ld $a0, 0($a1)\n" + "lwu $a0, 4($a1)\n" + "lwu $t3, 8($a1)\n" + "dins $a0, $t3, 32, 32\n" + "ld $a0, 256($a1)\n" + "ld $a0, 1000($a1)\n" + "ori $at, $zero, 0x7FF8\n" + "daddu $at, $at, $a1\n" + "lwu $a0, 4($at)\n" + "lwu $t3, 8($at)\n" + "dins $a0, $t3, 32, 32\n" + "ori $at, $zero, 0x8000\n" + "daddu $at, $at, $a1\n" + "ld $a0, 0($at)\n" + "ori $at, $zero, 0x8000\n" + "daddu $at, $at, $a1\n" + "lwu $a0, 4($at)\n" + "lwu $t3, 8($at)\n" + "dins $a0, $t3, 32, 32\n" + "lui $at, 1\n" + "daddu $at, $at, $a1\n" + "ld $a0, 0($at)\n" + "lui $at, 0x1234\n" + "ori $at, 0x5678\n" + "daddu $at, $at, $a1\n" + "ld $a0, 0($at)\n" + "ld $a0, -256($a1)\n" + "ld $a0, -32768($a1)\n" + "lui $at, 0xABCD\n" + "ori $at, 0xEF00\n" + "daddu $at, $at, $a1\n" + "ld $a0, 0($at)\n"; + DriverStr(expected, "LoadFromOffset"); +} + +TEST_F(AssemblerMIPS64Test, LoadFpuFromOffset) { + __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 0); + __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 4); + __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 256); + __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 0x7FFC); + __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 0x8000); + __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 0x8004); + __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 0x10000); + __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 0x12345678); + __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, -256); + __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, -32768); + __ LoadFpuFromOffset(mips64::kLoadWord, mips64::F0, mips64::A0, 0xABCDEF00); + + __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 0); + __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 4); + __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 256); + __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 0x7FFC); + __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 0x8000); + __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 0x8004); + __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 0x10000); + __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 0x12345678); + __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, -256); + __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, -32768); + __ LoadFpuFromOffset(mips64::kLoadDoubleword, mips64::F0, mips64::A0, 0xABCDEF00); + + const char* expected = + "lwc1 $f0, 0($a0)\n" + "lwc1 $f0, 4($a0)\n" + "lwc1 $f0, 256($a0)\n" + "lwc1 $f0, 0x7FFC($a0)\n" + "ori $at, $zero, 0x8000\n" + "daddu $at, $at, $a0\n" + "lwc1 $f0, 0($at)\n" + "ori $at, $zero, 0x8000\n" + "daddu $at, $at, $a0\n" + "lwc1 $f0, 4($at)\n" + "lui $at, 1\n" + "daddu $at, $at, $a0\n" + "lwc1 $f0, 0($at)\n" + "lui $at, 0x1234\n" + "ori $at, 0x5678\n" + "daddu $at, $at, $a0\n" + "lwc1 $f0, 0($at)\n" + "lwc1 $f0, -256($a0)\n" + "lwc1 $f0, -32768($a0)\n" + "lui $at, 0xABCD\n" + "ori $at, 0xEF00\n" + "daddu $at, $at, $a0\n" + "lwc1 $f0, 0($at)\n" + + "ldc1 $f0, 0($a0)\n" + "lwc1 $f0, 4($a0)\n" + "lw $t3, 8($a0)\n" + "mthc1 $t3, $f0\n" + "ldc1 $f0, 256($a0)\n" + "ori $at, $zero, 0x7FF8\n" + "daddu $at, $at, $a0\n" + "lwc1 $f0, 4($at)\n" + "lw $t3, 8($at)\n" + "mthc1 $t3, $f0\n" + "ori $at, $zero, 0x8000\n" + "daddu $at, $at, $a0\n" + "ldc1 $f0, 0($at)\n" + "ori $at, $zero, 0x8000\n" + "daddu $at, $at, $a0\n" + "lwc1 $f0, 4($at)\n" + "lw $t3, 8($at)\n" + "mthc1 $t3, $f0\n" + "lui $at, 1\n" + "daddu $at, $at, $a0\n" + "ldc1 $f0, 0($at)\n" + "lui $at, 0x1234\n" + "ori $at, 0x5678\n" + "daddu $at, $at, $a0\n" + "ldc1 $f0, 0($at)\n" + "ldc1 $f0, -256($a0)\n" + "ldc1 $f0, -32768($a0)\n" + "lui $at, 0xABCD\n" + "ori $at, 0xEF00\n" + "daddu $at, $at, $a0\n" + "ldc1 $f0, 0($at)\n"; + DriverStr(expected, "LoadFpuFromOffset"); +} + +TEST_F(AssemblerMIPS64Test, StoreToOffset) { + __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A0, 0); + __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 0); + __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 1); + __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 256); + __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 1000); + __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 0x7FFF); + __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 0x8000); + __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 0x8001); + __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 0x10000); + __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 0x12345678); + __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, -256); + __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, -32768); + __ StoreToOffset(mips64::kStoreByte, mips64::A0, mips64::A1, 0xABCDEF00); + + __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A0, 0); + __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 0); + __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 2); + __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 256); + __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 1000); + __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 0x7FFE); + __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 0x8000); + __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 0x8002); + __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 0x10000); + __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 0x12345678); + __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, -256); + __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, -32768); + __ StoreToOffset(mips64::kStoreHalfword, mips64::A0, mips64::A1, 0xABCDEF00); + + __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A0, 0); + __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 0); + __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 4); + __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 256); + __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 1000); + __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 0x7FFC); + __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 0x8000); + __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 0x8004); + __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 0x10000); + __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 0x12345678); + __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, -256); + __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, -32768); + __ StoreToOffset(mips64::kStoreWord, mips64::A0, mips64::A1, 0xABCDEF00); + + __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A0, 0); + __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 0); + __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 4); + __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 256); + __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 1000); + __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 0x7FFC); + __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 0x8000); + __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 0x8004); + __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 0x10000); + __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 0x12345678); + __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, -256); + __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, -32768); + __ StoreToOffset(mips64::kStoreDoubleword, mips64::A0, mips64::A1, 0xABCDEF00); + + const char* expected = + "sb $a0, 0($a0)\n" + "sb $a0, 0($a1)\n" + "sb $a0, 1($a1)\n" + "sb $a0, 256($a1)\n" + "sb $a0, 1000($a1)\n" + "sb $a0, 0x7FFF($a1)\n" + "ori $at, $zero, 0x8000\n" + "daddu $at, $at, $a1\n" + "sb $a0, 0($at)\n" + "ori $at, $zero, 0x8000\n" + "daddu $at, $at, $a1\n" + "sb $a0, 1($at)\n" + "lui $at, 1\n" + "daddu $at, $at, $a1\n" + "sb $a0, 0($at)\n" + "lui $at, 0x1234\n" + "ori $at, 0x5678\n" + "daddu $at, $at, $a1\n" + "sb $a0, 0($at)\n" + "sb $a0, -256($a1)\n" + "sb $a0, -32768($a1)\n" + "lui $at, 0xABCD\n" + "ori $at, 0xEF00\n" + "daddu $at, $at, $a1\n" + "sb $a0, 0($at)\n" + + "sh $a0, 0($a0)\n" + "sh $a0, 0($a1)\n" + "sh $a0, 2($a1)\n" + "sh $a0, 256($a1)\n" + "sh $a0, 1000($a1)\n" + "sh $a0, 0x7FFE($a1)\n" + "ori $at, $zero, 0x8000\n" + "daddu $at, $at, $a1\n" + "sh $a0, 0($at)\n" + "ori $at, $zero, 0x8000\n" + "daddu $at, $at, $a1\n" + "sh $a0, 2($at)\n" + "lui $at, 1\n" + "daddu $at, $at, $a1\n" + "sh $a0, 0($at)\n" + "lui $at, 0x1234\n" + "ori $at, 0x5678\n" + "daddu $at, $at, $a1\n" + "sh $a0, 0($at)\n" + "sh $a0, -256($a1)\n" + "sh $a0, -32768($a1)\n" + "lui $at, 0xABCD\n" + "ori $at, 0xEF00\n" + "daddu $at, $at, $a1\n" + "sh $a0, 0($at)\n" + + "sw $a0, 0($a0)\n" + "sw $a0, 0($a1)\n" + "sw $a0, 4($a1)\n" + "sw $a0, 256($a1)\n" + "sw $a0, 1000($a1)\n" + "sw $a0, 0x7FFC($a1)\n" + "ori $at, $zero, 0x8000\n" + "daddu $at, $at, $a1\n" + "sw $a0, 0($at)\n" + "ori $at, $zero, 0x8000\n" + "daddu $at, $at, $a1\n" + "sw $a0, 4($at)\n" + "lui $at, 1\n" + "daddu $at, $at, $a1\n" + "sw $a0, 0($at)\n" + "lui $at, 0x1234\n" + "ori $at, 0x5678\n" + "daddu $at, $at, $a1\n" + "sw $a0, 0($at)\n" + "sw $a0, -256($a1)\n" + "sw $a0, -32768($a1)\n" + "lui $at, 0xABCD\n" + "ori $at, 0xEF00\n" + "daddu $at, $at, $a1\n" + "sw $a0, 0($at)\n" + + "sd $a0, 0($a0)\n" + "sd $a0, 0($a1)\n" + "sw $a0, 4($a1)\n" + "dsrl32 $t3, $a0, 0\n" + "sw $t3, 8($a1)\n" + "sd $a0, 256($a1)\n" + "sd $a0, 1000($a1)\n" + "ori $at, $zero, 0x7FF8\n" + "daddu $at, $at, $a1\n" + "sw $a0, 4($at)\n" + "dsrl32 $t3, $a0, 0\n" + "sw $t3, 8($at)\n" + "ori $at, $zero, 0x8000\n" + "daddu $at, $at, $a1\n" + "sd $a0, 0($at)\n" + "ori $at, $zero, 0x8000\n" + "daddu $at, $at, $a1\n" + "sw $a0, 4($at)\n" + "dsrl32 $t3, $a0, 0\n" + "sw $t3, 8($at)\n" + "lui $at, 1\n" + "daddu $at, $at, $a1\n" + "sd $a0, 0($at)\n" + "lui $at, 0x1234\n" + "ori $at, 0x5678\n" + "daddu $at, $at, $a1\n" + "sd $a0, 0($at)\n" + "sd $a0, -256($a1)\n" + "sd $a0, -32768($a1)\n" + "lui $at, 0xABCD\n" + "ori $at, 0xEF00\n" + "daddu $at, $at, $a1\n" + "sd $a0, 0($at)\n"; + DriverStr(expected, "StoreToOffset"); +} + +TEST_F(AssemblerMIPS64Test, StoreFpuToOffset) { + __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 0); + __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 4); + __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 256); + __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 0x7FFC); + __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 0x8000); + __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 0x8004); + __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 0x10000); + __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 0x12345678); + __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, -256); + __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, -32768); + __ StoreFpuToOffset(mips64::kStoreWord, mips64::F0, mips64::A0, 0xABCDEF00); + + __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 0); + __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 4); + __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 256); + __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 0x7FFC); + __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 0x8000); + __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 0x8004); + __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 0x10000); + __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 0x12345678); + __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, -256); + __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, -32768); + __ StoreFpuToOffset(mips64::kStoreDoubleword, mips64::F0, mips64::A0, 0xABCDEF00); + + const char* expected = + "swc1 $f0, 0($a0)\n" + "swc1 $f0, 4($a0)\n" + "swc1 $f0, 256($a0)\n" + "swc1 $f0, 0x7FFC($a0)\n" + "ori $at, $zero, 0x8000\n" + "daddu $at, $at, $a0\n" + "swc1 $f0, 0($at)\n" + "ori $at, $zero, 0x8000\n" + "daddu $at, $at, $a0\n" + "swc1 $f0, 4($at)\n" + "lui $at, 1\n" + "daddu $at, $at, $a0\n" + "swc1 $f0, 0($at)\n" + "lui $at, 0x1234\n" + "ori $at, 0x5678\n" + "daddu $at, $at, $a0\n" + "swc1 $f0, 0($at)\n" + "swc1 $f0, -256($a0)\n" + "swc1 $f0, -32768($a0)\n" + "lui $at, 0xABCD\n" + "ori $at, 0xEF00\n" + "daddu $at, $at, $a0\n" + "swc1 $f0, 0($at)\n" + + "sdc1 $f0, 0($a0)\n" + "mfhc1 $t3, $f0\n" + "swc1 $f0, 4($a0)\n" + "sw $t3, 8($a0)\n" + "sdc1 $f0, 256($a0)\n" + "ori $at, $zero, 0x7FF8\n" + "daddu $at, $at, $a0\n" + "mfhc1 $t3, $f0\n" + "swc1 $f0, 4($at)\n" + "sw $t3, 8($at)\n" + "ori $at, $zero, 0x8000\n" + "daddu $at, $at, $a0\n" + "sdc1 $f0, 0($at)\n" + "ori $at, $zero, 0x8000\n" + "daddu $at, $at, $a0\n" + "mfhc1 $t3, $f0\n" + "swc1 $f0, 4($at)\n" + "sw $t3, 8($at)\n" + "lui $at, 1\n" + "daddu $at, $at, $a0\n" + "sdc1 $f0, 0($at)\n" + "lui $at, 0x1234\n" + "ori $at, 0x5678\n" + "daddu $at, $at, $a0\n" + "sdc1 $f0, 0($at)\n" + "sdc1 $f0, -256($a0)\n" + "sdc1 $f0, -32768($a0)\n" + "lui $at, 0xABCD\n" + "ori $at, 0xEF00\n" + "daddu $at, $at, $a0\n" + "sdc1 $f0, 0($at)\n"; + DriverStr(expected, "StoreFpuToOffset"); +} + +#undef __ + } // namespace art |