Skip to content

Commit

Permalink
[LoongArch 4/6] Add basic tablegen infra for LoongArch
Browse files Browse the repository at this point in the history
This patch introduces basic tablegen infra such as
LoongArch{InstrFormats,InstrInfo,RegisterInfo,CallingConv,}.td.

For now, only add instruction definitions for LoongArch basic integer
operations.
Our initial target is a working MC layer rather than codegen,
so appropriate SelectionDAG patterns will come later.

Differential revision: https://reviews.llvm.org/D115861
  • Loading branch information
SixWeining authored and rengolin committed Feb 10, 2022
1 parent 444c6d2 commit 33388ae
Show file tree
Hide file tree
Showing 40 changed files with 2,778 additions and 8 deletions.
21 changes: 21 additions & 0 deletions llvm/lib/Target/LoongArch/CMakeLists.txt
@@ -1,6 +1,27 @@
add_llvm_component_group(LoongArch)

set(LLVM_TARGET_DEFINITIONS LoongArch.td)

tablegen(LLVM LoongArchGenAsmMatcher.inc -gen-asm-matcher)
tablegen(LLVM LoongArchGenAsmWriter.inc -gen-asm-writer)
tablegen(LLVM LoongArchGenRegisterInfo.inc -gen-register-info)
tablegen(LLVM LoongArchGenInstrInfo.inc -gen-instr-info)
tablegen(LLVM LoongArchGenDAGISel.inc -gen-dag-isel)
tablegen(LLVM LoongArchGenMCPseudoLowering.inc -gen-pseudo-lowering)
tablegen(LLVM LoongArchGenMCCodeEmitter.inc -gen-emitter)
tablegen(LLVM LoongArchGenSubtargetInfo.inc -gen-subtarget)

add_public_tablegen_target(LoongArchCommonTableGen)

add_llvm_target(LoongArchCodeGen
LoongArchAsmPrinter.cpp
LoongArchFrameLowering.cpp
LoongArchInstrInfo.cpp
LoongArchISelDAGToDAG.cpp
LoongArchISelLowering.cpp
LoongArchMCInstLower.cpp
LoongArchRegisterInfo.cpp
LoongArchSubtarget.cpp
LoongArchTargetMachine.cpp

LINK_COMPONENTS
Expand Down
37 changes: 37 additions & 0 deletions llvm/lib/Target/LoongArch/LoongArch.h
@@ -0,0 +1,37 @@
//===-- LoongArch.h - Top-level interface for LoongArch ---------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains the entry points for global functions defined in the LLVM
// LoongArch back-end.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCH_H
#define LLVM_LIB_TARGET_LOONGARCH_LOONGARCH_H

#include "llvm/Target/TargetMachine.h"

namespace llvm {
class LoongArchTargetMachine;
class AsmPrinter;
class FunctionPass;
class MCInst;
class MCOperand;
class MachineInstr;
class MachineOperand;

bool lowerLoongArchMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
AsmPrinter &AP);
bool lowerLoongArchMachineOperandToMCOperand(const MachineOperand &MO,
MCOperand &MCOp,
const AsmPrinter &AP);

FunctionPass *createLoongArchISelDag(LoongArchTargetMachine &TM);
} // namespace llvm

#endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCH_H
133 changes: 133 additions & 0 deletions llvm/lib/Target/LoongArch/LoongArch.td
@@ -0,0 +1,133 @@
//===-- LoongArch.td - Describe the LoongArch Target -------*- tablegen -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

include "llvm/Target/Target.td"

//===----------------------------------------------------------------------===//
// LoongArch subtarget features and instruction predicates.
//===----------------------------------------------------------------------===//

// LoongArch is divided into two versions, the 32-bit version (LA32) and the
// 64-bit version (LA64).
def Feature64Bit
: SubtargetFeature<"64bit", "HasLA64", "true",
"LA64 Basic Integer and Privilege Instruction Set">;
def IsLA64
: Predicate<"Subtarget->is64Bit()">,
AssemblerPredicate<(all_of Feature64Bit),
"LA64 Basic Integer and Privilege Instruction Set">;
def IsLA32
: Predicate<"!Subtarget->is64Bit()">,
AssemblerPredicate<(all_of(not Feature64Bit)),
"LA32 Basic Integer and Privilege Instruction Set">;

defvar LA32 = DefaultMode;
def LA64 : HwMode<"+64bit">;

// Single Precision floating point
def FeatureBasicF : SubtargetFeature<"f", "HasBasicF", "true",
"'F' (Single-Precision Floating-Point)">;
def HasBasicF : Predicate<"Subtarget->hasBasicF()">,
AssemblerPredicate<(all_of FeatureBasicF),
"'F' (Single-Precision Floating-Point)">;

// Double Precision floating point
def FeatureBasicD : SubtargetFeature<"d", "HasBasicD", "true",
"'D' (Double-Precision Floating-Point)",
[FeatureBasicF]>;
def HasBasicD : Predicate<"Subtarget->hasBasicD()">,
AssemblerPredicate<(all_of FeatureBasicD),
"'D' (Double-Precision Floating-Point)">;

// Loongson SIMD eXtension (LSX)
def FeatureExtLSX
: SubtargetFeature<"lsx", "HasExtLSX", "true",
"'LSX' (Loongson SIMD Extension)", [FeatureBasicD]>;
def HasExtLSX : Predicate<"Subtarget->hasExtLSX()">,
AssemblerPredicate<(all_of FeatureExtLSX),
"'LSX' (Loongson SIMD Extension)">;

// Loongson Advanced SIMD eXtension (LASX)
def FeatureExtLASX
: SubtargetFeature<"lasx", "HasExtLASX", "true",
"'LASX' (Loongson Advanced SIMD Extension)",
[FeatureExtLSX]>;
def HasExtLASX
: Predicate<"Subtarget->hasExtLASX()">,
AssemblerPredicate<(all_of FeatureExtLASX),
"'LASX' (Loongson Advanced SIMD Extension)">;

// Loongson VirtualiZation (LVZ)
def FeatureExtLVZ
: SubtargetFeature<"lvz", "HasExtLVZ", "true",
"'LVZ' (Loongson Virtualization Extension)">;
def HasExtLVZ : Predicate<"Subtarget->hasExtLVZ()">,
AssemblerPredicate<(all_of FeatureExtLVZ),
"'LVZ' (Loongson Virtualization Extension)">;

// Loongson Binary Translation (LBT)
def FeatureExtLBT
: SubtargetFeature<"lbt", "HasExtLBT", "true",
"'LBT' (Loongson Binary Translation Extension)">;
def HasExtLBT
: Predicate<"Subtarget->hasExtLBT()">,
AssemblerPredicate<(all_of FeatureExtLBT),
"'LBT' (Loongson Binary Translation Extension)">;

//===----------------------------------------------------------------------===//
// Registers, instruction descriptions ...
//===----------------------------------------------------------------------===//

include "LoongArchRegisterInfo.td"
include "LoongArchCallingConv.td"
include "LoongArchInstrInfo.td"

//===----------------------------------------------------------------------===//
// LoongArch processors supported.
//===----------------------------------------------------------------------===//

def : ProcessorModel<"generic-la32", NoSchedModel, []>;
def : ProcessorModel<"generic-la64", NoSchedModel, [Feature64Bit]>;

def : ProcessorModel<"la464", NoSchedModel, [Feature64Bit,
FeatureExtLASX,
FeatureExtLVZ,
FeatureExtLBT]>;

//===----------------------------------------------------------------------===//
// Define the LoongArch target.
//===----------------------------------------------------------------------===//

def LoongArchInstrInfo : InstrInfo {
// guess mayLoad, mayStore, and hasSideEffects
// This option is a temporary migration help. It will go away.
let guessInstructionProperties = 1;
}

def LoongArchAsmParser : AsmParser {
let ShouldEmitMatchRegisterAltName = 1;
let AllowDuplicateRegisterNames = 1;
}

def LoongArchAsmParserVariant : AsmParserVariant {
int Variant = 0;
// Recognize hard coded registers.
string RegisterPrefix = "$";
}

def LoongArchAsmWriter : AsmWriter {
int PassSubtarget = 1;
}

def LoongArch : Target {
let InstructionSet = LoongArchInstrInfo;
let AssemblyParsers = [LoongArchAsmParser];
let AssemblyParserVariants = [LoongArchAsmParserVariant];
let AssemblyWriters = [LoongArchAsmWriter];
let AllowRegisterRenaming = 1;
}
48 changes: 48 additions & 0 deletions llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp
@@ -0,0 +1,48 @@
//===- LoongArchAsmPrinter.cpp - LoongArch LLVM Assembly Printer -*- C++ -*--=//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains a printer that converts from our internal representation
// of machine-dependent LLVM code to GAS-format LoongArch assembly language.
//
//===----------------------------------------------------------------------===//

#include "LoongArchAsmPrinter.h"
#include "LoongArch.h"
#include "LoongArchTargetMachine.h"
#include "TargetInfo/LoongArchTargetInfo.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/MC/TargetRegistry.h"

using namespace llvm;

#define DEBUG_TYPE "loongarch-asm-printer"

// Simple pseudo-instructions have their lowering (with expansion to real
// instructions) auto-generated.
#include "LoongArchGenMCPseudoLowering.inc"

void LoongArchAsmPrinter::emitInstruction(const MachineInstr *MI) {
// Do any auto-generated pseudo lowerings.
if (emitPseudoExpansionLowering(*OutStreamer, MI))
return;

MCInst TmpInst;
if (!lowerLoongArchMachineInstrToMCInst(MI, TmpInst, *this))
EmitToStreamer(*OutStreamer, TmpInst);
}

bool LoongArchAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
AsmPrinter::runOnMachineFunction(MF);
return true;
}

// Force static initialization.
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLoongArchAsmPrinter() {
RegisterAsmPrinter<LoongArchAsmPrinter> X(getTheLoongArch32Target());
RegisterAsmPrinter<LoongArchAsmPrinter> Y(getTheLoongArch64Target());
}
46 changes: 46 additions & 0 deletions llvm/lib/Target/LoongArch/LoongArchAsmPrinter.h
@@ -0,0 +1,46 @@
//===- LoongArchAsmPrinter.h - LoongArch LLVM Assembly Printer -*- C++ -*--===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// LoongArch Assembly printer class.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHASMPRINTER_H
#define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHASMPRINTER_H

#include "LoongArchSubtarget.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/Support/Compiler.h"

namespace llvm {

class LLVM_LIBRARY_VISIBILITY LoongArchAsmPrinter : public AsmPrinter {
const MCSubtargetInfo *STI;

public:
explicit LoongArchAsmPrinter(TargetMachine &TM,
std::unique_ptr<MCStreamer> Streamer)
: AsmPrinter(TM, std::move(Streamer)), STI(TM.getMCSubtargetInfo()) {}

StringRef getPassName() const override {
return "LoongArch Assembly Printer";
}

bool runOnMachineFunction(MachineFunction &MF) override;

void emitInstruction(const MachineInstr *MI) override;

// tblgen'erated function.
bool emitPseudoExpansionLowering(MCStreamer &OutStreamer,
const MachineInstr *MI);
};

} // end namespace llvm

#endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHASMPRINTER_H
23 changes: 23 additions & 0 deletions llvm/lib/Target/LoongArch/LoongArchCallingConv.td
@@ -0,0 +1,23 @@
//=- LoongArchCallingConv.td - Calling Conventions LoongArch -*- tablegen -*-=//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This describes the calling conventions for the LoongArch architecture.
//
//===----------------------------------------------------------------------===//

def CSR_ILP32S_LP64S
: CalleeSavedRegs<(add R1, (sequence "R%u", 22, 31))>;

def CSR_ILP32F_LP64F
: CalleeSavedRegs<(add CSR_ILP32S_LP64S, (sequence "F%u", 24, 31))>;

def CSR_ILP32D_LP64D
: CalleeSavedRegs<(add CSR_ILP32S_LP64S, (sequence "F%u_64", 24, 31))>;

// Needed for implementation of LoongArchRegisterInfo::getNoPreservedMask()
def CSR_NoRegs : CalleeSavedRegs<(add)>;
55 changes: 55 additions & 0 deletions llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp
@@ -0,0 +1,55 @@
//===-- LoongArchFrameLowering.cpp - LoongArch Frame Information -*- C++ -*-==//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains the LoongArch implementation of TargetFrameLowering class.
//
//===----------------------------------------------------------------------===//

#include "LoongArchFrameLowering.h"
#include "LoongArchSubtarget.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RegisterScavenging.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/MC/MCDwarf.h"

using namespace llvm;

#define DEBUG_TYPE "loongarch-frame-lowering"

// Return true if the specified function should have a dedicated frame
// pointer register. This is true if frame pointer elimination is
// disabled, if it needs dynamic stack realignment, if the function has
// variable sized allocas, or if the frame address is taken.
bool LoongArchFrameLowering::hasFP(const MachineFunction &MF) const {
const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();

const MachineFrameInfo &MFI = MF.getFrameInfo();
return MF.getTarget().Options.DisableFramePointerElim(MF) ||
RegInfo->hasStackRealignment(MF) || MFI.hasVarSizedObjects() ||
MFI.isFrameAddressTaken();
}

bool LoongArchFrameLowering::hasBP(const MachineFunction &MF) const {
const MachineFrameInfo &MFI = MF.getFrameInfo();
const TargetRegisterInfo *TRI = STI.getRegisterInfo();

return MFI.hasVarSizedObjects() && TRI->hasStackRealignment(MF);
}

void LoongArchFrameLowering::emitPrologue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
// TODO: Implement this when we have function calls
}

void LoongArchFrameLowering::emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
// TODO: Implement this when we have function calls
}

0 comments on commit 33388ae

Please sign in to comment.