John Brawn | c4ed600 | 2018-07-03 10:10:29 +0000 | [diff] [blame] | 1 | //===-- 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 Chatelet | c96a97b | 2018-09-20 12:22:18 +0000 | [diff] [blame] | 12 | #include "AArch64RegisterInfo.h" |
John Brawn | c4ed600 | 2018-07-03 10:10:29 +0000 | [diff] [blame] | 13 | |
Fangrui Song | 32401af | 2018-10-22 17:10:47 +0000 | [diff] [blame] | 14 | namespace llvm { |
John Brawn | c4ed600 | 2018-07-03 10:10:29 +0000 | [diff] [blame] | 15 | namespace exegesis { |
| 16 | |
Guillaume Chatelet | c96a97b | 2018-09-20 12:22:18 +0000 | [diff] [blame] | 17 | static 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. |
| 28 | static 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 Courbet | eee2e06 | 2018-11-09 13:15:32 +0000 | [diff] [blame^] | 37 | #include "AArch64GenExegesis.inc" |
| 38 | |
| 39 | namespace { |
Guillaume Chatelet | c96a97b | 2018-09-20 12:22:18 +0000 | [diff] [blame] | 40 | |
John Brawn | c4ed600 | 2018-07-03 10:10:29 +0000 | [diff] [blame] | 41 | class ExegesisAArch64Target : public ExegesisTarget { |
Clement Courbet | 41c8af3 | 2018-10-25 07:44:01 +0000 | [diff] [blame] | 42 | public: |
Clement Courbet | eee2e06 | 2018-11-09 13:15:32 +0000 | [diff] [blame^] | 43 | ExegesisAArch64Target() : ExegesisTarget(AArch64CpuPfmCounters) {} |
Clement Courbet | 41c8af3 | 2018-10-25 07:44:01 +0000 | [diff] [blame] | 44 | |
| 45 | private: |
Guillaume Chatelet | 5ad2909 | 2018-09-18 11:26:27 +0000 | [diff] [blame] | 46 | std::vector<llvm::MCInst> setRegTo(const llvm::MCSubtargetInfo &STI, |
Guillaume Chatelet | c96a97b | 2018-09-20 12:22:18 +0000 | [diff] [blame] | 47 | 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 Chatelet | 5ad2909 | 2018-09-18 11:26:27 +0000 | [diff] [blame] | 55 | } |
| 56 | |
John Brawn | c4ed600 | 2018-07-03 10:10:29 +0000 | [diff] [blame] | 57 | bool matchesArch(llvm::Triple::ArchType Arch) const override { |
| 58 | return Arch == llvm::Triple::aarch64 || Arch == llvm::Triple::aarch64_be; |
| 59 | } |
Guillaume Chatelet | c96a97b | 2018-09-20 12:22:18 +0000 | [diff] [blame] | 60 | |
John Brawn | c4ed600 | 2018-07-03 10:10:29 +0000 | [diff] [blame] | 61 | 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 Brawn | c4ed600 | 2018-07-03 10:10:29 +0000 | [diff] [blame] | 65 | }; |
| 66 | |
| 67 | } // namespace |
| 68 | |
| 69 | static ExegesisTarget *getTheExegesisAArch64Target() { |
| 70 | static ExegesisAArch64Target Target; |
| 71 | return &Target; |
| 72 | } |
| 73 | |
| 74 | void InitializeAArch64ExegesisTarget() { |
| 75 | ExegesisTarget::registerTarget(getTheExegesisAArch64Target()); |
| 76 | } |
| 77 | |
| 78 | } // namespace exegesis |
Fangrui Song | 32401af | 2018-10-22 17:10:47 +0000 | [diff] [blame] | 79 | } // namespace llvm |