blob: f5cc88c94a9361d1e14ede0631550462f2194fd4 [file] [log] [blame]
John Brawnc4ed6002018-07-03 10:10:29 +00001//===-- Target.cpp ----------------------------------------------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
John Brawnc4ed6002018-07-03 10:10:29 +00006//
7//===----------------------------------------------------------------------===//
8#include "../Target.h"
9#include "../Latency.h"
10#include "AArch64.h"
Guillaume Chateletc96a97b2018-09-20 12:22:18 +000011#include "AArch64RegisterInfo.h"
John Brawnc4ed6002018-07-03 10:10:29 +000012
Fangrui Song32401af2018-10-22 17:10:47 +000013namespace llvm {
John Brawnc4ed6002018-07-03 10:10:29 +000014namespace exegesis {
15
Guillaume Chateletc96a97b2018-09-20 12:22:18 +000016static unsigned getLoadImmediateOpcode(unsigned RegBitWidth) {
17 switch (RegBitWidth) {
18 case 32:
Clement Courbet50cdd562019-10-09 11:58:42 +000019 return AArch64::MOVi32imm;
Guillaume Chateletc96a97b2018-09-20 12:22:18 +000020 case 64:
Clement Courbet50cdd562019-10-09 11:58:42 +000021 return AArch64::MOVi64imm;
Guillaume Chateletc96a97b2018-09-20 12:22:18 +000022 }
23 llvm_unreachable("Invalid Value Width");
24}
25
26// Generates instruction to load an immediate value into a register.
Clement Courbet50cdd562019-10-09 11:58:42 +000027static MCInst loadImmediate(unsigned Reg, unsigned RegBitWidth,
28 const APInt &Value) {
Guillaume Chateletc96a97b2018-09-20 12:22:18 +000029 if (Value.getBitWidth() > RegBitWidth)
30 llvm_unreachable("Value must fit in the Register");
Clement Courbet50cdd562019-10-09 11:58:42 +000031 return MCInstBuilder(getLoadImmediateOpcode(RegBitWidth))
Guillaume Chateletc96a97b2018-09-20 12:22:18 +000032 .addReg(Reg)
33 .addImm(Value.getZExtValue());
34}
35
Clement Courbeteee2e062018-11-09 13:15:32 +000036#include "AArch64GenExegesis.inc"
37
38namespace {
Guillaume Chateletc96a97b2018-09-20 12:22:18 +000039
John Brawnc4ed6002018-07-03 10:10:29 +000040class ExegesisAArch64Target : public ExegesisTarget {
Clement Courbet41c8af32018-10-25 07:44:01 +000041public:
Clement Courbeteee2e062018-11-09 13:15:32 +000042 ExegesisAArch64Target() : ExegesisTarget(AArch64CpuPfmCounters) {}
Clement Courbet41c8af32018-10-25 07:44:01 +000043
44private:
Clement Courbet50cdd562019-10-09 11:58:42 +000045 std::vector<MCInst> setRegTo(const MCSubtargetInfo &STI, unsigned Reg,
46 const APInt &Value) const override {
47 if (AArch64::GPR32RegClass.contains(Reg))
Guillaume Chateletc96a97b2018-09-20 12:22:18 +000048 return {loadImmediate(Reg, 32, Value)};
Clement Courbet50cdd562019-10-09 11:58:42 +000049 if (AArch64::GPR64RegClass.contains(Reg))
Guillaume Chateletc96a97b2018-09-20 12:22:18 +000050 return {loadImmediate(Reg, 64, Value)};
Clement Courbet50cdd562019-10-09 11:58:42 +000051 errs() << "setRegTo is not implemented, results will be unreliable\n";
Guillaume Chateletc96a97b2018-09-20 12:22:18 +000052 return {};
Guillaume Chatelet5ad29092018-09-18 11:26:27 +000053 }
54
Clement Courbet50cdd562019-10-09 11:58:42 +000055 bool matchesArch(Triple::ArchType Arch) const override {
56 return Arch == Triple::aarch64 || Arch == Triple::aarch64_be;
John Brawnc4ed6002018-07-03 10:10:29 +000057 }
Guillaume Chateletc96a97b2018-09-20 12:22:18 +000058
Clement Courbet50cdd562019-10-09 11:58:42 +000059 void addTargetSpecificPasses(PassManagerBase &PM) const override {
John Brawnc4ed6002018-07-03 10:10:29 +000060 // Function return is a pseudo-instruction that needs to be expanded
Clement Courbet50cdd562019-10-09 11:58:42 +000061 PM.add(createAArch64ExpandPseudoPass());
John Brawnc4ed6002018-07-03 10:10:29 +000062 }
John Brawnc4ed6002018-07-03 10:10:29 +000063};
64
65} // namespace
66
67static ExegesisTarget *getTheExegesisAArch64Target() {
68 static ExegesisAArch64Target Target;
69 return &Target;
70}
71
72void InitializeAArch64ExegesisTarget() {
73 ExegesisTarget::registerTarget(getTheExegesisAArch64Target());
74}
75
76} // namespace exegesis
Fangrui Song32401af2018-10-22 17:10:47 +000077} // namespace llvm