mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-07 11:51:13 +00:00
[llvm-exegesis][mips] Add support for memory instructions
Implementing functions used to enable testing of memory instructions. Differential Revision: https://reviews.llvm.org/D72858
This commit is contained in:
parent
75e355b62f
commit
f27b780153
@ -7,12 +7,44 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
#include "../Target.h"
|
||||
#include "../Latency.h"
|
||||
#include "MCTargetDesc/MipsBaseInfo.h"
|
||||
#include "Mips.h"
|
||||
#include "MipsRegisterInfo.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace exegesis {
|
||||
|
||||
// Returns an error if we cannot handle the memory references in this
|
||||
// instruction.
|
||||
static Error isInvalidMemoryInstr(const Instruction &Instr) {
|
||||
switch (Instr.Description.TSFlags & MipsII::FormMask) {
|
||||
default:
|
||||
return Error::success();
|
||||
llvm_unreachable("Unknown FormMask value");
|
||||
// These have no memory access.
|
||||
case MipsII::Pseudo:
|
||||
case MipsII::FrmR:
|
||||
case MipsII::FrmJ:
|
||||
case MipsII::FrmFR:
|
||||
return Error::success();
|
||||
// These access memory and are handled.
|
||||
case MipsII::FrmI:
|
||||
return Error::success();
|
||||
// These access memory and are not handled yet.
|
||||
case MipsII::FrmFI:
|
||||
case MipsII::FrmOther:
|
||||
return make_error<Failure>("unsupported opcode: non uniform memory access");
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to fill a memory operand with a value.
|
||||
static void setMemOp(InstructionTemplate &IT, int OpIdx,
|
||||
const MCOperand &OpVal) {
|
||||
const auto Op = IT.getInstr().Operands[OpIdx];
|
||||
assert(Op.isExplicit() && "invalid memory pattern");
|
||||
IT.getValueFor(Op) = OpVal;
|
||||
}
|
||||
|
||||
#include "MipsGenExegesis.inc"
|
||||
|
||||
namespace {
|
||||
@ -21,6 +53,11 @@ public:
|
||||
ExegesisMipsTarget() : ExegesisTarget(MipsCpuPfmCounters) {}
|
||||
|
||||
private:
|
||||
unsigned getScratchMemoryRegister(const llvm::Triple &TT) const override;
|
||||
unsigned getMaxMemoryAccessSize() const override { return 64; }
|
||||
void fillMemoryOperands(InstructionTemplate &IT, unsigned Reg,
|
||||
unsigned Offset) const override;
|
||||
|
||||
std::vector<MCInst> setRegTo(const MCSubtargetInfo &STI, unsigned Reg,
|
||||
const APInt &Value) const override;
|
||||
bool matchesArch(Triple::ArchType Arch) const override {
|
||||
@ -92,6 +129,20 @@ static std::vector<MCInst> loadImmediate(unsigned Reg, bool IsGPR32,
|
||||
llvm_unreachable("Not implemented for values wider than 32 bits");
|
||||
}
|
||||
|
||||
unsigned ExegesisMipsTarget::getScratchMemoryRegister(const Triple &TT) const {
|
||||
return TT.isArch64Bit() ? Mips::A0_64 : Mips::A0;
|
||||
}
|
||||
|
||||
void ExegesisMipsTarget::fillMemoryOperands(InstructionTemplate &IT,
|
||||
unsigned Reg,
|
||||
unsigned Offset) const {
|
||||
assert(!isInvalidMemoryInstr(IT.getInstr()) &&
|
||||
"fillMemoryOperands requires a valid memory instruction");
|
||||
setMemOp(IT, 0, MCOperand::createReg(0)); // IndexReg
|
||||
setMemOp(IT, 1, MCOperand::createReg(Reg)); // BaseReg
|
||||
setMemOp(IT, 2, MCOperand::createImm(Offset)); // Disp
|
||||
}
|
||||
|
||||
std::vector<MCInst> ExegesisMipsTarget::setRegTo(const MCSubtargetInfo &STI,
|
||||
unsigned Reg,
|
||||
const APInt &Value) const {
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "MipsInstrInfo.h"
|
||||
#include "RegisterAliasing.h"
|
||||
#include "TestBase.h"
|
||||
#include "Uops.h"
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
@ -22,6 +23,7 @@ namespace {
|
||||
|
||||
using testing::AnyOf;
|
||||
using testing::ElementsAre;
|
||||
using testing::HasSubstr;
|
||||
using testing::SizeIs;
|
||||
|
||||
MATCHER(IsInvalid, "") { return !arg.isValid(); }
|
||||
@ -49,6 +51,8 @@ protected:
|
||||
using LatencySnippetGeneratorTest =
|
||||
SnippetGeneratorTest<LatencySnippetGenerator>;
|
||||
|
||||
using UopsSnippetGeneratorTest = SnippetGeneratorTest<UopsSnippetGenerator>;
|
||||
|
||||
TEST_F(LatencySnippetGeneratorTest, ImplicitSelfDependencyThroughExplicitRegs) {
|
||||
// - ADD
|
||||
// - Op0 Explicit Def RegClass(GPR32)
|
||||
@ -57,6 +61,7 @@ TEST_F(LatencySnippetGeneratorTest, ImplicitSelfDependencyThroughExplicitRegs) {
|
||||
// - Var0 [Op0]
|
||||
// - Var1 [Op1]
|
||||
// - Var2 [Op2]
|
||||
// - hasAliasingRegisters
|
||||
const unsigned Opcode = Mips::ADD;
|
||||
const auto CodeTemplates = checkAndGetCodeTemplates(Opcode);
|
||||
ASSERT_THAT(CodeTemplates, SizeIs(1));
|
||||
@ -81,6 +86,7 @@ TEST_F(LatencySnippetGeneratorTest,
|
||||
// - Var0 [Op0]
|
||||
// - Var1 [Op1]
|
||||
// - Var2 [Op2]
|
||||
// - hasAliasingRegisters
|
||||
randomGenerator().seed(0); // Initialize seed.
|
||||
const Instruction &Instr = State.getIC().getInstr(Mips::XOR);
|
||||
auto AllRegisters = State.getRATC().emptyRegisters();
|
||||
@ -90,6 +96,31 @@ TEST_F(LatencySnippetGeneratorTest,
|
||||
consumeError(std::move(Error));
|
||||
}
|
||||
|
||||
TEST_F(UopsSnippetGeneratorTest, MemoryUse) {
|
||||
// LB reads from memory.
|
||||
// - LB
|
||||
// - Op0 Explicit Def RegClass(GPR32)
|
||||
// - Op1 Explicit Use Memory RegClass(MSA128F16)
|
||||
// - Op2 Explicit Use Memory
|
||||
// - Var0 [Op0]
|
||||
// - Var1 [Op1]
|
||||
// - Var2 [Op2]
|
||||
// - hasMemoryOperands
|
||||
const unsigned Opcode = Mips::LB;
|
||||
const auto CodeTemplates = checkAndGetCodeTemplates(Opcode);
|
||||
ASSERT_THAT(CodeTemplates, SizeIs(1));
|
||||
const auto &CT = CodeTemplates[0];
|
||||
EXPECT_THAT(CT.Info, HasSubstr("instruction is parallel, repeating a random one."));
|
||||
EXPECT_THAT(CT.Execution, ExecutionMode::UNKNOWN);
|
||||
ASSERT_THAT(CT.Instructions,
|
||||
SizeIs(UopsSnippetGenerator::kMinNumDifferentAddresses));
|
||||
const InstructionTemplate &IT = CT.Instructions[0];
|
||||
EXPECT_THAT(IT.getOpcode(), Opcode);
|
||||
ASSERT_THAT(IT.getVariableValues(), SizeIs(3));
|
||||
EXPECT_EQ(IT.getVariableValues()[0].getReg(), 0u);
|
||||
EXPECT_EQ(IT.getVariableValues()[2].getImm(), 0);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace exegesis
|
||||
} // namespace llvm
|
||||
|
Loading…
Reference in New Issue
Block a user