[llvm-exegesis] Improve Register Setup.

Summary:
Added function to set a register to a particular value + tests.
Add EFLAGS test, use new setRegTo instead of setRegToConstant.

Reviewers: courbet, javed.absar

Subscribers: mgorny, tschuett, llvm-commits

Differential Revision: https://reviews.llvm.org/D51856

llvm-svn: 342466
diff --git a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
index fe9d253..90c5927 100644
--- a/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp
@@ -9,6 +9,7 @@
 #include "../Target.h"
 #include "../Latency.h"
 #include "AArch64.h"
+#include "AArch64RegisterInfo.h"
 
 namespace exegesis {
 
@@ -26,33 +27,51 @@
   }
 };
 
+namespace {
+
+static unsigned getLoadImmediateOpcode(unsigned RegBitWidth) {
+  switch (RegBitWidth) {
+  case 32:
+    return llvm::AArch64::MOVi32imm;
+  case 64:
+    return llvm::AArch64::MOVi64imm;
+  }
+  llvm_unreachable("Invalid Value Width");
+}
+
+// Generates instruction to load an immediate value into a register.
+static llvm::MCInst loadImmediate(unsigned Reg, unsigned RegBitWidth,
+                                  const llvm::APInt &Value) {
+  if (Value.getBitWidth() > RegBitWidth)
+    llvm_unreachable("Value must fit in the Register");
+  return llvm::MCInstBuilder(getLoadImmediateOpcode(RegBitWidth))
+      .addReg(Reg)
+      .addImm(Value.getZExtValue());
+}
+
+} // namespace
+
 class ExegesisAArch64Target : public ExegesisTarget {
   std::vector<llvm::MCInst> setRegTo(const llvm::MCSubtargetInfo &STI,
-                                     const llvm::APInt &Value,
-                                     unsigned Reg) const override {
-    llvm_unreachable("Not yet implemented");
-  }
-
-  unsigned getScratchMemoryRegister(const llvm::Triple &) const override {
-    llvm_unreachable("Not yet implemented");
-  }
-
-  void fillMemoryOperands(InstructionBuilder &IB, unsigned Reg,
-                          unsigned Offset) const override {
-    llvm_unreachable("Not yet implemented");
-  }
-
-  unsigned getMaxMemoryAccessSize() const override {
-    llvm_unreachable("Not yet implemented");
+                                     unsigned Reg,
+                                     const llvm::APInt &Value) const override {
+    if (llvm::AArch64::GPR32RegClass.contains(Reg))
+      return {loadImmediate(Reg, 32, Value)};
+    if (llvm::AArch64::GPR64RegClass.contains(Reg))
+      return {loadImmediate(Reg, 64, Value)};
+    llvm::errs() << "setRegTo is not implemented, results will be unreliable\n";
+    return {};
   }
 
   bool matchesArch(llvm::Triple::ArchType Arch) const override {
     return Arch == llvm::Triple::aarch64 || Arch == llvm::Triple::aarch64_be;
   }
+
   void addTargetSpecificPasses(llvm::PassManagerBase &PM) const override {
     // Function return is a pseudo-instruction that needs to be expanded
     PM.add(llvm::createAArch64ExpandPseudoPass());
   }
+
   std::unique_ptr<BenchmarkRunner>
   createLatencyBenchmarkRunner(const LLVMState &State) const override {
     return llvm::make_unique<AArch64LatencyBenchmarkRunner>(State);