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
--- /dev/null
+//===-- 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
--- /dev/null
+//===-- 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;
+}
--- /dev/null
+//===- 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());
+}
--- /dev/null
+//===- 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
--- /dev/null
+//=- 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)>;
--- /dev/null
+//===-- 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
+}
--- /dev/null
+//=- LoongArchFrameLowering.h - TargetFrameLowering 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 class implements LoongArch-specific bits of TargetFrameLowering class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHFRAMELOWERING_H
+#define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHFRAMELOWERING_H
+
+#include "llvm/CodeGen/TargetFrameLowering.h"
+
+namespace llvm {
+class LoongArchSubtarget;
+
+class LoongArchFrameLowering : public TargetFrameLowering {
+ const LoongArchSubtarget &STI;
+
+public:
+ explicit LoongArchFrameLowering(const LoongArchSubtarget &STI)
+ : TargetFrameLowering(StackGrowsDown,
+ /*StackAlignment=*/Align(16),
+ /*LocalAreaOffset=*/0),
+ STI(STI) {}
+
+ void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
+ void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
+
+ bool hasFP(const MachineFunction &MF) const override;
+ bool hasBP(const MachineFunction &MF) const;
+};
+} // namespace llvm
+#endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHFRAMELOWERING_H
--- /dev/null
+//=- LoongArchISelDAGToDAG.cpp - A dag to dag inst selector for LoongArch -===//
+//
+// 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 defines an instruction selector for the LoongArch target.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LoongArchISelDAGToDAG.h"
+#include "MCTargetDesc/LoongArchMCTargetDesc.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "loongarch-isel"
+
+void LoongArchDAGToDAGISel::Select(SDNode *Node) {
+ // If we have a custom node, we have already selected.
+ if (Node->isMachineOpcode()) {
+ LLVM_DEBUG(dbgs() << "== "; Node->dump(CurDAG); dbgs() << "\n");
+ Node->setNodeId(-1);
+ return;
+ }
+
+ // Instruction Selection not handled by the auto-generated tablegen selection
+ // should be handled here.
+ unsigned Opcode = Node->getOpcode();
+ SDLoc DL(Node);
+
+ switch (Opcode) {
+ default:
+ break;
+ // TODO: Add selection nodes needed later.
+ }
+
+ // Select the default instruction.
+ SelectCode(Node);
+}
+// This pass converts a legalized DAG into a LoongArch-specific DAG, ready
+// for instruction scheduling.
+FunctionPass *llvm::createLoongArchISelDag(LoongArchTargetMachine &TM) {
+ return new LoongArchDAGToDAGISel(TM);
+}
--- /dev/null
+//=- LoongArchISelDAGToDAG.h - A dag to dag inst selector for LoongArch ---===//
+//
+// 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 defines an instruction selector for the LoongArch target.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELDAGTODAG_H
+#define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELDAGTODAG_H
+
+#include "LoongArch.h"
+#include "LoongArchTargetMachine.h"
+#include "llvm/CodeGen/SelectionDAGISel.h"
+
+// LoongArch-specific code to select LoongArch machine instructions for
+// SelectionDAG operations.
+namespace llvm {
+class LoongArchDAGToDAGISel : public SelectionDAGISel {
+ const LoongArchSubtarget *Subtarget = nullptr;
+
+public:
+ explicit LoongArchDAGToDAGISel(LoongArchTargetMachine &TM)
+ : SelectionDAGISel(TM) {}
+
+ StringRef getPassName() const override {
+ return "LoongArch DAG->DAG Pattern Instruction Selection";
+ }
+
+ bool runOnMachineFunction(MachineFunction &MF) override {
+ Subtarget = &MF.getSubtarget<LoongArchSubtarget>();
+ return SelectionDAGISel::runOnMachineFunction(MF);
+ }
+
+ void Select(SDNode *Node) override;
+
+// Include the pieces autogenerated from the target description.
+#include "LoongArchGenDAGISel.inc"
+};
+
+} // namespace llvm
+
+#endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELDAGTODAG_H
--- /dev/null
+//=- LoongArchISelLowering.cpp - LoongArch DAG Lowering Implementation ---===//
+//
+// 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 defines the interfaces that LoongArch uses to lower LLVM code into
+// a selection DAG.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LoongArchISelLowering.h"
+#include "LoongArch.h"
+#include "LoongArchMachineFunctionInfo.h"
+#include "LoongArchRegisterInfo.h"
+#include "LoongArchSubtarget.h"
+#include "LoongArchTargetMachine.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Support/Debug.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "loongarch-isel-lowering"
+
+LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
+ const LoongArchSubtarget &STI)
+ : TargetLowering(TM), Subtarget(STI) {
+
+ MVT GRLenVT = Subtarget.getGRLenVT();
+ // Set up the register classes.
+ addRegisterClass(GRLenVT, &LoongArch::GPRRegClass);
+
+ // TODO: add necessary setOperationAction calls later.
+
+ // Compute derived properties from the register classes.
+ computeRegisterProperties(STI.getRegisterInfo());
+
+ setStackPointerRegisterToSaveRestore(LoongArch::R3);
+
+ // Function alignments.
+ const Align FunctionAlignment(4);
+ setMinFunctionAlignment(FunctionAlignment);
+}
--- /dev/null
+//=- LoongArchISelLowering.h - LoongArch DAG Lowering Interface -*- 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 defines the interfaces that LoongArch uses to lower LLVM code into
+// a selection DAG.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELLOWERING_H
+#define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELLOWERING_H
+
+#include "LoongArch.h"
+#include "llvm/CodeGen/CallingConvLower.h"
+#include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/CodeGen/TargetLowering.h"
+
+namespace llvm {
+class LoongArchSubtarget;
+struct LoongArchRegisterInfo;
+namespace LoongArchISD {
+enum NodeType : unsigned {
+ FIRST_NUMBER = ISD::BUILTIN_OP_END,
+
+ // TODO: add more LoongArchISDs
+
+};
+} // namespace LoongArchISD
+
+class LoongArchTargetLowering : public TargetLowering {
+ const LoongArchSubtarget &Subtarget;
+
+public:
+ explicit LoongArchTargetLowering(const TargetMachine &TM,
+ const LoongArchSubtarget &STI);
+
+ const LoongArchSubtarget &getSubtarget() const { return Subtarget; }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELLOWERING_H
--- /dev/null
+//===- LoongArchInstrFormats.td - LoongArch Instr. Formats -*- 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
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Describe LoongArch instructions format
+//
+// opcode - operation code.
+// {r/f}d - destination operand.
+// {r/f}{j/k/a} - source operand.
+// immN - immediate data.
+//
+//===----------------------------------------------------------------------===//
+
+class LAInst<dag outs, dag ins, string asmstr, list<dag> pattern = []>
+ : Instruction {
+ field bits<32> Inst;
+ // SoftFail is a field the disassembler can use to provide a way for
+ // instructions to not match without killing the whole decode process. It is
+ // mainly used for ARM, but Tablegen expects this field to exist or it fails
+ // to build the decode table.
+ field bits<32> SoftFail = 0;
+
+ let Namespace = "LoongArch";
+ let Size = 4;
+ let OutOperandList = outs;
+ let InOperandList = ins;
+ let AsmString = asmstr;
+ let Pattern = pattern;
+}
+
+// Pseudo instructions
+class Pseudo<dag outs, dag ins, string asmstr> : LAInst<outs, ins, asmstr> {
+ let isPseudo = 1;
+}
+
+// 2R-type
+// <opcode | rj | rd>
+class Fmt2R<bits<22> op, dag outs, dag ins, string asmstr,
+ list<dag> pattern = []> : LAInst<outs, ins, asmstr, pattern> {
+ bits<5> rj;
+ bits<5> rd;
+
+ let Inst{31-10} = op;
+ let Inst{9-5} = rj;
+ let Inst{4-0} = rd;
+}
+
+// 3R-type
+// <opcode | rk | rj | rd>
+// <opcode | fk | fj | fd>
+class Fmt3R<bits<17> op, dag outs, dag ins, string asmstr,
+ list<dag> pattern = []> : LAInst<outs, ins, asmstr, pattern> {
+ bits<5> rk;
+ bits<5> rj;
+ bits<5> rd;
+
+ let Inst{31-15} = op;
+ let Inst{14-10} = rk;
+ let Inst{9-5} = rj;
+ let Inst{4-0} = rd;
+}
+
+class Fmt3FR<bits<17> op, dag outs, dag ins, string asmstr,
+ list<dag> pattern = []> : LAInst<outs, ins, asmstr, pattern> {
+ bits<5> fk;
+ bits<5> fj;
+ bits<5> fd;
+
+ let Inst{31-15} = op;
+ let Inst{14-10} = fk;
+ let Inst{9-5} = fj;
+ let Inst{4-0} = fd;
+}
+
+// 4R-type
+// <opcode | ra | rk | rj | rd>
+class Fmt4R<bits<12> op, dag outs, dag ins, string asmstr,
+ list<dag> pattern = []> : LAInst<outs, ins, asmstr, pattern> {
+ bits<5> ra;
+ bits<5> rk;
+ bits<5> rj;
+ bits<5> rd;
+
+ let Inst{31-20} = op;
+ let Inst{19-15} = ra;
+ let Inst{14-10} = rk;
+ let Inst{9-5} = rj;
+ let Inst{4-0} = rd;
+}
+
+// 3RI2-type
+// <opcode | I2 | rk | rj | rd>
+class Fmt3RI2<bits<15> op, dag outs, dag ins, string asmstr,
+ list<dag> pattern = []> : LAInst<outs, ins, asmstr, pattern> {
+ bits<2> imm2;
+ bits<5> rk;
+ bits<5> rj;
+ bits<5> rd;
+
+ let Inst{31-17} = op;
+ let Inst{16-15} = imm2;
+ let Inst{14-10} = rk;
+ let Inst{9-5} = rj;
+ let Inst{4-0} = rd;
+}
+
+// 3RI3-type
+// <opcode | I3 | rk | rj | rd>
+class Fmt3RI3<bits<14> op, dag outs, dag ins, string asmstr,
+ list<dag> pattern = []> : LAInst<outs, ins, asmstr, pattern> {
+ bits<3> imm3;
+ bits<5> rk;
+ bits<5> rj;
+ bits<5> rd;
+
+ let Inst{31-18} = op;
+ let Inst{17-15} = imm3;
+ let Inst{14-10} = rk;
+ let Inst{9-5} = rj;
+ let Inst{4-0} = rd;
+}
+
+// 2RI5-type
+// <opcode | I5 | rj | rd>
+class Fmt2RI5<bits<17> op, dag outs, dag ins, string asmstr,
+ list<dag> pattern = []> : LAInst<outs, ins, asmstr, pattern> {
+ bits<5> imm5;
+ bits<5> rj;
+ bits<5> rd;
+
+ let Inst{31-15} = op;
+ let Inst{14-10} = imm5;
+ let Inst{9-5} = rj;
+ let Inst{4-0} = rd;
+}
+
+// 2RI6-type
+// <opcode | I6 | rj | rd>
+class Fmt2RI6<bits<16> op, dag outs, dag ins, string asmstr,
+ list<dag> pattern = []> : LAInst<outs, ins, asmstr, pattern> {
+ bits<6> imm6;
+ bits<5> rj;
+ bits<5> rd;
+
+ let Inst{31-16} = op;
+ let Inst{15-10} = imm6;
+ let Inst{9-5} = rj;
+ let Inst{4-0} = rd;
+}
+
+// 2RI8-type
+// <opcode | I8 | rj | rd>
+class Fmt2RI8<bits<14> op, dag outs, dag ins, string asmstr,
+ list<dag> pattern = []> : LAInst<outs, ins, asmstr, pattern> {
+ bits<8> imm8;
+ bits<5> rj;
+ bits<5> rd;
+
+ let Inst{31-18} = op;
+ let Inst{17-10} = imm8;
+ let Inst{9-5} = rj;
+ let Inst{4-0} = rd;
+}
+
+// 2RI12-type
+// <opcode | I12 | rj | rd>
+class Fmt2RI12<bits<10> op, dag outs, dag ins, string asmstr,
+ list<dag> pattern = []> : LAInst<outs, ins, asmstr, pattern> {
+ bits<12> imm12;
+ bits<5> rj;
+ bits<5> rd;
+
+ let Inst{31-22} = op;
+ let Inst{21-10} = imm12;
+ let Inst{9-5} = rj;
+ let Inst{4-0} = rd;
+}
+
+// 2RI14-type
+// <opcode | I14 | rj | rd>
+class Fmt2RI14<bits<8> op, dag outs, dag ins, string asmstr,
+ list<dag> pattern = []> : LAInst<outs, ins, asmstr, pattern> {
+ bits<14> imm14;
+ bits<5> rj;
+ bits<5> rd;
+
+ let Inst{31-24} = op;
+ let Inst{23-10} = imm14;
+ let Inst{9-5} = rj;
+ let Inst{4-0} = rd;
+}
+
+// 2RI16-type
+// <opcode | I16 | rj | rd>
+class Fmt2RI16<bits<6> op, dag outs, dag ins, string asmstr,
+ list<dag> pattern = []> : LAInst<outs, ins, asmstr, pattern> {
+ bits<16> imm16;
+ bits<5> rj;
+ bits<5> rd;
+
+ let Inst{31-26} = op;
+ let Inst{25-10} = imm16;
+ let Inst{9-5} = rj;
+ let Inst{4-0} = rd;
+}
+
+// 1RI20-type
+// <opcode | I20 | rd>
+class Fmt1RI20<bits<7> op, dag outs, dag ins, string asmstr,
+ list<dag> pattern = []> : LAInst<outs, ins, asmstr, pattern> {
+ bits<20> imm20;
+ bits<5> rd;
+
+ let Inst{31-25} = op;
+ let Inst{24-5} = imm20;
+ let Inst{4-0} = rd;
+}
+
+// 1RI21-type
+// <opcode | I21[15:0] | rj | I21[20:16]>
+class Fmt1RI21<bits<6> op, dag outs, dag ins, string asmstr,
+ list<dag> pattern = []> : LAInst<outs, ins, asmstr, pattern> {
+ bits<21> imm21;
+ bits<5> rj;
+
+ let Inst{31-26} = op;
+ let Inst{25-10} = imm21{15-0};
+ let Inst{9-5} = rj;
+ let Inst{4-0} = imm21{20-16};
+}
+
+// I15-type
+// <opcode | I15>
+class FmtI15<bits<17> op, dag outs, dag ins, string asmstr,
+ list<dag> pattern = []> : LAInst<outs, ins, asmstr, pattern> {
+ bits<15> imm15;
+
+ let Inst{31-15} = op;
+ let Inst{14-0} = imm15;
+}
+
+// I26-type
+// <opcode | I26[15:0] | I26[25:16]>
+class FmtI26<bits<6> op, dag outs, dag ins, string asmstr,
+ list<dag> pattern = []> : LAInst<outs, ins, asmstr, pattern> {
+ bits<26> imm26;
+
+ let Inst{31-26} = op;
+ let Inst{25-10} = imm26{15-0};
+ let Inst{9-0} = imm26{25-16};
+}
+
+// FmtBSTR_W
+// <opcode[11:1] | msb | opcode[0] | lsb | rj | rd>
+class FmtBSTR_W<bits<12> op, dag outs, dag ins, string asmstr,
+ list<dag> pattern = []> : LAInst<outs, ins, asmstr, pattern> {
+ bits<5> msb;
+ bits<5> lsb;
+ bits<5> rj;
+ bits<5> rd;
+
+ let Inst{31-21} = op{11-1};
+ let Inst{20-16} = msb;
+ let Inst{15} = op{0};
+ let Inst{14-10} = lsb;
+ let Inst{9-5} = rj;
+ let Inst{4-0} = rd;
+}
+
+// FmtBSTR_D
+// <opcode | msb | lsb | rj | rd>
+class FmtBSTR_D<bits<10> op, dag outs, dag ins, string asmstr,
+ list<dag> pattern = []> : LAInst<outs, ins, asmstr, pattern> {
+ bits<6> msb;
+ bits<6> lsb;
+ bits<5> rj;
+ bits<5> rd;
+
+ let Inst{31-22} = op;
+ let Inst{21-16} = msb;
+ let Inst{15-10} = lsb;
+ let Inst{9-5} = rj;
+ let Inst{4-0} = rd;
+}
+
+// FmtASRT
+// <opcode | rk | rj | 0x0>
+class FmtASRT<bits<17> op, dag outs, dag ins, string asmstr,
+ list<dag> pattern = []> : LAInst<outs, ins, asmstr, pattern> {
+ bits<5> rk;
+ bits<5> rj;
+
+ let Inst{31-15} = op;
+ let Inst{14-10} = rk;
+ let Inst{9-5} = rj;
+ let Inst{4-0} = 0x0;
+}
+
+// FmtPRELD
+// < 0b0010101011 | I12 | rj | I5>
+class FmtPRELD<dag outs, dag ins, string asmstr,
+ list<dag> pattern = []> : LAInst<outs, ins, asmstr, pattern> {
+ bits<12> imm12;
+ bits<5> rj;
+ bits<5> imm5;
+
+ let Inst{31-22} = 0b0010101011;
+ let Inst{21-10} = imm12;
+ let Inst{9-5} = rj;
+ let Inst{4-0} = imm5;
+}
+
+// FmtPRELDX
+// < 0b00111000001011000 | rk | rj | I5>
+class FmtPRELDX<dag outs, dag ins, string asmstr,
+ list<dag> pattern = []> : LAInst<outs, ins, asmstr, pattern> {
+ bits<5> rk;
+ bits<5> rj;
+ bits<5> imm5;
+
+ let Inst{31-15} = 0b00111000001011000;
+ let Inst{14-10} = rk;
+ let Inst{9-5} = rj;
+ let Inst{4-0} = imm5;
+}
--- /dev/null
+//=- LoongArchInstrInfo.cpp - LoongArch Instruction 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 the TargetInstrInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LoongArchInstrInfo.h"
+
+using namespace llvm;
+
+#define GET_INSTRINFO_CTOR_DTOR
+#include "LoongArchGenInstrInfo.inc"
+
+LoongArchInstrInfo::LoongArchInstrInfo(LoongArchSubtarget &STI)
+ // FIXME: add CFSetup and CFDestroy Inst when we implement function call.
+ : LoongArchGenInstrInfo(),
+
+ STI(STI) {}
--- /dev/null
+//=- LoongArchInstrInfo.h - LoongArch Instruction 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 the TargetInstrInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHINSTRINFO_H
+#define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHINSTRINFO_H
+
+#include "llvm/CodeGen/TargetInstrInfo.h"
+
+#define GET_INSTRINFO_HEADER
+#include "LoongArchGenInstrInfo.inc"
+
+namespace llvm {
+
+class LoongArchSubtarget;
+
+class LoongArchInstrInfo : public LoongArchGenInstrInfo {
+ const LoongArchSubtarget &STI;
+
+public:
+ explicit LoongArchInstrInfo(LoongArchSubtarget &STI);
+};
+
+} // end namespace llvm
+#endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHINSTRINFO_H
--- /dev/null
+//== LoongArchInstrInfo.td - Target Description for 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 file describes the LoongArch instructions in TableGen format.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// LoongArch specific DAG Nodes.
+//===----------------------------------------------------------------------===//
+
+// TODO: Add LoongArch specific DAG Nodes
+
+//===----------------------------------------------------------------------===//
+// Operand and SDNode transformation definitions.
+//===----------------------------------------------------------------------===//
+class ImmAsmOperand<string prefix, int width, string suffix> : AsmOperandClass {
+ let Name = prefix # "Imm" # width # suffix;
+ let DiagnosticType = !strconcat("Invalid", Name);
+}
+
+class SImmAsmOperand<int width, string suffix = "">
+ : ImmAsmOperand<"S", width, suffix> {
+}
+
+class UImmAsmOperand<int width, string suffix = "">
+ : ImmAsmOperand<"U", width, suffix> {
+}
+
+def uimm2 : Operand<GRLenVT>;
+def uimm2_plus1 : Operand<GRLenVT>;
+def uimm3 : Operand<GRLenVT>;
+def uimm5 : Operand<GRLenVT>;
+def uimm6 : Operand<GRLenVT>;
+def uimm12 : Operand<GRLenVT>;
+def uimm15 : Operand<GRLenVT>;
+def simm12 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isInt<12>(Imm);}]>;
+def simm14 : Operand<GRLenVT>;
+def simm14_lsl2 : Operand<GRLenVT>;
+def simm16 : Operand<GRLenVT>;
+def simm16_lsl2 : Operand<GRLenVT>;
+def simm20 : Operand<GRLenVT>;
+def simm21_lsl2 : Operand<GRLenVT>;
+def simm26_lsl2 : Operand<GRLenVT>;
+
+//===----------------------------------------------------------------------===//
+// Instruction Formats
+//===----------------------------------------------------------------------===//
+
+include "LoongArchInstrFormats.td"
+
+//===----------------------------------------------------------------------===//
+// Instruction Class Templates
+//===----------------------------------------------------------------------===//
+class ALU_3R<bits<17> op, string opstr>
+ : Fmt3R<op, (outs GPR:$rd), (ins GPR:$rj, GPR:$rk),
+ !strconcat(opstr, "\t$rd, $rj, $rk")>;
+class ALU_2R<bits<22> op, string opstr>
+ : Fmt2R<op, (outs GPR:$rd), (ins GPR:$rj),
+ !strconcat(opstr, "\t$rd, $rj")>;
+
+class ALU_3RI2<bits<15> op, string opstr, Operand ImmOpnd>
+ : Fmt3RI2<op, (outs GPR:$rd), (ins GPR:$rj, GPR:$rk, ImmOpnd:$imm2),
+ !strconcat(opstr, "\t$rd, $rj, $rk, $imm2")>;
+class ALU_3RI3<bits<14> op, string opstr, Operand ImmOpnd>
+ : Fmt3RI3<op, (outs GPR:$rd), (ins GPR:$rj, GPR:$rk, ImmOpnd:$imm3),
+ !strconcat(opstr, "\t$rd, $rj, $rk, $imm3")>;
+class ALU_2RI5<bits<17> op, string opstr, Operand ImmOpnd>
+ : Fmt2RI5<op, (outs GPR:$rd), (ins GPR:$rj, ImmOpnd:$imm5),
+ !strconcat(opstr, "\t$rd, $rj, $imm5")>;
+class ALU_2RI6<bits<16> op, string opstr, Operand ImmOpnd>
+ : Fmt2RI6<op, (outs GPR:$rd), (ins GPR:$rj, ImmOpnd:$imm6),
+ !strconcat(opstr, "\t$rd, $rj, $imm6")>;
+class ALU_2RI12<bits<10> op, string opstr, Operand ImmOpnd>
+ : Fmt2RI12<op, (outs GPR:$rd), (ins GPR:$rj, ImmOpnd:$imm12),
+ !strconcat(opstr, "\t$rd, $rj, $imm12")>;
+class ALU_2RI16<bits<6> op, string opstr, Operand ImmOpnd>
+ : Fmt2RI16<op, (outs GPR:$rd), (ins GPR:$rj, ImmOpnd:$imm16),
+ !strconcat(opstr, "\t$rd, $rj, $imm16")>;
+class ALU_1RI20<bits<7> op, string opstr, Operand ImmOpnd>
+ : Fmt1RI20<op, (outs GPR:$rd), (ins ImmOpnd:$imm20),
+ !strconcat(opstr, "\t$rd, $imm20")>;
+
+class ALU_BSTRW<bits<12> op, string opstr, Operand ImmOpnd>
+ : FmtBSTR_W<op, (outs GPR:$rd), (ins GPR:$rj, ImmOpnd:$msb, ImmOpnd:$lsb),
+ !strconcat(opstr, "\t$rd, $rj, $msb, $lsb")>;
+class ALU_BSTRD<bits<10> op, string opstr, Operand ImmOpnd>
+ : FmtBSTR_D<op, (outs GPR:$rd), (ins GPR:$rj, ImmOpnd:$msb, ImmOpnd:$lsb),
+ !strconcat(opstr, "\t$rd, $rj, $msb, $lsb")>;
+
+class MISC_I15<bits<17> op, string opstr>
+ : FmtI15<op, (outs), (ins uimm15:$imm15), !strconcat(opstr, "\t$imm15")>;
+
+class RDTIME_2R<bits<22> op, string opstr>
+ : Fmt2R<op, (outs GPR:$rd, GPR:$rj), (ins),
+ !strconcat(opstr, "\t$rd, $rj")>;
+
+class BrCC_2RI16<bits<6> op, string opstr>
+ : Fmt2RI16<op, (outs), (ins GPR:$rj, GPR:$rd, simm16_lsl2:$imm16),
+ !strconcat(opstr, "\t$rj, $rd, $imm16")> {
+ let isBranch = 1;
+ let isTerminator = 1;
+}
+class BrCCZ_1RI21<bits<6> op, string opstr>
+ : Fmt1RI21<op, (outs), (ins GPR:$rj, simm21_lsl2:$imm21),
+ !strconcat(opstr, "\t$rj, $imm21")> {
+ let isBranch = 1;
+ let isTerminator = 1;
+}
+class Br_I26<bits<6> op, string opstr>
+ : FmtI26<op, (outs), (ins simm26_lsl2:$imm26),
+ !strconcat(opstr, "\t$imm26")> {
+ let isBranch = 1;
+ let isTerminator = 1;
+}
+
+let mayLoad = 1 in {
+class LOAD_3R<bits<17> op, string opstr>
+ : Fmt3R<op, (outs GPR:$rd), (ins GPR:$rj, GPR:$rk),
+ !strconcat(opstr, "\t$rd, $rj, $rk")>;
+class LOAD_2RI12<bits<10> op, string opstr>
+ : Fmt2RI12<op, (outs GPR:$rd), (ins GPR:$rj, simm12:$imm12),
+ !strconcat(opstr, "\t$rd, $rj, $imm12")>;
+class LOAD_2RI14<bits<8> op, string opstr>
+ : Fmt2RI14<op, (outs GPR:$rd), (ins GPR:$rj, simm14_lsl2:$imm14),
+ !strconcat(opstr, "\t$rd, $rj, $imm14")>;
+} // mayLoad = 1
+
+let mayStore = 1 in {
+class STORE_3R<bits<17> op, string opstr>
+ : Fmt3R<op, (outs), (ins GPR:$rd, GPR:$rj, GPR:$rk),
+ !strconcat(opstr, "\t$rd, $rj, $rk")>;
+class STORE_2RI12<bits<10> op, string opstr>
+ : Fmt2RI12<op, (outs), (ins GPR:$rd, GPR:$rj, simm12:$imm12),
+ !strconcat(opstr, "\t$rd, $rj, $imm12")>;
+class STORE_2RI14<bits<8> op, string opstr>
+ : Fmt2RI14<op, (outs), (ins GPR:$rd, GPR:$rj, simm14_lsl2:$imm14),
+ !strconcat(opstr, "\t$rd, $rj, $imm14")>;
+} // mayStore = 1
+
+let mayLoad = 1, mayStore = 1 in
+class AM_3R<bits<17> op, string opstr>
+ : Fmt3R<op, (outs GPR:$rd), (ins GPR:$rj, GPR:$rk),
+ !strconcat(opstr, "\t$rd, $rj, $rk")>;
+
+let mayLoad = 1 in
+class LLBase<bits<8> op, string opstr>
+ : Fmt2RI14<op, (outs GPR:$rd), (ins GPR:$rj, simm14:$imm14),
+ !strconcat(opstr, "\t$rd, $rj, $imm14")>;
+
+let mayStore = 1, Constraints = "$rd = $dst" in
+class SCBase<bits<8> op, string opstr>
+ : Fmt2RI14<op, (outs GPR:$dst), (ins GPR:$rd, GPR:$rj, simm14:$imm14),
+ !strconcat(opstr, "\t$rd, $rj, $imm14")>;
+
+//===----------------------------------------------------------------------===//
+// Instructions
+//===----------------------------------------------------------------------===//
+
+// Arithmetic Operation Instructions
+def ADD_W : ALU_3R<0b00000000000100000, "add.w">;
+def SUB_W : ALU_3R<0b00000000000100010, "sub.w">;
+def ADDI_W : ALU_2RI12<0b0000001010, "addi.w", simm12>;
+def ALSL_W : ALU_3RI2<0b000000000000010, "alsl.w", uimm2_plus1>;
+def LU12I_W : ALU_1RI20<0b0001010, "lu12i.w", simm20>;
+def SLT : ALU_3R<0b00000000000100100, "slt">;
+def SLTU : ALU_3R<0b00000000000100101, "sltu">;
+def SLTI : ALU_2RI12<0b0000001000, "slti", simm12>;
+def SLTUI : ALU_2RI12<0b0000001001, "sltui", simm12>;
+def PCADDI : ALU_1RI20<0b0001100, "pcaddi", simm20>;
+def PCADDU12I : ALU_1RI20<0b0001110, "pcaddu12i", simm20>;
+def PCALAU12I : ALU_1RI20<0b0001101, "pcalau12i", simm20>;
+def AND : ALU_3R<0b00000000000101001, "and">;
+def OR : ALU_3R<0b00000000000101010, "or">;
+def NOR : ALU_3R<0b00000000000101000, "nor">;
+def XOR : ALU_3R<0b00000000000101011, "xor">;
+def ANDN : ALU_3R<0b00000000000101101, "andn">;
+def ORN : ALU_3R<0b00000000000101100, "orn">;
+def ANDI : ALU_2RI12<0b0000001101, "andi", uimm12>;
+def ORI : ALU_2RI12<0b0000001110, "ori", uimm12>;
+def XORI : ALU_2RI12<0b0000001111, "xori", uimm12>;
+def MUL_W : ALU_3R<0b00000000000111000, "mul.w">;
+def MULH_W : ALU_3R<0b00000000000111001, "mulh.w">;
+def MULH_WU : ALU_3R<0b00000000000111010, "mulh.wu">;
+def DIV_W : ALU_3R<0b00000000001000000, "div.w">;
+def MOD_W : ALU_3R<0b00000000001000001, "mod.w">;
+def DIV_WU : ALU_3R<0b00000000001000010, "div.wu">;
+def MOD_WU : ALU_3R<0b00000000001000011, "mod.wu">;
+
+// Bit-shift Instructions
+def SLL_W : ALU_3R<0b00000000000101110, "sll.w">;
+def SRL_W : ALU_3R<0b00000000000101111, "srl.w">;
+def SRA_W : ALU_3R<0b00000000000110000, "sra.w">;
+def ROTR_W : ALU_3R<0b00000000000110110, "rotr.w">;
+
+def SLLI_W : ALU_2RI5<0b00000000010000001, "slli.w", uimm5>;
+def SRLI_W : ALU_2RI5<0b00000000010001001, "srli.w", uimm5>;
+def SRAI_W : ALU_2RI5<0b00000000010010001, "srai.w", uimm5>;
+def ROTRI_W : ALU_2RI5<0b00000000010011001, "rotri.w", uimm5>;
+
+// Bit-manipulation Instructions
+def EXT_W_B : ALU_2R<0b0000000000000000010111, "ext.w.b">;
+def EXT_W_H : ALU_2R<0b0000000000000000010110, "ext.w.h">;
+def CLO_W : ALU_2R<0b0000000000000000000100, "clo.w">;
+def CLZ_W : ALU_2R<0b0000000000000000000101, "clz.w">;
+def CTO_W : ALU_2R<0b0000000000000000000110, "cto.w">;
+def CTZ_W : ALU_2R<0b0000000000000000000111, "ctz.w">;
+def BYTEPICK_W : ALU_3RI2<0b000000000000100, "bytepick.w", uimm2>;
+def REVB_2H : ALU_2R<0b0000000000000000001100, "revb.2h">;
+def BITREV_4B : ALU_2R<0b0000000000000000010010, "bitrev.4b">;
+def BITREV_W : ALU_2R<0b0000000000000000010100, "bitrev.w">;
+def BSTRINS_W : ALU_BSTRW<0b000000000110, "bstrins.w", uimm5>;
+def BSTRPICK_W : ALU_BSTRW<0b000000000111, "bstrpick.w", uimm5>;
+def MASKEQZ : ALU_3R<0b00000000000100110, "maskeqz">;
+def MASKNEZ : ALU_3R<0b00000000000100111, "masknez">;
+
+// Branch Instructions
+def BEQ : BrCC_2RI16<0b010110, "beq">;
+def BNE : BrCC_2RI16<0b010111, "bne">;
+def BLT : BrCC_2RI16<0b011000, "blt">;
+def BGE : BrCC_2RI16<0b011001, "bge">;
+def BLTU : BrCC_2RI16<0b011010, "bltu">;
+def BGEU : BrCC_2RI16<0b011011, "bgeu">;
+def BEQZ : BrCCZ_1RI21<0b010000, "beqz">;
+def BNEZ : BrCCZ_1RI21<0b010001, "bnez">;
+def B : Br_I26<0b010100, "b">;
+
+let isCall = 1 in
+def BL : FmtI26<0b010101, (outs), (ins simm26_lsl2:$imm26), "bl\t$imm26">;
+def JIRL : Fmt2RI16<0b010011, (outs GPR:$rd),
+ (ins GPR:$rj, simm16_lsl2:$imm16),
+ "jirl\t$rd, $rj, $imm16">;
+
+// Common Memory Access Instructions
+def LD_B : LOAD_2RI12<0b0010100000, "ld.b">;
+def LD_H : LOAD_2RI12<0b0010100001, "ld.h">;
+def LD_W : LOAD_2RI12<0b0010100010, "ld.w">;
+def LD_BU : LOAD_2RI12<0b0010101000, "ld.bu">;
+def LD_HU : LOAD_2RI12<0b0010101001, "ld.hu">;
+def ST_B : STORE_2RI12<0b0010100100, "st.b">;
+def ST_H : STORE_2RI12<0b0010100101, "st.h">;
+def ST_W : STORE_2RI12<0b0010100110, "st.w">;
+def PRELD : FmtPRELD<(outs), (ins uimm5:$imm5, GPR:$rj, simm12:$imm12),
+ "preld\t$imm5, $rj, $imm12">;
+
+// Atomic Memory Access Instructions
+def LL_W : LLBase<0b00100000, "ll.w">;
+def SC_W : SCBase<0b00100001, "sc.w">;
+
+// Barrier Instructions
+def DBAR : MISC_I15<0b00111000011100100, "dbar">;
+def IBAR : MISC_I15<0b00111000011100101, "ibar">;
+
+// Other Miscellaneous Instructions
+def SYSCALL : MISC_I15<0b00000000001010110, "syscall">;
+def BREAK : MISC_I15<0b00000000001010100, "break">;
+def RDTIMEL_W : RDTIME_2R<0b0000000000000000011000, "rdtimel.w">;
+def RDTIMEH_W : RDTIME_2R<0b0000000000000000011001, "rdtimeh.w">;
+def CPUCFG : ALU_2R<0b0000000000000000011011, "cpucfg">;
+
+/// LA64 instructions
+let Predicates = [IsLA64] in {
+
+// Arithmetic Operation Instructions for 64-bits
+def ADD_D : ALU_3R<0b00000000000100001, "add.d">;
+def SUB_D : ALU_3R<0b00000000000100011, "sub.d">;
+def ADDI_D : ALU_2RI12<0b0000001011, "addi.d", simm12>;
+def ADDU16I_D : ALU_2RI16<0b000100, "addu16i.d", simm16>;
+def ALSL_WU : ALU_3RI2<0b000000000000011, "alsl.wu", uimm2_plus1>;
+def ALSL_D : ALU_3RI2<0b000000000010110, "alsl.d", uimm2_plus1>;
+def LU32I_D : ALU_1RI20<0b0001011, "lu32i.d", simm20>;
+def LU52I_D : ALU_2RI12<0b0000001100, "lu52i.d", simm12>;
+def PCADDU18I : ALU_1RI20<0b0001111, "pcaddu18i", simm20>;
+def MUL_D : ALU_3R<0b00000000000111011, "mul.d">;
+def MULH_D : ALU_3R<0b00000000000111100, "mulh.d">;
+def MULH_DU : ALU_3R<0b00000000000111101, "mulh.du">;
+def MULW_D_W : ALU_3R<0b00000000000111110, "mulw.d.w">;
+def MULW_D_WU : ALU_3R<0b00000000000111111, "mulw.d.wu">;
+def DIV_D : ALU_3R<0b00000000001000100, "div.d">;
+def MOD_D : ALU_3R<0b00000000001000101, "mod.d">;
+def DIV_DU : ALU_3R<0b00000000001000110, "div.du">;
+def MOD_DU : ALU_3R<0b00000000001000111, "mod.du">;
+
+// Bit-shift Instructions for 64-bits
+def SLL_D : ALU_3R<0b00000000000110001, "sll.d">;
+def SRL_D : ALU_3R<0b00000000000110010, "srl.d">;
+def SRA_D : ALU_3R<0b00000000000110011, "sra.d">;
+def ROTR_D : ALU_3R<0b00000000000110111, "rotr.d">;
+def SLLI_D : ALU_2RI6<0b0000000001000001, "slli.d", uimm6>;
+def SRLI_D : ALU_2RI6<0b0000000001000101, "srli.d", uimm6>;
+def SRAI_D : ALU_2RI6<0b0000000001001001, "srai.d", uimm6>;
+def ROTRI_D : ALU_2RI6<0b0000000001001101, "rotri.d", uimm6>;
+
+// Bit-manipulation Instructions for 64-bits
+def CLO_D : ALU_2R<0b0000000000000000001000, "clo.d">;
+def CLZ_D : ALU_2R<0b0000000000000000001001, "clz.d">;
+def CTO_D : ALU_2R<0b0000000000000000001010, "cto.d">;
+def CTZ_D : ALU_2R<0b0000000000000000001011, "ctz.d">;
+def BYTEPICK_D : ALU_3RI3<0b00000000000011, "bytepick.d", uimm3>;
+def REVB_4H : ALU_2R<0b0000000000000000001101, "revb.4h">;
+def REVB_2W : ALU_2R<0b0000000000000000001110, "revb.2w">;
+def REVB_D : ALU_2R<0b0000000000000000001111, "revb.d">;
+def REVH_2W : ALU_2R<0b0000000000000000010000, "revh.2w">;
+def REVH_D : ALU_2R<0b0000000000000000010001, "revh.d">;
+def BITREV_8B : ALU_2R<0b0000000000000000010011, "bitrev.8b">;
+def BITREV_D : ALU_2R<0b0000000000000000010101, "bitrev.d">;
+def BSTRINS_D : ALU_BSTRD<0b0000000010, "bstrins.d", uimm6>;
+def BSTRPICK_D : ALU_BSTRD<0b0000000011, "bstrpick.d", uimm6>;
+
+// Common Memory Access Instructions for 64-bits
+def LD_WU : LOAD_2RI12<0b0010101010, "ld.wu">;
+def ST_D : STORE_2RI12<0b0010100111, "st.d">;
+def LDX_B : LOAD_3R<0b00111000000000000, "ldx.b">;
+def LDX_H : LOAD_3R<0b00111000000001000, "ldx.h">;
+def LDX_W : LOAD_3R<0b00111000000010000, "ldx.w">;
+def LDX_D : LOAD_3R<0b00111000000011000, "ldx.d">;
+def LDX_BU : LOAD_3R<0b00111000001000000, "ldx.bu">;
+def LDX_HU : LOAD_3R<0b00111000001001000, "ldx.hu">;
+def LDX_WU : LOAD_3R<0b00111000001010000, "ldx.wu">;
+def STX_B : STORE_3R<0b00111000000100000, "stx.b">;
+def STX_H : STORE_3R<0b00111000000101000, "stx.h">;
+def STX_W : STORE_3R<0b00111000000110000, "stx.w">;
+def STX_D : STORE_3R<0b00111000000111000, "stx.d">;
+def LDPTR_W : LOAD_2RI14<0b00100100, "ldptr.w">;
+def LDPTR_D : LOAD_2RI14<0b00100110, "ldptr.d">;
+def STPTR_W : STORE_2RI14<0b00100101, "stptr.w">;
+def STPTR_D : STORE_2RI14<0b00100111, "stptr.d">;
+def PRELDX : FmtPRELDX<(outs), (ins uimm5:$imm5, GPR:$rj, GPR:$rk),
+ "preldx\t$imm5, $rj, $rk">;
+
+// Bound Check Memory Access Instructions
+def LDGT_B : LOAD_3R<0b00111000011110000, "ldgt.b">;
+def LDGT_H : LOAD_3R<0b00111000011110001, "ldgt.h">;
+def LDGT_W : LOAD_3R<0b00111000011110010, "ldgt.w">;
+def LDGT_D : LOAD_3R<0b00111000011110011, "ldgt.d">;
+def LDLE_B : LOAD_3R<0b00111000011110100, "ldle.b">;
+def LDLE_H : LOAD_3R<0b00111000011110101, "ldle.h">;
+def LDLE_W : LOAD_3R<0b00111000011110110, "ldle.w">;
+def LDLE_D : LOAD_3R<0b00111000011110111, "ldle.d">;
+def STGT_B : STORE_3R<0b00111000011111000, "stgt.b">;
+def STGT_H : STORE_3R<0b00111000011111001, "stgt.h">;
+def STGT_W : STORE_3R<0b00111000011111010, "stgt.w">;
+def STGT_D : STORE_3R<0b00111000011111011, "stgt.d">;
+def STLE_B : STORE_3R<0b00111000011111100, "stle.b">;
+def STLE_H : STORE_3R<0b00111000011111101, "stle.h">;
+def STLE_W : STORE_3R<0b00111000011111110, "stle.w">;
+def STLE_D : STORE_3R<0b00111000011111111, "stle.d">;
+
+// Atomic Memory Access Instructions for 64-bits
+def AMSWAP_W : AM_3R<0b00111000011000000, "amswap.w">;
+def AMSWAP_D : AM_3R<0b00111000011000001, "amswap.d">;
+def AMADD_W : AM_3R<0b00111000011000010, "amadd.w">;
+def AMADD_D : AM_3R<0b00111000011000011, "amadd.d">;
+def AMAND_W : AM_3R<0b00111000011000100, "amand.w">;
+def AMAND_D : AM_3R<0b00111000011000101, "amand.d">;
+def AMOR_W : AM_3R<0b00111000011000110, "amor.w">;
+def AMOR_D : AM_3R<0b00111000011000111, "amor.d">;
+def AMXOR_W : AM_3R<0b00111000011001000, "amxor.w">;
+def AMXOR_D : AM_3R<0b00111000011001001, "amxor.d">;
+def AMMAX_W : AM_3R<0b00111000011001010, "ammax.w">;
+def AMMAX_D : AM_3R<0b00111000011001011, "ammax.d">;
+def AMMIN_W : AM_3R<0b00111000011001100, "ammin.w">;
+def AMMIN_D : AM_3R<0b00111000011001101, "ammin.d">;
+def AMMAX_WU : AM_3R<0b00111000011001110, "ammax.wu">;
+def AMMAX_DU : AM_3R<0b00111000011001111, "ammax.du">;
+def AMMIN_WU : AM_3R<0b00111000011010000, "ammin.wu">;
+def AMMIN_DU : AM_3R<0b00111000011010001, "ammin.du">;
+def AMSWAP_DB_W : AM_3R<0b00111000011010010, "amswap_db.w">;
+def AMSWAP_DB_D : AM_3R<0b00111000011010011, "amswap_db.d">;
+def AMADD_DB_W : AM_3R<0b00111000011010100, "amadd_db.w">;
+def AMADD_DB_D : AM_3R<0b00111000011010101, "amadd_db.d">;
+def AMAND_DB_W : AM_3R<0b00111000011010110, "amand_db.w">;
+def AMAND_DB_D : AM_3R<0b00111000011010111, "amand_db.d">;
+def AMOR_DB_W : AM_3R<0b00111000011011000, "amor_db.w">;
+def AMOR_DB_D : AM_3R<0b00111000011011001, "amor_db.d">;
+def AMXOR_DB_W : AM_3R<0b00111000011011010, "amxor_db.w">;
+def AMXOR_DB_D : AM_3R<0b00111000011011011, "amxor_db.d">;
+def AMMAX_DB_W : AM_3R<0b00111000011011100, "ammax_db.w">;
+def AMMAX_DB_D : AM_3R<0b00111000011011101, "ammax_db.d">;
+def AMMIN_DB_W : AM_3R<0b00111000011011110, "ammin_db.w">;
+def AMMIN_DB_D : AM_3R<0b00111000011011111, "ammin_db.d">;
+def AMMAX_DB_WU : AM_3R<0b00111000011100000, "ammax_db.wu">;
+def AMMAX_DB_DU : AM_3R<0b00111000011100001, "ammax_db.du">;
+def AMMIN_DB_WU : AM_3R<0b00111000011100010, "ammin_db.wu">;
+def AMMIN_DB_DU : AM_3R<0b00111000011100011, "ammin_db.du">;
+def LL_D : LLBase<0b00100010, "ll.d">;
+def SC_D : SCBase<0b00100011, "sc.d">;
+
+// CRC Check Instructions
+def CRC_W_B_W : ALU_3R<0b00000000001001000, "crc.w.b.w">;
+def CRC_W_H_W : ALU_3R<0b00000000001001001, "crc.w.h.w">;
+def CRC_W_W_W : ALU_3R<0b00000000001001010, "crc.w.w.w">;
+def CRC_W_D_W : ALU_3R<0b00000000001001011, "crc.w.d.w">;
+def CRCC_W_B_W : ALU_3R<0b00000000001001100, "crcc.w.b.w">;
+def CRCC_W_H_W : ALU_3R<0b00000000001001101, "crcc.w.h.w">;
+def CRCC_W_W_W : ALU_3R<0b00000000001001110, "crcc.w.w.w">;
+def CRCC_W_D_W : ALU_3R<0b00000000001001111, "crcc.w.d.w">;
+
+// Other Miscellaneous Instructions for 64-bits
+def ASRTLE_D : FmtASRT<0b00000000000000010, (outs), (ins GPR:$rj, GPR:$rk),
+ "asrtle.d\t$rj, $rk">;
+def ASRTGT_D : FmtASRT<0b00000000000000011, (outs), (ins GPR:$rj, GPR:$rk),
+ "asrtgt.d\t$rj, $rk">;
+def RDTIME_D : RDTIME_2R<0b0000000000000000011010, "rdtime.d">;
+} // Predicates = [IsLA64]
+
+//===----------------------------------------------------------------------===//
+// Pseudo-instructions and codegen patterns
+//
+// Naming convention: For 'generic' pattern classes, we use the naming
+// convention PatTy1Ty2.
+//===----------------------------------------------------------------------===//
+
+/// Generic pattern classes
+
+class PatGprGpr<SDPatternOperator OpNode, LAInst Inst>
+ : Pat<(OpNode GPR:$rj, GPR:$rk), (Inst GPR:$rj, GPR:$rk)>;
+class PatGprGpr_32<SDPatternOperator OpNode, LAInst Inst>
+ : Pat<(sext_inreg (OpNode GPR:$rj, GPR:$rk), i32), (Inst GPR:$rj, GPR:$rk)>;
+
+class PatGprImm<SDPatternOperator OpNode, LAInst Inst, Operand ImmOpnd>
+ : Pat<(OpNode GPR:$rj, ImmOpnd:$imm),
+ (Inst GPR:$rj, ImmOpnd:$imm)>;
+class PatGprImm_32<SDPatternOperator OpNode, LAInst Inst, Operand ImmOpnd>
+ : Pat<(sext_inreg (OpNode GPR:$rj, ImmOpnd:$imm), i32),
+ (Inst GPR:$rj, ImmOpnd:$imm)>;
+
+def : PatGprGpr<and, AND>;
+def : PatGprGpr<or, OR>;
+def : PatGprGpr<xor, XOR>;
+
+/// LA32 patterns
+let Predicates = [IsLA32] in {
+def : PatGprGpr<add, ADD_W>;
+def : PatGprImm<add, ADDI_W, simm12>;
+} // Predicates = [IsLA32]
+
+/// LA64 patterns
+let Predicates = [IsLA64] in {
+def : Pat<(sext_inreg GPR:$rj, i32), (ADDI_W GPR:$rj, 0)>;
+
+def : PatGprGpr<add, ADD_D>;
+def : PatGprGpr_32<add, ADD_W>;
+
+def : PatGprImm<add, ADDI_D, simm12>;
+def : PatGprImm_32<add, ADDI_W, simm12>;
+} // Predicates = [IsLA64]
+
+//===----------------------------------------------------------------------===//
+// Assembler Pseudo Instructions
+//===----------------------------------------------------------------------===//
+def : InstAlias<"nop", (ANDI R0, R0, 0)>;
+def : InstAlias<"move $dst, $src", (OR GPR:$dst, GPR:$src, R0)>;
--- /dev/null
+//=- LoongArchMCInstLower.cpp - Convert LoongArch MachineInstr to an MCInst -=//
+//
+// 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 code to lower LoongArch MachineInstrs to their
+// corresponding MCInst records.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LoongArch.h"
+#include "LoongArchSubtarget.h"
+#include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+bool llvm::lowerLoongArchMachineOperandToMCOperand(const MachineOperand &MO,
+ MCOperand &MCOp,
+ const AsmPrinter &AP) {
+ switch (MO.getType()) {
+ default:
+ report_fatal_error(
+ "lowerLoongArchMachineOperandToMCOperand: unknown operand type");
+ case MachineOperand::MO_Register:
+ // Ignore all implicit register operands.
+ if (MO.isImplicit())
+ return false;
+ MCOp = MCOperand::createReg(MO.getReg());
+ break;
+ case MachineOperand::MO_RegisterMask:
+ // Regmasks are like implicit defs.
+ return false;
+ case MachineOperand::MO_Immediate:
+ MCOp = MCOperand::createImm(MO.getImm());
+ break;
+ // TODO: lower special operands
+ case MachineOperand::MO_MachineBasicBlock:
+ case MachineOperand::MO_GlobalAddress:
+ case MachineOperand::MO_BlockAddress:
+ case MachineOperand::MO_ExternalSymbol:
+ case MachineOperand::MO_ConstantPoolIndex:
+ case MachineOperand::MO_JumpTableIndex:
+ break;
+ }
+ return true;
+}
+
+bool llvm::lowerLoongArchMachineInstrToMCInst(const MachineInstr *MI,
+ MCInst &OutMI, AsmPrinter &AP) {
+ OutMI.setOpcode(MI->getOpcode());
+
+ for (const MachineOperand &MO : MI->operands()) {
+ MCOperand MCOp;
+ if (lowerLoongArchMachineOperandToMCOperand(MO, MCOp, AP))
+ OutMI.addOperand(MCOp);
+ }
+ return false;
+}
--- /dev/null
+//=- LoongArchMachineFunctionInfo.h - LoongArch machine function info -----===//
+//
+// 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 declares LoongArch-specific per-machine-function information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHMACHINEFUNCTIONINFO_H
+#define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHMACHINEFUNCTIONINFO_H
+
+#include "LoongArchSubtarget.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineFunction.h"
+
+namespace llvm {
+
+/// LoongArchMachineFunctionInfo - This class is derived from
+/// MachineFunctionInfo and contains private LoongArch-specific information for
+/// each MachineFunction.
+class LoongArchMachineFunctionInfo : public MachineFunctionInfo {
+private:
+ /// FrameIndex for start of varargs area
+ int VarArgsFrameIndex = 0;
+ /// Size of the save area used for varargs
+ int VarArgsSaveSize = 0;
+
+ /// Size of stack frame to save callee saved registers
+ unsigned CalleeSavedStackSize = 0;
+
+public:
+ LoongArchMachineFunctionInfo(const MachineFunction &MF) {}
+
+ int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }
+ void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }
+
+ unsigned getVarArgsSaveSize() const { return VarArgsSaveSize; }
+ void setVarArgsSaveSize(int Size) { VarArgsSaveSize = Size; }
+
+ unsigned getCalleeSavedStackSize() const { return CalleeSavedStackSize; }
+ void setCalleeSavedStackSize(unsigned Size) { CalleeSavedStackSize = Size; }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHMACHINEFUNCTIONINFO_H
--- /dev/null
+//===- LoongArchRegisterInfo.cpp - LoongArch Register 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 the TargetRegisterInfo
+// class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LoongArchRegisterInfo.h"
+#include "LoongArch.h"
+#include "LoongArchSubtarget.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/RegisterScavenging.h"
+#include "llvm/CodeGen/TargetFrameLowering.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/Support/ErrorHandling.h"
+
+using namespace llvm;
+
+#define GET_REGINFO_TARGET_DESC
+#include "LoongArchGenRegisterInfo.inc"
+
+LoongArchRegisterInfo::LoongArchRegisterInfo(unsigned HwMode)
+ : LoongArchGenRegisterInfo(LoongArch::R1, /*DwarfFlavour*/ 0,
+ /*EHFlavor*/ 0,
+ /*PC*/ 0, HwMode) {}
+
+const MCPhysReg *
+LoongArchRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
+ auto &Subtarget = MF->getSubtarget<LoongArchSubtarget>();
+
+ switch (Subtarget.getTargetABI()) {
+ default:
+ llvm_unreachable("Unrecognized ABI");
+ case LoongArchABI::ABI_ILP32S:
+ case LoongArchABI::ABI_LP64S:
+ return CSR_ILP32S_LP64S_SaveList;
+ case LoongArchABI::ABI_ILP32F:
+ case LoongArchABI::ABI_LP64F:
+ return CSR_ILP32F_LP64F_SaveList;
+ case LoongArchABI::ABI_ILP32D:
+ case LoongArchABI::ABI_LP64D:
+ return CSR_ILP32D_LP64D_SaveList;
+ }
+}
+
+const uint32_t *
+LoongArchRegisterInfo::getCallPreservedMask(const MachineFunction &MF,
+ CallingConv::ID CC) const {
+ auto &Subtarget = MF.getSubtarget<LoongArchSubtarget>();
+
+ switch (Subtarget.getTargetABI()) {
+ default:
+ llvm_unreachable("Unrecognized ABI");
+ case LoongArchABI::ABI_ILP32S:
+ case LoongArchABI::ABI_LP64S:
+ return CSR_ILP32S_LP64S_RegMask;
+ case LoongArchABI::ABI_ILP32F:
+ case LoongArchABI::ABI_LP64F:
+ return CSR_ILP32F_LP64F_RegMask;
+ case LoongArchABI::ABI_ILP32D:
+ case LoongArchABI::ABI_LP64D:
+ return CSR_ILP32D_LP64D_RegMask;
+ }
+}
+
+const uint32_t *LoongArchRegisterInfo::getNoPreservedMask() const {
+ return CSR_NoRegs_RegMask;
+}
+
+BitVector
+LoongArchRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
+ const LoongArchFrameLowering *TFI = getFrameLowering(MF);
+ BitVector Reserved(getNumRegs());
+
+ // Use markSuperRegs to ensure any register aliases are also reserved
+ markSuperRegs(Reserved, LoongArch::R0); // zero
+ markSuperRegs(Reserved, LoongArch::R2); // tp
+ markSuperRegs(Reserved, LoongArch::R3); // sp
+ markSuperRegs(Reserved, LoongArch::R21); // non-allocatable
+ if (TFI->hasFP(MF))
+ markSuperRegs(Reserved, LoongArch::R22); // fp
+ // Reserve the base register if we need to realign the stack and allocate
+ // variable-sized objects at runtime.
+ if (TFI->hasBP(MF))
+ markSuperRegs(Reserved, LoongArchABI::getBPReg()); // bp
+
+ assert(checkAllSuperRegsMarked(Reserved));
+ return Reserved;
+}
+
+bool LoongArchRegisterInfo::isConstantPhysReg(MCRegister PhysReg) const {
+ return PhysReg == LoongArch::R0;
+}
+
+Register
+LoongArchRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
+ const TargetFrameLowering *TFI = getFrameLowering(MF);
+ return TFI->hasFP(MF) ? LoongArch::R22 : LoongArch::R3;
+}
+
+void LoongArchRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
+ int SPAdj,
+ unsigned FIOperandNum,
+ RegScavenger *RS) const {
+ assert(SPAdj == 0 && "Unexpected non-zero SPAdj value");
+ // TODO: Implement this when we have function calls
+}
--- /dev/null
+//= LoongArchRegisterInfo.h - LoongArch Register Information Impl -*- 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 the TargetRegisterInfo
+// class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHREGISTERINFO_H
+#define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHREGISTERINFO_H
+
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+
+#define GET_REGINFO_HEADER
+#include "LoongArchGenRegisterInfo.inc"
+
+namespace llvm {
+
+struct LoongArchRegisterInfo : public LoongArchGenRegisterInfo {
+
+ LoongArchRegisterInfo(unsigned HwMode);
+
+ const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;
+ const uint32_t *getCallPreservedMask(const MachineFunction &MF,
+ CallingConv::ID) const override;
+ const uint32_t *getNoPreservedMask() const override;
+
+ BitVector getReservedRegs(const MachineFunction &MF) const override;
+ bool isConstantPhysReg(MCRegister PhysReg) const override;
+
+ const TargetRegisterClass *
+ getPointerRegClass(const MachineFunction &MF,
+ unsigned Kind = 0) const override {
+ return &LoongArch::GPRRegClass;
+ }
+
+ void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj,
+ unsigned FIOperandNum,
+ RegScavenger *RS = nullptr) const override;
+
+ Register getFrameRegister(const MachineFunction &MF) const override;
+};
+} // namespace llvm
+
+#endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHREGISTERINFO_H
--- /dev/null
+//===-- LoongArchRegisterInfo.td - LoongArch Register defs -*- 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
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Declarations that describe the LoongArch register files
+//===----------------------------------------------------------------------===//
+
+let Namespace = "LoongArch" in {
+class LoongArchReg<bits<16> Enc, string n, list<string> alt = []>
+ : Register<n> {
+ let HWEncoding = Enc;
+ let AltNames = alt;
+}
+
+class LoongArchReg32<bits<16> Enc, string n, list<string> alt = []>
+ : Register<n> {
+ let HWEncoding = Enc;
+ let AltNames = alt;
+}
+
+def sub_32 : SubRegIndex<32>;
+class LoongArchReg64<LoongArchReg32 subreg> : Register<""> {
+ let HWEncoding = subreg.HWEncoding;
+ let SubRegs = [subreg];
+ let SubRegIndices = [sub_32];
+ let AsmName = subreg.AsmName;
+ let AltNames = subreg.AltNames;
+}
+
+let FallbackRegAltNameIndex = NoRegAltName in
+def RegAliasName : RegAltNameIndex;
+} // Namespace = "LoongArch"
+
+// Integer registers
+
+let RegAltNameIndices = [RegAliasName] in {
+ def R0 : LoongArchReg<0, "r0", ["zero"]>, DwarfRegNum<[0]>;
+ def R1 : LoongArchReg<1, "r1", ["ra"]>, DwarfRegNum<[1]>;
+ def R2 : LoongArchReg<2, "r2", ["tp"]>, DwarfRegNum<[2]>;
+ def R3 : LoongArchReg<3, "r3", ["sp"]>, DwarfRegNum<[3]>;
+ def R4 : LoongArchReg<4, "r4", ["a0"]>, DwarfRegNum<[4]>;
+ def R5 : LoongArchReg<5, "r5", ["a1"]>, DwarfRegNum<[5]>;
+ def R6 : LoongArchReg<6, "r6", ["a2"]>, DwarfRegNum<[6]>;
+ def R7 : LoongArchReg<7, "r7", ["a3"]>, DwarfRegNum<[7]>;
+ def R8 : LoongArchReg<8, "r8", ["a4"]>, DwarfRegNum<[8]>;
+ def R9 : LoongArchReg<9, "r9", ["a5"]>, DwarfRegNum<[9]>;
+ def R10 : LoongArchReg<10, "r10", ["a6"]>, DwarfRegNum<[10]>;
+ def R11 : LoongArchReg<11, "r11", ["a7"]>, DwarfRegNum<[11]>;
+ def R12 : LoongArchReg<12, "r12", ["t0"]>, DwarfRegNum<[12]>;
+ def R13 : LoongArchReg<13, "r13", ["t1"]>, DwarfRegNum<[13]>;
+ def R14 : LoongArchReg<14, "r14", ["t2"]>, DwarfRegNum<[14]>;
+ def R15 : LoongArchReg<15, "r15", ["t3"]>, DwarfRegNum<[15]>;
+ def R16 : LoongArchReg<16, "r16", ["t4"]>, DwarfRegNum<[16]>;
+ def R17 : LoongArchReg<17, "r17", ["t5"]>, DwarfRegNum<[17]>;
+ def R18 : LoongArchReg<18, "r18", ["t6"]>, DwarfRegNum<[18]>;
+ def R19 : LoongArchReg<19, "r19", ["t7"]>, DwarfRegNum<[19]>;
+ def R20 : LoongArchReg<20, "r20", ["t8"]>, DwarfRegNum<[20]>;
+ def R21 : LoongArchReg<21, "r21", [""]>, DwarfRegNum<[21]>;
+ def R22 : LoongArchReg<22, "r22", ["fp", "s9"]>, DwarfRegNum<[22]>;
+ def R23 : LoongArchReg<23, "r23", ["s0"]>, DwarfRegNum<[23]>;
+ def R24 : LoongArchReg<24, "r24", ["s1"]>, DwarfRegNum<[24]>;
+ def R25 : LoongArchReg<25, "r25", ["s2"]>, DwarfRegNum<[25]>;
+ def R26 : LoongArchReg<26, "r26", ["s3"]>, DwarfRegNum<[26]>;
+ def R27 : LoongArchReg<27, "r27", ["s4"]>, DwarfRegNum<[27]>;
+ def R28 : LoongArchReg<28, "r28", ["s5"]>, DwarfRegNum<[28]>;
+ def R29 : LoongArchReg<29, "r29", ["s6"]>, DwarfRegNum<[29]>;
+ def R30 : LoongArchReg<30, "r30", ["s7"]>, DwarfRegNum<[30]>;
+ def R31 : LoongArchReg<31, "r31", ["s8"]>, DwarfRegNum<[31]>;
+} // RegAltNameIndices = [RegAliasName]
+
+def GRLenVT : ValueTypeByHwMode<[LA32, LA64],
+ [i32, i64]>;
+def GRLenRI : RegInfoByHwMode<
+ [LA32, LA64],
+ [RegInfo<32,32,32>, RegInfo<64,64,64>]>;
+
+// The order of registers represents the preferred allocation sequence.
+// Registers are listed in the order caller-save, callee-save, specials.
+def GPR : RegisterClass<"LoongArch", [GRLenVT], 32, (add
+ // Argument registers (a0...a7)
+ (sequence "R%u", 4, 11),
+ // Temporary registers (t0...t8)
+ (sequence "R%u", 12, 20),
+ // Static register (s9/fp, s0...s8)
+ (sequence "R%u", 22, 31),
+ // Specials (r0, ra, tp, sp)
+ (sequence "R%u", 0, 3),
+ // Reserved (Non-allocatable)
+ R21
+ )> {
+ let RegInfos = GRLenRI;
+}
+
+// Floating point registers
+
+let RegAltNameIndices = [RegAliasName] in {
+ def F0 : LoongArchReg32<0, "f0", ["fa0"]>, DwarfRegNum<[32]>;
+ def F1 : LoongArchReg32<1, "f1", ["fa1"]>, DwarfRegNum<[33]>;
+ def F2 : LoongArchReg32<2, "f2", ["fa2"]>, DwarfRegNum<[34]>;
+ def F3 : LoongArchReg32<3, "f3", ["fa3"]>, DwarfRegNum<[35]>;
+ def F4 : LoongArchReg32<4, "f4", ["fa4"]>, DwarfRegNum<[36]>;
+ def F5 : LoongArchReg32<5, "f5", ["fa5"]>, DwarfRegNum<[37]>;
+ def F6 : LoongArchReg32<6, "f6", ["fa6"]>, DwarfRegNum<[38]>;
+ def F7 : LoongArchReg32<7, "f7", ["fa7"]>, DwarfRegNum<[39]>;
+ def F8 : LoongArchReg32<8, "f8", ["ft0"]>, DwarfRegNum<[40]>;
+ def F9 : LoongArchReg32<9, "f9", ["ft1"]>, DwarfRegNum<[41]>;
+ def F10 : LoongArchReg32<10,"f10", ["ft2"]>, DwarfRegNum<[42]>;
+ def F11 : LoongArchReg32<11,"f11", ["ft3"]>, DwarfRegNum<[43]>;
+ def F12 : LoongArchReg32<12,"f12", ["ft4"]>, DwarfRegNum<[44]>;
+ def F13 : LoongArchReg32<13,"f13", ["ft5"]>, DwarfRegNum<[45]>;
+ def F14 : LoongArchReg32<14,"f14", ["ft6"]>, DwarfRegNum<[46]>;
+ def F15 : LoongArchReg32<15,"f15", ["ft7"]>, DwarfRegNum<[47]>;
+ def F16 : LoongArchReg32<16,"f16", ["ft8"]>, DwarfRegNum<[48]>;
+ def F17 : LoongArchReg32<17,"f17", ["ft9"]>, DwarfRegNum<[49]>;
+ def F18 : LoongArchReg32<18,"f18", ["ft10"]>, DwarfRegNum<[50]>;
+ def F19 : LoongArchReg32<19,"f19", ["ft11"]>, DwarfRegNum<[51]>;
+ def F20 : LoongArchReg32<20,"f20", ["ft12"]>, DwarfRegNum<[52]>;
+ def F21 : LoongArchReg32<21,"f21", ["ft13"]>, DwarfRegNum<[53]>;
+ def F22 : LoongArchReg32<22,"f22", ["ft14"]>, DwarfRegNum<[54]>;
+ def F23 : LoongArchReg32<23,"f23", ["ft15"]>, DwarfRegNum<[55]>;
+ def F24 : LoongArchReg32<24,"f24", ["fs0"]>, DwarfRegNum<[56]>;
+ def F25 : LoongArchReg32<25,"f25", ["fs1"]>, DwarfRegNum<[57]>;
+ def F26 : LoongArchReg32<26,"f26", ["fs2"]>, DwarfRegNum<[58]>;
+ def F27 : LoongArchReg32<27,"f27", ["fs3"]>, DwarfRegNum<[59]>;
+ def F28 : LoongArchReg32<28,"f28", ["fs4"]>, DwarfRegNum<[60]>;
+ def F29 : LoongArchReg32<29,"f29", ["fs5"]>, DwarfRegNum<[61]>;
+ def F30 : LoongArchReg32<30,"f30", ["fs6"]>, DwarfRegNum<[62]>;
+ def F31 : LoongArchReg32<31,"f31", ["fs7"]>, DwarfRegNum<[63]>;
+
+ foreach I = 0-31 in {
+ def F#I#_64 : LoongArchReg64<!cast<LoongArchReg32>("F"#I)>,
+ DwarfRegNum<[!add(I, 32)]>;
+ }
+}
+
+// The order of registers represents the preferred allocation sequence.
+def FPR32 : RegisterClass<"LoongArch", [f32], 32, (sequence "F%u", 0, 31)>;
+def FPR64 : RegisterClass<"LoongArch", [f64], 64, (sequence "F%u_64", 0, 31)>;
--- /dev/null
+//===-- LoongArchSubtarget.cpp - LoongArch Subtarget 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 implements the LoongArch specific subclass of TargetSubtargetInfo.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LoongArchSubtarget.h"
+#include "LoongArchFrameLowering.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "loongarch-subtarget"
+
+#define GET_SUBTARGETINFO_TARGET_DESC
+#define GET_SUBTARGETINFO_CTOR
+#include "LoongArchGenSubtargetInfo.inc"
+
+void LoongArchSubtarget::anchor() {}
+
+LoongArchSubtarget &LoongArchSubtarget::initializeSubtargetDependencies(
+ const Triple &TT, StringRef CPU, StringRef TuneCPU, StringRef FS,
+ StringRef ABIName) {
+ bool Is64Bit = TT.isArch64Bit();
+ if (CPU.empty())
+ CPU = Is64Bit ? "generic-la64" : "generic-la32";
+
+ if (TuneCPU.empty())
+ TuneCPU = CPU;
+
+ ParseSubtargetFeatures(CPU, TuneCPU, FS);
+ if (Is64Bit) {
+ GRLenVT = MVT::i64;
+ GRLen = 64;
+ }
+
+ // TODO: ILP32{S,F} LP64{S,F}
+ TargetABI = Is64Bit ? LoongArchABI::ABI_LP64D : LoongArchABI::ABI_ILP32D;
+ return *this;
+}
+
+LoongArchSubtarget::LoongArchSubtarget(const Triple &TT, StringRef CPU,
+ StringRef TuneCPU, StringRef FS,
+ StringRef ABIName,
+ const TargetMachine &TM)
+ : LoongArchGenSubtargetInfo(TT, CPU, TuneCPU, FS),
+ FrameLowering(
+ initializeSubtargetDependencies(TT, CPU, TuneCPU, FS, ABIName)),
+ InstrInfo(*this), RegInfo(getHwMode()), TLInfo(TM, *this) {}
--- /dev/null
+//===- LoongArchSubtarget.h - Define Subtarget for the 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 declares the LoongArch specific subclass of TargetSubtargetInfo.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHSUBTARGET_H
+#define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHSUBTARGET_H
+
+#include "LoongArchFrameLowering.h"
+#include "LoongArchISelLowering.h"
+#include "LoongArchInstrInfo.h"
+#include "LoongArchRegisterInfo.h"
+#include "MCTargetDesc/LoongArchBaseInfo.h"
+#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/Target/TargetMachine.h"
+
+#define GET_SUBTARGETINFO_HEADER
+#include "LoongArchGenSubtargetInfo.inc"
+
+namespace llvm {
+class StringRef;
+
+class LoongArchSubtarget : public LoongArchGenSubtargetInfo {
+ virtual void anchor();
+ bool HasLA64 = false;
+ bool HasBasicF = false;
+ bool HasBasicD = false;
+ bool HasExtLSX = false;
+ bool HasExtLASX = false;
+ bool HasExtLVZ = false;
+ bool HasExtLBT = false;
+ unsigned GRLen = 32;
+ MVT GRLenVT = MVT::i32;
+ LoongArchABI::ABI TargetABI = LoongArchABI::ABI_Unknown;
+ LoongArchFrameLowering FrameLowering;
+ LoongArchInstrInfo InstrInfo;
+ LoongArchRegisterInfo RegInfo;
+ LoongArchTargetLowering TLInfo;
+
+ /// Initializes using the passed in CPU and feature strings so that we can
+ /// use initializer lists for subtarget initialization.
+ LoongArchSubtarget &initializeSubtargetDependencies(const Triple &TT,
+ StringRef CPU,
+ StringRef TuneCPU,
+ StringRef FS,
+ StringRef ABIName);
+
+public:
+ // Initializes the data members to match that of the specified triple.
+ LoongArchSubtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU,
+ StringRef FS, StringRef ABIName, const TargetMachine &TM);
+
+ // Parses features string setting specified subtarget options. The
+ // definition of this function is auto-generated by tblgen.
+ void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
+
+ const LoongArchFrameLowering *getFrameLowering() const override {
+ return &FrameLowering;
+ }
+ const LoongArchInstrInfo *getInstrInfo() const override { return &InstrInfo; }
+ const LoongArchRegisterInfo *getRegisterInfo() const override {
+ return &RegInfo;
+ }
+ const LoongArchTargetLowering *getTargetLowering() const override {
+ return &TLInfo;
+ }
+ bool is64Bit() const { return HasLA64; }
+ bool hasBasicF() const { return HasBasicF; }
+ bool hasBasicD() const { return HasBasicD; }
+ bool hasExtLSX() const { return HasExtLSX; }
+ bool hasExtLASX() const { return HasExtLASX; }
+ bool hasExtLVZ() const { return HasExtLVZ; }
+ bool hasExtLBT() const { return HasExtLBT; }
+ MVT getGRLenVT() const { return GRLenVT; }
+ unsigned getGRLen() const { return GRLen; }
+ LoongArchABI::ABI getTargetABI() const { return TargetABI; }
+};
+} // namespace llvm
+
+#endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHSUBTARGET_H
//===----------------------------------------------------------------------===//
#include "LoongArchTargetMachine.h"
+#include "LoongArch.h"
+#include "MCTargetDesc/LoongArchBaseInfo.h"
#include "TargetInfo/LoongArchTargetInfo.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
+#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/MC/TargetRegistry.h"
using namespace llvm;
Optional<CodeModel::Model> CM, CodeGenOpt::Level OL, bool JIT)
: LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options,
getEffectiveRelocModel(TT, RM),
- getEffectiveCodeModel(CM, CodeModel::Small), OL) {
+ getEffectiveCodeModel(CM, CodeModel::Small), OL),
+ TLOF(std::make_unique<TargetLoweringObjectFileELF>()) {
initAsmInfo();
}
LoongArchTargetMachine::~LoongArchTargetMachine() = default;
+
+const LoongArchSubtarget *
+LoongArchTargetMachine::getSubtargetImpl(const Function &F) const {
+ Attribute CPUAttr = F.getFnAttribute("target-cpu");
+ Attribute TuneAttr = F.getFnAttribute("tune-cpu");
+ Attribute FSAttr = F.getFnAttribute("target-features");
+
+ std::string CPU =
+ CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
+ std::string TuneCPU =
+ TuneAttr.isValid() ? TuneAttr.getValueAsString().str() : CPU;
+ std::string FS =
+ FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
+
+ std::string Key = CPU + TuneCPU + FS;
+ auto &I = SubtargetMap[Key];
+ if (!I) {
+ // This needs to be done before we create a new subtarget since any
+ // creation will depend on the TM and the code generation flags on the
+ // function that reside in TargetOptions.
+ resetTargetOptions(F);
+ auto ABIName = Options.MCOptions.getABIName();
+ if (const MDString *ModuleTargetABI = dyn_cast_or_null<MDString>(
+ F.getParent()->getModuleFlag("target-abi"))) {
+ auto TargetABI = LoongArchABI::getTargetABI(ABIName);
+ if (TargetABI != LoongArchABI::ABI_Unknown &&
+ ModuleTargetABI->getString() != ABIName) {
+ report_fatal_error("-target-abi option != target-abi module flag");
+ }
+ ABIName = ModuleTargetABI->getString();
+ }
+ I = std::make_unique<LoongArchSubtarget>(TargetTriple, CPU, TuneCPU, FS,
+ ABIName, *this);
+ }
+ return I.get();
+}
+
+namespace {
+class LoongArchPassConfig : public TargetPassConfig {
+public:
+ LoongArchPassConfig(LoongArchTargetMachine &TM, PassManagerBase &PM)
+ : TargetPassConfig(TM, PM) {}
+
+ LoongArchTargetMachine &getLoongArchTargetMachine() const {
+ return getTM<LoongArchTargetMachine>();
+ }
+
+ bool addInstSelector() override;
+};
+} // namespace
+
+TargetPassConfig *
+LoongArchTargetMachine::createPassConfig(PassManagerBase &PM) {
+ return new LoongArchPassConfig(*this, PM);
+}
+
+bool LoongArchPassConfig::addInstSelector() {
+ addPass(createLoongArchISelDag(getLoongArchTargetMachine()));
+
+ return false;
+}
#ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHTARGETMACHINE_H
#define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHTARGETMACHINE_H
+#include "LoongArchSubtarget.h"
#include "llvm/Target/TargetMachine.h"
namespace llvm {
class LoongArchTargetMachine : public LLVMTargetMachine {
+ std::unique_ptr<TargetLoweringObjectFile> TLOF;
+ mutable StringMap<std::unique_ptr<LoongArchSubtarget>> SubtargetMap;
public:
LoongArchTargetMachine(const Target &T, const Triple &TT, StringRef CPU,
Optional<CodeModel::Model> CM, CodeGenOpt::Level OL,
bool JIT);
~LoongArchTargetMachine() override;
+
+ const LoongArchSubtarget *getSubtargetImpl(const Function &F) const override;
+ const LoongArchSubtarget *getSubtargetImpl() const = delete;
+
+ // Pass Pipeline Configuration
+ TargetPassConfig *createPassConfig(PassManagerBase &PM) override;
+
+ TargetLoweringObjectFile *getObjFileLowering() const override {
+ return TLOF.get();
+ }
};
} // end namespace llvm
add_llvm_component_library(LLVMLoongArchDesc
+ LoongArchAsmBackend.cpp
+ LoongArchBaseInfo.cpp
+ LoongArchELFObjectWriter.cpp
+ LoongArchInstPrinter.cpp
+ LoongArchMCAsmInfo.cpp
LoongArchMCTargetDesc.cpp
+ LoongArchMCCodeEmitter.cpp
LINK_COMPONENTS
MC
--- /dev/null
+//===-- LoongArchAsmBackend.cpp - LoongArch Assembler Backend -*- 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 implements the LoongArchAsmBackend class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LoongArchAsmBackend.h"
+#include "llvm/MC/MCAsmLayout.h"
+#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCELFObjectWriter.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/EndianStream.h"
+
+#define DEBUG_TYPE "loongarch-asmbackend"
+
+using namespace llvm;
+
+void LoongArchAsmBackend::applyFixup(const MCAssembler &Asm,
+ const MCFixup &Fixup,
+ const MCValue &Target,
+ MutableArrayRef<char> Data, uint64_t Value,
+ bool IsResolved,
+ const MCSubtargetInfo *STI) const {
+ // TODO: Apply the Value for given Fixup into the provided data fragment.
+ return;
+}
+
+bool LoongArchAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
+ const MCFixup &Fixup,
+ const MCValue &Target) {
+ // TODO: Determine which relocation require special processing at linking
+ // time.
+ return false;
+}
+
+bool LoongArchAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
+ const MCSubtargetInfo *STI) const {
+ // Check for byte count not multiple of instruction word size
+ if (Count % 4 != 0)
+ return false;
+
+ // The nop on LoongArch is andi r0, r0, 0.
+ for (; Count >= 4; Count -= 4)
+ support::endian::write<uint32_t>(OS, 0x03400000, support::little);
+
+ return true;
+}
+
+std::unique_ptr<MCObjectTargetWriter>
+LoongArchAsmBackend::createObjectTargetWriter() const {
+ return createLoongArchELFObjectWriter(OSABI, Is64Bit);
+}
+
+MCAsmBackend *llvm::createLoongArchAsmBackend(const Target &T,
+ const MCSubtargetInfo &STI,
+ const MCRegisterInfo &MRI,
+ const MCTargetOptions &Options) {
+ const Triple &TT = STI.getTargetTriple();
+ uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS());
+ return new LoongArchAsmBackend(STI, OSABI, TT.isArch64Bit());
+}
--- /dev/null
+//===-- LoongArchAsmBackend.h - LoongArch Assembler Backend ---*- 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 defines the LoongArchAsmBackend class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHASMBACKEND_H
+#define LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHASMBACKEND_H
+
+#include "MCTargetDesc/LoongArchBaseInfo.h"
+#include "MCTargetDesc/LoongArchMCTargetDesc.h"
+#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/MC/MCFixupKindInfo.h"
+
+namespace llvm {
+
+class LoongArchAsmBackend : public MCAsmBackend {
+ const MCSubtargetInfo &STI;
+ uint8_t OSABI;
+ bool Is64Bit;
+
+public:
+ LoongArchAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI, bool Is64Bit)
+ : MCAsmBackend(support::little), STI(STI), OSABI(OSABI),
+ Is64Bit(Is64Bit) {}
+ ~LoongArchAsmBackend() override {}
+
+ void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
+ const MCValue &Target, MutableArrayRef<char> Data,
+ uint64_t Value, bool IsResolved,
+ const MCSubtargetInfo *STI) const override;
+
+ bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
+ const MCValue &Target) override;
+
+ bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
+ const MCRelaxableFragment *DF,
+ const MCAsmLayout &Layout) const override {
+ return false;
+ }
+
+ unsigned getNumFixupKinds() const override {
+ // FIXME: Implement this when we define fixup kind
+ return 0;
+ }
+
+ void relaxInstruction(MCInst &Inst,
+ const MCSubtargetInfo &STI) const override {}
+
+ bool writeNopData(raw_ostream &OS, uint64_t Count,
+ const MCSubtargetInfo *STI) const override;
+
+ std::unique_ptr<MCObjectTargetWriter>
+ createObjectTargetWriter() const override;
+};
+} // namespace llvm
+
+#endif // LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHASMBACKEND_H
--- /dev/null
+//= LoongArchBaseInfo.cpp - Top level definitions for LoongArch MC -*- 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 implements helper functions for the LoongArch target useful for the
+// compiler back-end and the MC libraries.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LoongArchBaseInfo.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+
+namespace llvm {
+
+namespace LoongArchABI {
+
+ABI getTargetABI(StringRef ABIName) {
+ auto TargetABI = StringSwitch<ABI>(ABIName)
+ .Case("ilp32s", ABI_ILP32S)
+ .Case("ilp32f", ABI_ILP32F)
+ .Case("ilp32d", ABI_ILP32D)
+ .Case("lp64s", ABI_LP64S)
+ .Case("lp64f", ABI_LP64F)
+ .Case("lp64d", ABI_LP64D)
+ .Default(ABI_Unknown);
+ return TargetABI;
+}
+
+// FIXME: other register?
+MCRegister getBPReg() { return LoongArch::R31; }
+
+} // namespace LoongArchABI
+
+} // namespace llvm
--- /dev/null
+//=- LoongArchBaseInfo.h - Top level definitions for LoongArch MC -*- 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 small standalone enum definitions and helper function
+// definitions for the LoongArch target useful for the compiler back-end and the
+// MC libraries.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHBASEINFO_H
+#define LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHBASEINFO_H
+
+#include "MCTargetDesc/LoongArchMCTargetDesc.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/MC/MCInstrDesc.h"
+#include "llvm/MC/SubtargetFeature.h"
+
+namespace llvm {
+
+namespace LoongArchABI {
+enum ABI {
+ ABI_ILP32S,
+ ABI_ILP32F,
+ ABI_ILP32D,
+ ABI_LP64S,
+ ABI_LP64F,
+ ABI_LP64D,
+ ABI_Unknown
+};
+
+ABI getTargetABI(StringRef ABIName);
+
+// Returns the register used to hold the stack pointer after realignment.
+MCRegister getBPReg();
+} // namespace LoongArchABI
+
+} // namespace llvm
+
+#endif // LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHBASEINFO_H
--- /dev/null
+//===-- LoongArchELFObjectWriter.cpp - LoongArch ELF Writer ---*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "MCTargetDesc/LoongArchMCTargetDesc.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCELFObjectWriter.h"
+#include "llvm/MC/MCFixup.h"
+#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/Support/ErrorHandling.h"
+
+using namespace llvm;
+
+namespace {
+class LoongArchELFObjectWriter : public MCELFObjectTargetWriter {
+public:
+ LoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit);
+
+ ~LoongArchELFObjectWriter() override;
+
+ // Return true if the given relocation must be with a symbol rather than
+ // section plus offset.
+ bool needsRelocateWithSymbol(const MCSymbol &Sym,
+ unsigned Type) const override {
+ return true;
+ }
+
+protected:
+ unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
+ const MCFixup &Fixup, bool IsPCRel) const override;
+};
+} // namespace
+
+LoongArchELFObjectWriter::LoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit)
+ : MCELFObjectTargetWriter(Is64Bit, OSABI, ELF::EM_LOONGARCH,
+ /*HasRelocationAddend*/ true) {}
+
+LoongArchELFObjectWriter::~LoongArchELFObjectWriter() {}
+
+unsigned LoongArchELFObjectWriter::getRelocType(MCContext &Ctx,
+ const MCValue &Target,
+ const MCFixup &Fixup,
+ bool IsPCRel) const {
+ const MCExpr *Expr = Fixup.getValue();
+ // Determine the type of the relocation
+ unsigned Kind = Fixup.getTargetKind();
+
+ if (Kind >= FirstLiteralRelocationKind)
+ return Kind - FirstLiteralRelocationKind;
+
+ switch (Kind) {
+ // TODO: Implement this when we defined fixup kind.
+ default:
+ return ELF::R_LARCH_NONE;
+ }
+}
+
+std::unique_ptr<MCObjectTargetWriter>
+llvm::createLoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit) {
+ return std::make_unique<LoongArchELFObjectWriter>(OSABI, Is64Bit);
+}
--- /dev/null
+//===- LoongArchInstPrinter.cpp - Convert LoongArch MCInst to asm syntax --===//
+//
+// 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 class prints an LoongArch MCInst to a .s file.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LoongArchInstPrinter.h"
+#include "LoongArchBaseInfo.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/MC/MCSymbol.h"
+using namespace llvm;
+
+#define DEBUG_TYPE "loongarch-asm-printer"
+
+// Include the auto-generated portion of the assembly writer.
+#define PRINT_ALIAS_INSTR
+#include "LoongArchGenAsmWriter.inc"
+
+void LoongArchInstPrinter::printInst(const MCInst *MI, uint64_t Address,
+ StringRef Annot,
+ const MCSubtargetInfo &STI,
+ raw_ostream &O) {
+ if (!printAliasInstr(MI, Address, STI, O))
+ printInstruction(MI, Address, STI, O);
+ printAnnotation(O, Annot);
+}
+
+void LoongArchInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const {
+ O << getRegisterName(RegNo);
+}
+
+void LoongArchInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI,
+ raw_ostream &O) {
+ const MCOperand &MO = MI->getOperand(OpNo);
+
+ if (MO.isReg()) {
+ printRegName(O, MO.getReg());
+ return;
+ }
+
+ if (MO.isImm()) {
+ O << MO.getImm();
+ return;
+ }
+
+ assert(MO.isExpr() && "Unknown operand kind in printOperand");
+ MO.getExpr()->print(O, &MAI);
+}
+
+const char *LoongArchInstPrinter::getRegisterName(unsigned RegNo) {
+ // Default print reg alias name
+ return getRegisterName(RegNo, LoongArch::RegAliasName);
+}
--- /dev/null
+//===-- LoongArchInstPrinter.h - Convert LoongArch MCInst to asm syntax ---===//
+//
+// 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 class prints a LoongArch MCInst to a .s file.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHINSTPRINTER_H
+#define LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHINSTPRINTER_H
+
+#include "MCTargetDesc/LoongArchMCTargetDesc.h"
+#include "llvm/MC/MCInstPrinter.h"
+
+namespace llvm {
+
+class LoongArchInstPrinter : public MCInstPrinter {
+public:
+ LoongArchInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
+ const MCRegisterInfo &MRI)
+ : MCInstPrinter(MAI, MII, MRI) {}
+
+ void printInst(const MCInst *MI, uint64_t Address, StringRef Annot,
+ const MCSubtargetInfo &STI, raw_ostream &O) override;
+ void printRegName(raw_ostream &O, unsigned RegNo) const override;
+
+ // Autogenerated by tblgen.
+ std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
+ void printInstruction(const MCInst *MI, uint64_t Address,
+ const MCSubtargetInfo &STI, raw_ostream &O);
+ bool printAliasInstr(const MCInst *MI, uint64_t Address,
+ const MCSubtargetInfo &STI, raw_ostream &O);
+ void printCustomAliasOperand(const MCInst *MI, uint64_t Address,
+ unsigned OpIdx, unsigned PrintMethodIdx,
+ const MCSubtargetInfo &STI, raw_ostream &O);
+ static const char *getRegisterName(unsigned RegNo);
+ static const char *getRegisterName(unsigned RegNo, unsigned AltIdx);
+
+private:
+ void printOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
+ raw_ostream &O);
+};
+} // namespace llvm
+
+#endif // LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHINSTPRINTER_H
--- /dev/null
+//===-- LoongArchMCAsmInfo.cpp - LoongArch Asm properties ------*- 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 declarations of the LoongArchMCAsmInfo properties.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LoongArchMCAsmInfo.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/MC/MCStreamer.h"
+
+using namespace llvm;
+
+void LoongArchMCAsmInfo::anchor() {}
+
+LoongArchMCAsmInfo::LoongArchMCAsmInfo(const Triple &TT) {
+ CodePointerSize = CalleeSaveStackSlotSize = TT.isArch64Bit() ? 8 : 4;
+ AlignmentIsInBytes = false;
+ Data8bitsDirective = "\t.byte\t";
+ Data16bitsDirective = "\t.half\t";
+ Data32bitsDirective = "\t.word\t";
+ Data64bitsDirective = "\t.dword\t";
+ ZeroDirective = "\t.space\t";
+ CommentString = "#";
+ SupportsDebugInformation = true;
+ ExceptionsType = ExceptionHandling::DwarfCFI;
+}
--- /dev/null
+//===-- LoongArchMCAsmInfo.h - LoongArch Asm Info --------------*- 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 declaration of the LoongArchMCAsmInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHMCASMINFO_H
+#define LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHMCASMINFO_H
+
+#include "llvm/MC/MCAsmInfoELF.h"
+
+namespace llvm {
+class Triple;
+
+class LoongArchMCAsmInfo : public MCAsmInfoELF {
+ void anchor() override;
+
+public:
+ explicit LoongArchMCAsmInfo(const Triple &TargetTriple);
+};
+
+} // namespace llvm
+
+#endif // LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHMCASMINFO_H
--- /dev/null
+//=- LoongArchMCCodeEmitter.cpp - Convert LoongArch code to machine code --===//
+//
+// 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 implements the LoongArchMCCodeEmitter class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MCTargetDesc/LoongArchBaseInfo.h"
+#include "MCTargetDesc/LoongArchMCTargetDesc.h"
+#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCInstBuilder.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/Support/EndianStream.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "mccodeemitter"
+
+namespace {
+class LoongArchMCCodeEmitter : public MCCodeEmitter {
+ LoongArchMCCodeEmitter(const LoongArchMCCodeEmitter &) = delete;
+ void operator=(const LoongArchMCCodeEmitter &) = delete;
+ MCContext &Ctx;
+ MCInstrInfo const &MCII;
+
+public:
+ LoongArchMCCodeEmitter(MCContext &ctx, MCInstrInfo const &MCII)
+ : Ctx(ctx), MCII(MCII) {}
+
+ ~LoongArchMCCodeEmitter() override {}
+
+ void encodeInstruction(const MCInst &MI, raw_ostream &OS,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const override;
+
+ /// TableGen'erated function for getting the binary encoding for an
+ /// instruction.
+ uint64_t getBinaryCodeForInstr(const MCInst &MI,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
+
+ /// Return binary encoding of operand. If the machine operand requires
+ /// relocation, record the relocation and return zero.
+ unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
+};
+} // end anonymous namespace
+
+unsigned
+LoongArchMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+
+ if (MO.isReg())
+ return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
+
+ if (MO.isImm())
+ return static_cast<unsigned>(MO.getImm());
+
+ llvm_unreachable("Unhandled expression!");
+ return 0;
+}
+
+void LoongArchMCCodeEmitter::encodeInstruction(
+ const MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
+ // Get byte count of instruction.
+ unsigned Size = Desc.getSize();
+
+ switch (Size) {
+ default:
+ llvm_unreachable("Unhandled encodeInstruction length!");
+ case 4: {
+ uint32_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
+ support::endian::write(OS, Bits, support::little);
+ break;
+ }
+ }
+}
+
+MCCodeEmitter *llvm::createLoongArchMCCodeEmitter(const MCInstrInfo &MCII,
+ const MCRegisterInfo &MRI,
+ MCContext &Ctx) {
+ return new LoongArchMCCodeEmitter(Ctx, MCII);
+}
+
+#include "LoongArchGenMCCodeEmitter.inc"
//
//===----------------------------------------------------------------------===//
+#include "LoongArchMCTargetDesc.h"
+#include "LoongArchBaseInfo.h"
+#include "LoongArchInstPrinter.h"
+#include "LoongArchMCAsmInfo.h"
+#include "TargetInfo/LoongArchTargetInfo.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCDwarf.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/Compiler.h"
-// FIXME: This is just a placeholder to make current commit buildable. Body of
-// this function will be filled in later commits.
-extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLoongArchTargetMC() {}
+#define GET_INSTRINFO_MC_DESC
+#include "LoongArchGenInstrInfo.inc"
+
+#define GET_REGINFO_MC_DESC
+#include "LoongArchGenRegisterInfo.inc"
+
+#define GET_SUBTARGETINFO_MC_DESC
+#include "LoongArchGenSubtargetInfo.inc"
+
+using namespace llvm;
+
+static MCRegisterInfo *createLoongArchMCRegisterInfo(const Triple &TT) {
+ MCRegisterInfo *X = new MCRegisterInfo();
+ InitLoongArchMCRegisterInfo(X, LoongArch::R1);
+ return X;
+}
+
+static MCInstrInfo *createLoongArchMCInstrInfo() {
+ MCInstrInfo *X = new MCInstrInfo();
+ InitLoongArchMCInstrInfo(X);
+ return X;
+}
+
+static MCSubtargetInfo *
+createLoongArchMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
+ if (CPU.empty())
+ CPU = TT.isArch64Bit() ? "la464" : "generic-la32";
+ return createLoongArchMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FS);
+}
+
+static MCAsmInfo *createLoongArchMCAsmInfo(const MCRegisterInfo &MRI,
+ const Triple &TT,
+ const MCTargetOptions &Options) {
+ MCAsmInfo *MAI = new LoongArchMCAsmInfo(TT);
+
+ MCRegister SP = MRI.getDwarfRegNum(LoongArch::R2, true);
+ MCCFIInstruction Inst = MCCFIInstruction::cfiDefCfa(nullptr, SP, 0);
+ MAI->addInitialFrameState(Inst);
+
+ return MAI;
+}
+
+static MCInstPrinter *createLoongArchMCInstPrinter(const Triple &T,
+ unsigned SyntaxVariant,
+ const MCAsmInfo &MAI,
+ const MCInstrInfo &MII,
+ const MCRegisterInfo &MRI) {
+ return new LoongArchInstPrinter(MAI, MII, MRI);
+}
+
+extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLoongArchTargetMC() {
+ for (Target *T : {&getTheLoongArch32Target(), &getTheLoongArch64Target()}) {
+ // Register the MC register info.
+ TargetRegistry::RegisterMCRegInfo(*T, createLoongArchMCRegisterInfo);
+
+ // Register the MC instruction info.
+ TargetRegistry::RegisterMCInstrInfo(*T, createLoongArchMCInstrInfo);
+
+ // Register the MC subtarget info.
+ TargetRegistry::RegisterMCSubtargetInfo(*T, createLoongArchMCSubtargetInfo);
+
+ // Register the MC asm info.
+ TargetRegistry::RegisterMCAsmInfo(*T, createLoongArchMCAsmInfo);
+
+ // Register the MC Code Emitter
+ TargetRegistry::RegisterMCCodeEmitter(*T, createLoongArchMCCodeEmitter);
+
+ // Register the asm backend.
+ TargetRegistry::RegisterMCAsmBackend(*T, createLoongArchAsmBackend);
+
+ // Register the MCInstPrinter.
+ TargetRegistry::RegisterMCInstPrinter(*T, createLoongArchMCInstPrinter);
+ }
+}
--- /dev/null
+//===- LoongArchMCTargetDesc.h - LoongArch Target Descriptions --*- 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 provides LoongArch specific target descriptions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHMCTARGETDESC_H
+#define LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHMCTARGETDESC_H
+
+#include "llvm/MC/MCTargetOptions.h"
+#include "llvm/Support/DataTypes.h"
+#include <memory>
+
+namespace llvm {
+class MCAsmBackend;
+class MCCodeEmitter;
+class MCContext;
+class MCInstrInfo;
+class MCObjectTargetWriter;
+class MCRegisterInfo;
+class MCSubtargetInfo;
+class Target;
+
+MCCodeEmitter *createLoongArchMCCodeEmitter(const MCInstrInfo &MCII,
+ const MCRegisterInfo &MRI,
+ MCContext &Ctx);
+
+MCAsmBackend *createLoongArchAsmBackend(const Target &T,
+ const MCSubtargetInfo &STI,
+ const MCRegisterInfo &MRI,
+ const MCTargetOptions &Options);
+
+std::unique_ptr<MCObjectTargetWriter>
+createLoongArchELFObjectWriter(uint8_t OSABI, bool Is64Bit);
+
+} // namespace llvm
+
+// Defines symbolic names for LoongArch registers.
+#define GET_REGINFO_ENUM
+#include "LoongArchGenRegisterInfo.inc"
+
+// Defines symbolic names for LoongArch instructions.
+#define GET_INSTRINFO_ENUM
+#include "LoongArchGenInstrInfo.inc"
+
+#define GET_SUBTARGETINFO_ENUM
+#include "LoongArchGenSubtargetInfo.inc"
+
+#endif // LLVM_LIB_TARGET_LOONGARCH_MCTARGETDESC_LOONGARCHMCTARGETDESC_H
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLoongArchTargetInfo() {
RegisterTarget<Triple::loongarch32, /*HasJIT=*/false> X(
- getTheLoongArch32Target(), "loongarch32", "LoongArch (32-bit)",
+ getTheLoongArch32Target(), "loongarch32", "32-bit LoongArch",
"LoongArch");
RegisterTarget<Triple::loongarch64, /*HasJIT=*/false> Y(
- getTheLoongArch64Target(), "loongarch64", "LoongArch (64-bit)",
+ getTheLoongArch64Target(), "loongarch64", "64-bit LoongArch",
"LoongArch");
}
; RUN: llc --version | FileCheck %s
-; CHECK: loongarch32 - LoongArch (32-bit)
-; CHECK: loongarch64 - LoongArch (64-bit)
+; CHECK: loongarch32 - 32-bit LoongArch
+; CHECK: loongarch64 - 64-bit LoongArch