diff options
author | 2023-03-15 13:36:40 +0800 | |
---|---|---|
committer | 2023-05-11 16:08:45 +0000 | |
commit | 593fc2ed0b80bc2af4834f595cbb9fcc20edeb03 (patch) | |
tree | 18de608f51c3ae9f124a219d9c54d7aa0bac3b5d | |
parent | ca3bf187748a26cfb33b53965e29086c5dc614de (diff) |
Add assembler for riscv64, part 2.
Test: m test-art-host-gtest
Bug: 271573990
Signed-off-by: Lifang Xia <lifang_xia@linux.alibaba.com>
Signed-off-by: Wendong Wang <wangwd@xcvmbyte.com>
Signed-off-by: Cao Xia <caoxia@eswincomputing.com>
Change-Id: I51a5c17f0d1d4e10d3b3b2f4e2ae88a75ca13bd1
-rw-r--r-- | compiler/utils/assembler_test.h | 191 | ||||
-rw-r--r-- | compiler/utils/riscv64/assembler_riscv64.cc | 98 | ||||
-rw-r--r-- | compiler/utils/riscv64/assembler_riscv64.h | 93 | ||||
-rw-r--r-- | compiler/utils/riscv64/assembler_riscv64_test.cc | 181 |
4 files changed, 528 insertions, 35 deletions
diff --git a/compiler/utils/assembler_test.h b/compiler/utils/assembler_test.h index f8a7f61f75..d375302d9d 100644 --- a/compiler/utils/assembler_test.h +++ b/compiler/utils/assembler_test.h @@ -411,6 +411,179 @@ class AssemblerTest : public AssemblerTestBase { return str; } + template <typename RegType, typename ImmType> + std::string RepeatTemplatedRegisterImmBitsShift( + void (Ass::*f)(RegType, ImmType), + int imm_bits, + int shift, + const std::vector<RegType*> registers, + std::string (AssemblerTest::*GetName)(const RegType&), + const std::string& fmt, + int bias) { + std::string str; + std::vector<int64_t> imms = CreateImmediateValuesBits(abs(imm_bits), (imm_bits > 0), shift); + + for (auto reg : registers) { + for (int64_t imm : imms) { + ImmType new_imm = CreateImmediate(imm); + if (f != nullptr) { + (assembler_.get()->*f)(*reg, new_imm + bias); + } + std::string base = fmt; + + std::string reg_string = (this->*GetName)(*reg); + size_t reg_index; + while ((reg_index = base.find(REG_TOKEN)) != std::string::npos) { + base.replace(reg_index, ConstexprStrLen(REG_TOKEN), reg_string); + } + + size_t imm_index = base.find(IMM_TOKEN); + if (imm_index != std::string::npos) { + std::ostringstream sreg; + sreg << imm + bias; + std::string imm_string = sreg.str(); + base.replace(imm_index, ConstexprStrLen(IMM_TOKEN), imm_string); + } + + if (str.size() > 0) { + str += "\n"; + } + str += base; + } + } + // Add a newline at the end. + str += "\n"; + return str; + } + + template <typename ImmType> + std::string RepeatTemplatedImmBitsShift( + void (Ass::*f)(ImmType), int imm_bits, int shift, const std::string& fmt, int bias = 0) { + std::vector<int64_t> imms = CreateImmediateValuesBits(abs(imm_bits), (imm_bits > 0), shift); + + WarnOnCombinations(imms.size()); + + std::string str; + + for (int64_t imm : imms) { + ImmType new_imm = CreateImmediate(imm); + if (f != nullptr) { + (assembler_.get()->*f)(new_imm + bias); + } + std::string base = fmt; + + size_t imm_index = base.find(IMM_TOKEN); + if (imm_index != std::string::npos) { + std::ostringstream sreg; + sreg << imm; + std::string imm_string = sreg.str(); + base.replace(imm_index, ConstexprStrLen(IMM_TOKEN), imm_string); + } + + if (str.size() > 0) { + str += "\n"; + } + str += base; + } + + // Add a newline at the end. + str += "\n"; + return str; + } + + template <typename Reg1, typename Reg2, typename ImmType> + std::string RepeatTemplatedRegistersImmBitsShift( + void (Ass::*f)(Reg1, Reg2, ImmType), + int imm_bits, + int shift, + const std::vector<Reg1*> reg1_registers, + const std::vector<Reg2*> reg2_registers, + std::string (AssemblerTest::*GetName1)(const Reg1&), + std::string (AssemblerTest::*GetName2)(const Reg2&), + const std::string& fmt, + int bias = 0, + int multiplier = 1) { + std::string str; + std::vector<int64_t> imms = CreateImmediateValuesBits(abs(imm_bits), (imm_bits > 0), shift); + + for (auto reg1 : reg1_registers) { + for (auto reg2 : reg2_registers) { + for (int64_t imm : imms) { + ImmType new_imm = CreateImmediate(imm); + if (f != nullptr) { + (assembler_.get()->*f)(*reg1, *reg2, new_imm * multiplier + bias); + } + std::string base = fmt; + + std::string reg1_string = (this->*GetName1)(*reg1); + size_t reg1_index; + while ((reg1_index = base.find(REG1_TOKEN)) != std::string::npos) { + base.replace(reg1_index, ConstexprStrLen(REG1_TOKEN), reg1_string); + } + + std::string reg2_string = (this->*GetName2)(*reg2); + size_t reg2_index; + while ((reg2_index = base.find(REG2_TOKEN)) != std::string::npos) { + base.replace(reg2_index, ConstexprStrLen(REG2_TOKEN), reg2_string); + } + + size_t imm_index = base.find(IMM_TOKEN); + if (imm_index != std::string::npos) { + std::ostringstream sreg; + sreg << imm * multiplier + bias; + std::string imm_string = sreg.str(); + base.replace(imm_index, ConstexprStrLen(IMM_TOKEN), imm_string); + } + + if (str.size() > 0) { + str += "\n"; + } + str += base; + } + } + } + // Add a newline at the end. + str += "\n"; + return str; + } + + template <typename ImmType> + std::string RepeatIbS( + void (Ass::*f)(ImmType), int imm_bits, int shift, const std::string& fmt, int bias = 0) { + return RepeatTemplatedImmBitsShift<ImmType>(f, imm_bits, shift, fmt, bias); + } + + template <typename ImmType> + std::string RepeatRIbS( + void (Ass::*f)(Reg, ImmType), int imm_bits, int shift, const std::string& fmt, int bias = 0) { + return RepeatTemplatedRegisterImmBitsShift<Reg, ImmType>( + f, + imm_bits, + shift, + GetRegisters(), + &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, + fmt, + bias); + } + + template <typename ImmType> + std::string RepeatRRIbS(void (Ass::*f)(Reg, Reg, ImmType), + int imm_bits, + int shift, + const std::string& fmt, + int bias = 0) { + return RepeatTemplatedRegistersImmBitsShift<Reg, Reg, ImmType>( + f, + imm_bits, + shift, + GetRegisters(), + GetRegisters(), + &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, + &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, + fmt, + bias); + } + template <typename ImmType> std::string RepeatRRIb(void (Ass::*f)(Reg, Reg, ImmType), int imm_bits, @@ -857,7 +1030,9 @@ class AssemblerTest : public AssemblerTestBase { const int kMaxBitsExhaustiveTest = 8; // Create a couple of immediate values up to the number of bits given. - virtual std::vector<int64_t> CreateImmediateValuesBits(const int imm_bits, bool as_uint = false) { + virtual std::vector<int64_t> CreateImmediateValuesBits(const int imm_bits, + bool as_uint = false, + int shift = 0) { CHECK_GT(imm_bits, 0); CHECK_LE(imm_bits, 64); std::vector<int64_t> res; @@ -865,11 +1040,11 @@ class AssemblerTest : public AssemblerTestBase { if (imm_bits <= kMaxBitsExhaustiveTest) { if (as_uint) { for (uint64_t i = MinInt<uint64_t>(imm_bits); i <= MaxInt<uint64_t>(imm_bits); i++) { - res.push_back(static_cast<int64_t>(i)); + res.push_back(static_cast<int64_t>(i << shift)); } } else { for (int64_t i = MinInt<int64_t>(imm_bits); i <= MaxInt<int64_t>(imm_bits); i++) { - res.push_back(i); + res.push_back(i << shift); } } } else { @@ -877,14 +1052,14 @@ class AssemblerTest : public AssemblerTestBase { for (uint64_t i = MinInt<uint64_t>(kMaxBitsExhaustiveTest); i <= MaxInt<uint64_t>(kMaxBitsExhaustiveTest); i++) { - res.push_back(static_cast<int64_t>(i)); + res.push_back(static_cast<int64_t>(i << shift)); } for (int i = 0; i <= imm_bits; i++) { uint64_t j = (MaxInt<uint64_t>(kMaxBitsExhaustiveTest) + 1) + ((MaxInt<uint64_t>(imm_bits) - (MaxInt<uint64_t>(kMaxBitsExhaustiveTest) + 1)) * i / imm_bits); - res.push_back(static_cast<int64_t>(j)); + res.push_back(static_cast<int64_t>(j << shift)); } } else { for (int i = 0; i <= imm_bits; i++) { @@ -892,18 +1067,18 @@ class AssemblerTest : public AssemblerTestBase { ((((MinInt<int64_t>(kMaxBitsExhaustiveTest) - 1) - MinInt<int64_t>(imm_bits)) * i) / imm_bits); - res.push_back(static_cast<int64_t>(j)); + res.push_back(static_cast<int64_t>(j << shift)); } for (int64_t i = MinInt<int64_t>(kMaxBitsExhaustiveTest); i <= MaxInt<int64_t>(kMaxBitsExhaustiveTest); i++) { - res.push_back(static_cast<int64_t>(i)); + res.push_back(static_cast<int64_t>(i << shift)); } for (int i = 0; i <= imm_bits; i++) { int64_t j = (MaxInt<int64_t>(kMaxBitsExhaustiveTest) + 1) + ((MaxInt<int64_t>(imm_bits) - (MaxInt<int64_t>(kMaxBitsExhaustiveTest) + 1)) * i / imm_bits); - res.push_back(static_cast<int64_t>(j)); + res.push_back(static_cast<int64_t>(j << shift)); } } } diff --git a/compiler/utils/riscv64/assembler_riscv64.cc b/compiler/utils/riscv64/assembler_riscv64.cc index cc2d526239..fd6fae35fc 100644 --- a/compiler/utils/riscv64/assembler_riscv64.cc +++ b/compiler/utils/riscv64/assembler_riscv64.cc @@ -43,6 +43,52 @@ void Riscv64Assembler::Emit(uint32_t value) { /////////////////////////////// RV64 "IM" Instructions /////////////////////////////// +// LUI/AUIPC (RV32I, with sign-extension on RV64I), opcode = 0x17, 0x37 + +void Riscv64Assembler::Lui(XRegister rd, uint32_t imm20) { + EmitU(imm20, rd, 0x37); +} + +void Riscv64Assembler::Auipc(XRegister rd, uint32_t imm20) { + EmitU(imm20, rd, 0x17); +} + +// Jump instructions (RV32I), opcode = 0x67, 0x6f + +void Riscv64Assembler::Jal(XRegister rd, int32_t offset) { + EmitJ(offset, rd, 0x6F); +} + +void Riscv64Assembler::Jalr(XRegister rd, XRegister rs1, int32_t offset) { + EmitI(offset, rs1, 0x0, rd, 0x67); +} + +// Branch instructions, opcode = 0x63 (subfunc from 0x0 ~ 0x7), 0x67, 0x6f + +void Riscv64Assembler::Beq(XRegister rs1, XRegister rs2, int32_t offset) { + EmitB(offset, rs2, rs1, 0x0, 0x63); +} + +void Riscv64Assembler::Bne(XRegister rs1, XRegister rs2, int32_t offset) { + EmitB(offset, rs2, rs1, 0x1, 0x63); +} + +void Riscv64Assembler::Blt(XRegister rs1, XRegister rs2, int32_t offset) { + EmitB(offset, rs2, rs1, 0x4, 0x63); +} + +void Riscv64Assembler::Bge(XRegister rs1, XRegister rs2, int32_t offset) { + EmitB(offset, rs2, rs1, 0x5, 0x63); +} + +void Riscv64Assembler::Bltu(XRegister rs1, XRegister rs2, int32_t offset) { + EmitB(offset, rs2, rs1, 0x6, 0x63); +} + +void Riscv64Assembler::Bgeu(XRegister rs1, XRegister rs2, int32_t offset) { + EmitB(offset, rs2, rs1, 0x7, 0x63); +} + // Load instructions (RV32I+RV64I): opcode = 0x03, funct3 from 0x0 ~ 0x6 void Riscv64Assembler::Lb(XRegister rd, XRegister rs1, int32_t offset) { @@ -613,6 +659,58 @@ void Riscv64Assembler::FAbsD(FRegister rd, FRegister rs) { FSgnjxS(rd, rs, rs); void Riscv64Assembler::FNegD(FRegister rd, FRegister rs) { FSgnjnS(rd, rs, rs); } +void Riscv64Assembler::Beqz(XRegister rs, int32_t offset) { + Beq(rs, Zero, offset); +} + +void Riscv64Assembler::Bnez(XRegister rs, int32_t offset) { + Bne(rs, Zero, offset); +} + +void Riscv64Assembler::Blez(XRegister rt, int32_t offset) { + Bge(Zero, rt, offset); +} + +void Riscv64Assembler::Bgez(XRegister rt, int32_t offset) { + Bge(rt, Zero, offset); +} + +void Riscv64Assembler::Bltz(XRegister rt, int32_t offset) { + Blt(rt, Zero, offset); +} + +void Riscv64Assembler::Bgtz(XRegister rt, int32_t offset) { + Blt(Zero, rt, offset); +} + +void Riscv64Assembler::Bgt(XRegister rs, XRegister rt, int32_t offset) { + Blt(rt, rs, offset); +} + +void Riscv64Assembler::Ble(XRegister rs, XRegister rt, int32_t offset) { + Bge(rt, rs, offset); +} + +void Riscv64Assembler::Bgtu(XRegister rs, XRegister rt, int32_t offset) { + Bltu(rt, rs, offset); +} + +void Riscv64Assembler::Bleu(XRegister rs, XRegister rt, int32_t offset) { + Bgeu(rt, rs, offset); +} + +void Riscv64Assembler::J(int32_t offset) { Jal(Zero, offset); } + +void Riscv64Assembler::Jal(int32_t offset) { Jal(RA, offset); } + +void Riscv64Assembler::Jr(XRegister rs) { Jalr(Zero, rs, 0); } + +void Riscv64Assembler::Jalr(XRegister rs) { Jalr(RA, rs, 0); } + +void Riscv64Assembler::Jalr(XRegister rd, XRegister rs) { Jalr(rd, rs, 0); } + +void Riscv64Assembler::Ret() { Jalr(Zero, RA, 0); } + /////////////////////////////// RV64 MACRO Instructions END /////////////////////////////// /////////////////////////////// RV64 VARIANTS extension end //////////// diff --git a/compiler/utils/riscv64/assembler_riscv64.h b/compiler/utils/riscv64/assembler_riscv64.h index b648a712b5..13e7826320 100644 --- a/compiler/utils/riscv64/assembler_riscv64.h +++ b/compiler/utils/riscv64/assembler_riscv64.h @@ -35,13 +35,13 @@ namespace art { namespace riscv64 { enum class FPRoundingMode : uint32_t { - kRNE = 0x0, // Round to Nearest, ties to Even - kRTZ = 0x1, // Round towards Zero - kRDN = 0x2, // Round Down (towards −Infinity) - kRUP = 0x3, // Round Up (towards +Infinity) - kRMM = 0x4, // Round to Nearest, ties to Max Magnitude - kDYN = 0x7, // Dynamic rounding mode - kDefault = kDYN + kRNE = 0x0, // Round to Nearest, ties to Even + kRTZ = 0x1, // Round towards Zero + kRDN = 0x2, // Round Down (towards −Infinity) + kRUP = 0x3, // Round Up (towards +Infinity) + kRMM = 0x4, // Round to Nearest, ties to Max Magnitude + kDYN = 0x7, // Dynamic rounding mode + kDefault = kDYN }; static constexpr size_t kRiscv64HalfwordSize = 2; @@ -65,6 +65,26 @@ class Riscv64Assembler final : public Assembler { size_t CodeSize() const override { return Assembler::CodeSize(); } DebugFrameOpCodeWriterForAssembler& cfi() { return Assembler::cfi(); } + // According to "The RISC-V Instruction Set Manual" + + // LUI/AUIPC (RV32I, with sign-extension on RV64I), opcode = 0x17, 0x37 + // Note: These take a 20-bit unsigned value to align with the clang assembler for testing, + // but the value stored in the register shall actually be sign-extended to 64 bits. + void Lui(XRegister rd, uint32_t imm20); + void Auipc(XRegister rd, uint32_t imm20); + + // Jump instructions (RV32I), opcode = 0x67, 0x6f + void Jal(XRegister rd, int32_t offset); + void Jalr(XRegister rd, XRegister rs1, int32_t offset); + + // Branch instructions (RV32I), opcode = 0x63, funct3 from 0x0 ~ 0x1 and 0x4 ~ 0x7 + void Beq(XRegister rs1, XRegister rs2, int32_t offset); + void Bne(XRegister rs1, XRegister rs2, int32_t offset); + void Blt(XRegister rs1, XRegister rs2, int32_t offset); + void Bge(XRegister rs1, XRegister rs2, int32_t offset); + void Bltu(XRegister rs1, XRegister rs2, int32_t offset); + void Bgeu(XRegister rs1, XRegister rs2, int32_t offset); + // Load instructions (RV32I+RV64I): opcode = 0x03, funct3 from 0x0 ~ 0x6 void Lb(XRegister rd, XRegister rs1, int32_t offset); void Lh(XRegister rd, XRegister rs1, int32_t offset); @@ -292,7 +312,8 @@ class Riscv64Assembler final : public Assembler { void FClassD(XRegister rd, FRegister rs1); ////////////////////////////// RV64 MACRO Instructions START /////////////////////////////// - // These pseudo instructions are from "RISC-V ASM manual". + // These pseudo instructions are from "RISC-V Assembly Programmer's Manual". + void Nop(); void Mv(XRegister rd, XRegister rs); void Not(XRegister rd, XRegister rs); @@ -314,6 +335,27 @@ class Riscv64Assembler final : public Assembler { void FMvD(FRegister rd, FRegister rs); void FAbsD(FRegister rd, FRegister rs); void FNegD(FRegister rd, FRegister rs); + + // Branch pseudo instructions + void Beqz(XRegister rs, int32_t offset); + void Bnez(XRegister rs, int32_t offset); + void Blez(XRegister rs, int32_t offset); + void Bgez(XRegister rs, int32_t offset); + void Bltz(XRegister rs, int32_t offset); + void Bgtz(XRegister rs, int32_t offset); + void Bgt(XRegister rs, XRegister rt, int32_t offset); + void Ble(XRegister rs, XRegister rt, int32_t offset); + void Bgtu(XRegister rs, XRegister rt, int32_t offset); + void Bleu(XRegister rs, XRegister rt, int32_t offset); + + // Jump pseudo instructions + void J(int32_t offset); + void Jal(int32_t offset); + void Jr(XRegister rs); + void Jalr(XRegister rs); + void Jalr(XRegister rd, XRegister rs); + void Ret(); + /////////////////////////////// RV64 MACRO Instructions END /////////////////////////////// void Bind(Label* label ATTRIBUTE_UNUSED) override { @@ -414,6 +456,41 @@ class Riscv64Assembler final : public Assembler { Emit(encoding); } + void EmitB(int32_t offset, XRegister rs2, XRegister rs1, uint32_t funct3, uint32_t opcode) { + DCHECK_ALIGNED(offset, 2); + DCHECK(IsInt<13>(offset)) << offset; + DCHECK(IsUint<5>(static_cast<uint32_t>(rs2))); + DCHECK(IsUint<5>(static_cast<uint32_t>(rs1))); + DCHECK(IsUint<3>(funct3)); + DCHECK(IsUint<7>(opcode)); + uint32_t imm12 = (static_cast<uint32_t>(offset) >> 1) & 0xfffu; + uint32_t encoding = (imm12 & 0x800u) << (31 - 11) | (imm12 & 0x03f0u) << (25 - 4) | + static_cast<uint32_t>(rs2) << 20 | static_cast<uint32_t>(rs1) << 15 | + static_cast<uint32_t>(funct3) << 12 | + (imm12 & 0xfu) << 8 | (imm12 & 0x400u) >> (10 - 7) | opcode; + Emit(encoding); + } + + void EmitU(uint32_t imm20, XRegister rd, uint32_t opcode) { + CHECK(IsUint<20>(imm20)) << imm20; + DCHECK(IsUint<5>(static_cast<uint32_t>(rd))); + DCHECK(IsUint<7>(opcode)); + uint32_t encoding = imm20 << 12 | static_cast<uint32_t>(rd) << 7 | opcode; + Emit(encoding); + } + + void EmitJ(int32_t offset, XRegister rd, uint32_t opcode) { + DCHECK_ALIGNED(offset, 2); + CHECK(IsInt<21>(offset)) << offset; + DCHECK(IsUint<5>(static_cast<uint32_t>(rd))); + DCHECK(IsUint<7>(opcode)); + uint32_t imm20 = (static_cast<uint32_t>(offset) >> 1) & 0xfffffu; + uint32_t encoding = (imm20 & 0x80000u) << (31 - 19) | (imm20 & 0x03ffu) << 21 | + (imm20 & 0x400u) << (20 - 10) | (imm20 & 0x7f800u) << (12 - 11) | + static_cast<uint32_t>(rd) << 7 | opcode; + Emit(encoding); + } + static constexpr uint32_t kXlen = 64; DISALLOW_COPY_AND_ASSIGN(Riscv64Assembler); diff --git a/compiler/utils/riscv64/assembler_riscv64_test.cc b/compiler/utils/riscv64/assembler_riscv64_test.cc index 019191c852..20d607beff 100644 --- a/compiler/utils/riscv64/assembler_riscv64_test.cc +++ b/compiler/utils/riscv64/assembler_riscv64_test.cc @@ -189,62 +189,118 @@ class AssemblerRISCV64Test : public AssemblerTest<riscv64::Riscv64Assembler, TEST_F(AssemblerRISCV64Test, Toolchain) { EXPECT_TRUE(CheckTools()); } +TEST_F(AssemblerRISCV64Test, Lui) { + DriverStr(RepeatRIb(&riscv64::Riscv64Assembler::Lui, 20, "lui {reg}, {imm}"), "Lui"); +} + +TEST_F(AssemblerRISCV64Test, Auipc) { + DriverStr(RepeatRIb(&riscv64::Riscv64Assembler::Auipc, 20, "auipc {reg}, {imm}"), "Auipc"); +} + +TEST_F(AssemblerRISCV64Test, Jal) { + // TODO(riscv64): Change "-19, 2" to "-20, 1" for "C" Standard Extension. + DriverStr(RepeatRIbS(&riscv64::Riscv64Assembler::Jal, -19, 2, "jal {reg}, {imm}\n"), + "Jal"); +} + +TEST_F(AssemblerRISCV64Test, Jalr) { + // TODO(riscv64): Change "-11, 2" to "-12, 1" for "C" Standard Extension. + DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Jalr, -12, "jalr {reg1}, {reg2}, {imm}\n"), + "Jalr"); +} + +TEST_F(AssemblerRISCV64Test, Beq) { + // TODO(riscv64): Change "-11, 2" to "-12, 1" for "C" Standard Extension. + DriverStr(RepeatRRIbS(&riscv64::Riscv64Assembler::Beq, -11, 2, "beq {reg1}, {reg2}, {imm}\n"), + "Beq"); +} + +TEST_F(AssemblerRISCV64Test, Bne) { + // TODO(riscv64): Change "-11, 2" to "-12, 1" for "C" Standard Extension. + DriverStr(RepeatRRIbS(&riscv64::Riscv64Assembler::Bne, -11, 2, "bne {reg1}, {reg2}, {imm}\n"), + "Bne"); +} + +TEST_F(AssemblerRISCV64Test, Blt) { + // TODO(riscv64): Change "-11, 2" to "-12, 1" for "C" Standard Extension. + DriverStr(RepeatRRIbS(&riscv64::Riscv64Assembler::Blt, -11, 2, "blt {reg1}, {reg2}, {imm}\n"), + "Blt"); +} + +TEST_F(AssemblerRISCV64Test, Bge) { + // TODO(riscv64): Change "-11, 2" to "-12, 1" for "C" Standard Extension. + DriverStr(RepeatRRIbS(&riscv64::Riscv64Assembler::Bge, -11, 2, "bge {reg1}, {reg2}, {imm}\n"), + "Bge"); +} + +TEST_F(AssemblerRISCV64Test, Bltu) { + // TODO(riscv64): Change "-11, 2" to "-12, 1" for "C" Standard Extension. + DriverStr(RepeatRRIbS(&riscv64::Riscv64Assembler::Bltu, -11, 2, "bltu {reg1}, {reg2}, {imm}\n"), + "Bltu"); +} + +TEST_F(AssemblerRISCV64Test, Bgeu) { + // TODO(riscv64): Change "-11, 2" to "-12, 1" for "C" Standard Extension. + DriverStr(RepeatRRIbS(&riscv64::Riscv64Assembler::Bgeu, -11, 2, "bgeu {reg1}, {reg2}, {imm}\n"), + "Bgeu"); +} + TEST_F(AssemblerRISCV64Test, Lb) { - DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Lb, -11, "lb {reg1}, {imm}({reg2})"), "Lb"); + DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Lb, -12, "lb {reg1}, {imm}({reg2})"), "Lb"); } TEST_F(AssemblerRISCV64Test, Lh) { - DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Lh, -11, "lh {reg1}, {imm}({reg2})"), "Lh"); + DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Lh, -12, "lh {reg1}, {imm}({reg2})"), "Lh"); } TEST_F(AssemblerRISCV64Test, Lw) { - DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Lw, -11, "lw {reg1}, {imm}({reg2})"), "Lw"); + DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Lw, -12, "lw {reg1}, {imm}({reg2})"), "Lw"); } TEST_F(AssemblerRISCV64Test, Ld) { - DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Ld, -11, "ld {reg1}, {imm}({reg2})"), "Ld"); + DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Ld, -12, "ld {reg1}, {imm}({reg2})"), "Ld"); } TEST_F(AssemblerRISCV64Test, Lbu) { - DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Lbu, -11, "lbu {reg1}, {imm}({reg2})"), "Lbu"); + DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Lbu, -12, "lbu {reg1}, {imm}({reg2})"), "Lbu"); } TEST_F(AssemblerRISCV64Test, Lhu) { - DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Lhu, -11, "lhu {reg1}, {imm}({reg2})"), "Lhu"); + DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Lhu, -12, "lhu {reg1}, {imm}({reg2})"), "Lhu"); } TEST_F(AssemblerRISCV64Test, Lwu) { - DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Lwu, -11, "lwu {reg1}, {imm}({reg2})"), "Lwu"); + DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Lwu, -12, "lwu {reg1}, {imm}({reg2})"), "Lwu"); } TEST_F(AssemblerRISCV64Test, Sb) { - DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Sb, -11, "sb {reg1}, {imm}({reg2})"), "Sb"); + DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Sb, -12, "sb {reg1}, {imm}({reg2})"), "Sb"); } TEST_F(AssemblerRISCV64Test, Sh) { - DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Sh, -11, "sh {reg1}, {imm}({reg2})"), "Sh"); + DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Sh, -12, "sh {reg1}, {imm}({reg2})"), "Sh"); } TEST_F(AssemblerRISCV64Test, Sw) { - DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Sw, -11, "sw {reg1}, {imm}({reg2})"), "Sw"); + DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Sw, -12, "sw {reg1}, {imm}({reg2})"), "Sw"); } TEST_F(AssemblerRISCV64Test, Sd) { - DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Sd, -11, "sd {reg1}, {imm}({reg2})"), "Sd"); + DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Sd, -12, "sd {reg1}, {imm}({reg2})"), "Sd"); } TEST_F(AssemblerRISCV64Test, Addi) { - DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Addi, -11, "addi {reg1}, {reg2}, {imm}"), + DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Addi, -12, "addi {reg1}, {reg2}, {imm}"), "Addi"); } TEST_F(AssemblerRISCV64Test, Slti) { - DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Slti, -11, "slti {reg1}, {reg2}, {imm}"), + DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Slti, -12, "slti {reg1}, {reg2}, {imm}"), "Slti"); } TEST_F(AssemblerRISCV64Test, Sltiu) { - DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Sltiu, -11, "sltiu {reg1}, {reg2}, {imm}"), + DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Sltiu, -12, "sltiu {reg1}, {reg2}, {imm}"), "Sltiu"); } @@ -253,11 +309,11 @@ TEST_F(AssemblerRISCV64Test, Xori) { } TEST_F(AssemblerRISCV64Test, Ori) { - DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Ori, -11, "ori {reg1}, {reg2}, {imm}"), "Ori"); + DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Ori, -12, "ori {reg1}, {reg2}, {imm}"), "Ori"); } TEST_F(AssemblerRISCV64Test, Andi) { - DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Andi, -11, "andi {reg1}, {reg2}, {imm}"), + DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Andi, -12, "andi {reg1}, {reg2}, {imm}"), "Andi"); } @@ -314,7 +370,7 @@ TEST_F(AssemblerRISCV64Test, Sra) { } TEST_F(AssemblerRISCV64Test, Addiw) { - DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Addiw, -11, "addiw {reg1}, {reg2}, {imm}"), + DriverStr(RepeatRRIb(&riscv64::Riscv64Assembler::Addiw, -12, "addiw {reg1}, {reg2}, {imm}"), "Addiw"); } @@ -406,11 +462,11 @@ TEST_F(AssemblerRISCV64Test, Remuw) { } TEST_F(AssemblerRISCV64Test, FLw) { - DriverStr(RepeatFRIb(&riscv64::Riscv64Assembler::FLw, -11, "flw {reg1}, {imm}({reg2})"), "FLw"); + DriverStr(RepeatFRIb(&riscv64::Riscv64Assembler::FLw, -12, "flw {reg1}, {imm}({reg2})"), "FLw"); } TEST_F(AssemblerRISCV64Test, FLd) { - DriverStr(RepeatFRIb(&riscv64::Riscv64Assembler::FLd, -11, "fld {reg1}, {imm}({reg2})"), "FLw"); + DriverStr(RepeatFRIb(&riscv64::Riscv64Assembler::FLd, -12, "fld {reg1}, {imm}({reg2})"), "FLw"); } TEST_F(AssemblerRISCV64Test, FSw) { @@ -769,6 +825,93 @@ TEST_F(AssemblerRISCV64Test, FNegD) { "FNegD"); } +TEST_F(AssemblerRISCV64Test, Beqz) { + // TODO(riscv64): Change "-11, 2" to "-12, 1" for "C" Standard Extension. + DriverStr(RepeatRIbS(&riscv64::Riscv64Assembler::Beqz, -11, 2, "beq {reg}, zero, {imm}\n"), + "Beqz"); +} + +TEST_F(AssemblerRISCV64Test, Bnez) { + // TODO(riscv64): Change "-11, 2" to "-12, 1" for "C" Standard Extension. + DriverStr(RepeatRIbS(&riscv64::Riscv64Assembler::Bnez, -11, 2, "bne {reg}, zero, {imm}\n"), + "Bnez"); +} + +TEST_F(AssemblerRISCV64Test, Blez) { + // TODO(riscv64): Change "-11, 2" to "-12, 1" for "C" Standard Extension. + DriverStr(RepeatRIbS(&riscv64::Riscv64Assembler::Blez, -11, 2, "bge zero, {reg}, {imm}\n"), + "Blez"); +} + +TEST_F(AssemblerRISCV64Test, Bgez) { + // TODO(riscv64): Change "-11, 2" to "-12, 1" for "C" Standard Extension. + DriverStr(RepeatRIbS(&riscv64::Riscv64Assembler::Bgez, -11, 2, "bge {reg}, zero, {imm}\n"), + "Bgez"); +} + +TEST_F(AssemblerRISCV64Test, Bltz) { + // TODO(riscv64): Change "-11, 2" to "-12, 1" for "C" Standard Extension. + DriverStr(RepeatRIbS(&riscv64::Riscv64Assembler::Bltz, -11, 2, "blt {reg}, zero, {imm}\n"), + "Bltz"); +} + +TEST_F(AssemblerRISCV64Test, Bgtz) { + // TODO(riscv64): Change "-11, 2" to "-12, 1" for "C" Standard Extension. + DriverStr(RepeatRIbS(&riscv64::Riscv64Assembler::Bgtz, -11, 2, "blt zero, {reg}, {imm}\n"), + "Bgtz"); +} + +TEST_F(AssemblerRISCV64Test, Bgt) { + // TODO(riscv64): Change "-11, 2" to "-12, 1" for "C" Standard Extension. + DriverStr(RepeatRRIbS(&riscv64::Riscv64Assembler::Bgt, -11, 2, "blt {reg2}, {reg1}, {imm}\n"), + "Bgt"); +} + +TEST_F(AssemblerRISCV64Test, Ble) { + // TODO(riscv64): Change "-11, 2" to "-12, 1" for "C" Standard Extension. + DriverStr(RepeatRRIbS(&riscv64::Riscv64Assembler::Ble, -11, 2, "bge {reg2}, {reg1}, {imm}\n"), + "Bge"); +} + +TEST_F(AssemblerRISCV64Test, Bgtu) { + // TODO(riscv64): Change "-11, 2" to "-12, 1" for "C" Standard Extension. + DriverStr(RepeatRRIbS(&riscv64::Riscv64Assembler::Bgtu, -11, 2, "bltu {reg2}, {reg1}, {imm}\n"), + "Bgtu"); +} + +TEST_F(AssemblerRISCV64Test, Bleu) { + // TODO(riscv64): Change "-11, 2" to "-12, 1" for "C" Standard Extension. + DriverStr(RepeatRRIbS(&riscv64::Riscv64Assembler::Bleu, -11, 2, "bgeu {reg2}, {reg1}, {imm}\n"), + "Bgeu"); +} + +TEST_F(AssemblerRISCV64Test, J) { + // TODO(riscv64): Change "-19, 2" to "-20, 1" for "C" Standard Extension. + DriverStr(RepeatIbS<int32_t>(&riscv64::Riscv64Assembler::J, -19, 2, "j {imm}\n"), "J"); +} + +TEST_F(AssemblerRISCV64Test, JalRA) { + // TODO(riscv64): Change "-19, 2" to "-20, 1" for "C" Standard Extension. + DriverStr(RepeatIbS<int32_t>(&riscv64::Riscv64Assembler::Jal, -19, 2, "jal {imm}\n"), "JalRA"); +} + +TEST_F(AssemblerRISCV64Test, Jr) { + DriverStr(RepeatR(&riscv64::Riscv64Assembler::Jr, "jr {reg}\n"), "Jr"); +} + +TEST_F(AssemblerRISCV64Test, JalrRA) { + DriverStr(RepeatR(&riscv64::Riscv64Assembler::Jalr, "jalr {reg}\n"), "JalrRA"); +} + +TEST_F(AssemblerRISCV64Test, Jalr0) { + DriverStr(RepeatRR(&riscv64::Riscv64Assembler::Jalr, "jalr {reg1}, {reg2}\n"), "Jalr0"); +} + +TEST_F(AssemblerRISCV64Test, Ret) { + GetAssembler()->Ret(); + DriverStr("ret\n", "Ret"); +} + #undef __ } // namespace art |