blob: c778b89032cd63d11f23d77f0f5efd42a3dc938d [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"
John Brawnc4ed6002018-07-03 10:10:29 +00009#include "AArch64.h"
Guillaume Chateletc96a97b2018-09-20 12:22:18 +000010#include "AArch64RegisterInfo.h"
John Brawnc4ed6002018-07-03 10:10:29 +000011
Fangrui Song32401af2018-10-22 17:10:47 +000012namespace llvm {
John Brawnc4ed6002018-07-03 10:10:29 +000013namespace exegesis {
14
Guillaume Chateletc96a97b2018-09-20 12:22:18 +000015static unsigned getLoadImmediateOpcode(unsigned RegBitWidth) {
16 switch (RegBitWidth) {
17 case 32:
Clement Courbet50cdd562019-10-09 11:58:42 +000018 return AArch64::MOVi32imm;
Guillaume Chateletc96a97b2018-09-20 12:22:18 +000019 case 64:
Clement Courbet50cdd562019-10-09 11:58:42 +000020 return AArch64::MOVi64imm;
Guillaume Chateletc96a97b2018-09-20 12:22:18 +000021 }
22 llvm_unreachable("Invalid Value Width");
23}
24
25// Generates instruction to load an immediate value into a register.
Clement Courbet50cdd562019-10-09 11:58:42 +000026static MCInst loadImmediate(unsigned Reg, unsigned RegBitWidth,
27 const APInt &Value) {
Guillaume Chateletc96a97b2018-09-20 12:22:18 +000028 if (Value.getBitWidth() > RegBitWidth)
29 llvm_unreachable("Value must fit in the Register");
Clement Courbet50cdd562019-10-09 11:58:42 +000030 return MCInstBuilder(getLoadImmediateOpcode(RegBitWidth))
Guillaume Chateletc96a97b2018-09-20 12:22:18 +000031 .addReg(Reg)
32 .addImm(Value.getZExtValue());
33}
34
Clement Courbeteee2e062018-11-09 13:15:32 +000035#include "AArch64GenExegesis.inc"
36
37namespace {
Guillaume Chateletc96a97b2018-09-20 12:22:18 +000038
John Brawnc4ed6002018-07-03 10:10:29 +000039class ExegesisAArch64Target : public ExegesisTarget {
Clement Courbet41c8af32018-10-25 07:44:01 +000040public:
Clement Courbeteee2e062018-11-09 13:15:32 +000041 ExegesisAArch64Target() : ExegesisTarget(AArch64CpuPfmCounters) {}
Clement Courbet41c8af32018-10-25 07:44:01 +000042
43private:
Clement Courbet50cdd562019-10-09 11:58:42 +000044 std::vector<MCInst> setRegTo(const MCSubtargetInfo &STI, unsigned Reg,
45 const APInt &Value) const override {
46 if (AArch64::GPR32RegClass.contains(Reg))
Guillaume Chateletc96a97b2018-09-20 12:22:18 +000047 return {loadImmediate(Reg, 32, Value)};
Clement Courbet50cdd562019-10-09 11:58:42 +000048 if (AArch64::GPR64RegClass.contains(Reg))
Guillaume Chateletc96a97b2018-09-20 12:22:18 +000049 return {loadImmediate(Reg, 64, Value)};
Clement Courbet50cdd562019-10-09 11:58:42 +000050 errs() << "setRegTo is not implemented, results will be unreliable\n";
Guillaume Chateletc96a97b2018-09-20 12:22:18 +000051 return {};
Guillaume Chatelet5ad29092018-09-18 11:26:27 +000052 }
53
Clement Courbet50cdd562019-10-09 11:58:42 +000054 bool matchesArch(Triple::ArchType Arch) const override {
55 return Arch == Triple::aarch64 || Arch == Triple::aarch64_be;
John Brawnc4ed6002018-07-03 10:10:29 +000056 }
Guillaume Chateletc96a97b2018-09-20 12:22:18 +000057
Clement Courbet50cdd562019-10-09 11:58:42 +000058 void addTargetSpecificPasses(PassManagerBase &PM) const override {
John Brawnc4ed6002018-07-03 10:10:29 +000059 // Function return is a pseudo-instruction that needs to be expanded
Clement Courbet50cdd562019-10-09 11:58:42 +000060 PM.add(createAArch64ExpandPseudoPass());
John Brawnc4ed6002018-07-03 10:10:29 +000061 }
John Brawnc4ed6002018-07-03 10:10:29 +000062};
63
64} // namespace
65
66static ExegesisTarget *getTheExegesisAArch64Target() {
67 static ExegesisAArch64Target Target;
68 return &Target;
69}
70
71void InitializeAArch64ExegesisTarget() {
72 ExegesisTarget::registerTarget(getTheExegesisAArch64Target());
73}
74
75} // namespace exegesis
Fangrui Song32401af2018-10-22 17:10:47 +000076} // namespace llvm