blob: d6b6cff54727dd952eca7a69231f3af4e365c2e2 [file] [log] [blame]
John Brawnc4ed6002018-07-03 10:10:29 +00001//===-- Target.cpp ----------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9#include "../Target.h"
10#include "../Latency.h"
11#include "AArch64.h"
Guillaume Chateletc96a97b2018-09-20 12:22:18 +000012#include "AArch64RegisterInfo.h"
John Brawnc4ed6002018-07-03 10:10:29 +000013
Fangrui Song32401af2018-10-22 17:10:47 +000014namespace llvm {
John Brawnc4ed6002018-07-03 10:10:29 +000015namespace exegesis {
16
Guillaume Chateletc96a97b2018-09-20 12:22:18 +000017static unsigned getLoadImmediateOpcode(unsigned RegBitWidth) {
18 switch (RegBitWidth) {
19 case 32:
20 return llvm::AArch64::MOVi32imm;
21 case 64:
22 return llvm::AArch64::MOVi64imm;
23 }
24 llvm_unreachable("Invalid Value Width");
25}
26
27// Generates instruction to load an immediate value into a register.
28static llvm::MCInst loadImmediate(unsigned Reg, unsigned RegBitWidth,
29 const llvm::APInt &Value) {
30 if (Value.getBitWidth() > RegBitWidth)
31 llvm_unreachable("Value must fit in the Register");
32 return llvm::MCInstBuilder(getLoadImmediateOpcode(RegBitWidth))
33 .addReg(Reg)
34 .addImm(Value.getZExtValue());
35}
36
Clement Courbeteee2e062018-11-09 13:15:32 +000037#include "AArch64GenExegesis.inc"
38
39namespace {
Guillaume Chateletc96a97b2018-09-20 12:22:18 +000040
John Brawnc4ed6002018-07-03 10:10:29 +000041class ExegesisAArch64Target : public ExegesisTarget {
Clement Courbet41c8af32018-10-25 07:44:01 +000042public:
Clement Courbeteee2e062018-11-09 13:15:32 +000043 ExegesisAArch64Target() : ExegesisTarget(AArch64CpuPfmCounters) {}
Clement Courbet41c8af32018-10-25 07:44:01 +000044
45private:
Guillaume Chatelet5ad29092018-09-18 11:26:27 +000046 std::vector<llvm::MCInst> setRegTo(const llvm::MCSubtargetInfo &STI,
Guillaume Chateletc96a97b2018-09-20 12:22:18 +000047 unsigned Reg,
48 const llvm::APInt &Value) const override {
49 if (llvm::AArch64::GPR32RegClass.contains(Reg))
50 return {loadImmediate(Reg, 32, Value)};
51 if (llvm::AArch64::GPR64RegClass.contains(Reg))
52 return {loadImmediate(Reg, 64, Value)};
53 llvm::errs() << "setRegTo is not implemented, results will be unreliable\n";
54 return {};
Guillaume Chatelet5ad29092018-09-18 11:26:27 +000055 }
56
John Brawnc4ed6002018-07-03 10:10:29 +000057 bool matchesArch(llvm::Triple::ArchType Arch) const override {
58 return Arch == llvm::Triple::aarch64 || Arch == llvm::Triple::aarch64_be;
59 }
Guillaume Chateletc96a97b2018-09-20 12:22:18 +000060
John Brawnc4ed6002018-07-03 10:10:29 +000061 void addTargetSpecificPasses(llvm::PassManagerBase &PM) const override {
62 // Function return is a pseudo-instruction that needs to be expanded
63 PM.add(llvm::createAArch64ExpandPseudoPass());
64 }
John Brawnc4ed6002018-07-03 10:10:29 +000065};
66
67} // namespace
68
69static ExegesisTarget *getTheExegesisAArch64Target() {
70 static ExegesisAArch64Target Target;
71 return &Target;
72}
73
74void InitializeAArch64ExegesisTarget() {
75 ExegesisTarget::registerTarget(getTheExegesisAArch64Target());
76}
77
78} // namespace exegesis
Fangrui Song32401af2018-10-22 17:10:47 +000079} // namespace llvm