[llvm] 064859b - [VE] Minimal codegen for empty functions
Simon Moll via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 15 00:56:02 PST 2020
Author: Kazushi (Jam) Marukawa
Date: 2020-01-15T09:55:16+01:00
New Revision: 064859bde79ccd221fd5196fd2d889014c5435c4
URL: https://github.com/llvm/llvm-project/commit/064859bde79ccd221fd5196fd2d889014c5435c4
DIFF: https://github.com/llvm/llvm-project/commit/064859bde79ccd221fd5196fd2d889014c5435c4.diff
LOG: [VE] Minimal codegen for empty functions
Summary:
This patch implements minimal VE code generation for empty function bodies (no args, no value return).
Contents
* empty function code generation test.
* Minimal function prologue & epilogue emission
* Instruction formats and instruction definitions as far as required for the empty function prologue & epilogue.
* I64 register class definitions.
Reviewed By: arsenm
Differential Revision: https://reviews.llvm.org/D72598
Added:
llvm/lib/Target/VE/InstPrinter/CMakeLists.txt
llvm/lib/Target/VE/InstPrinter/LLVMBuild.txt
llvm/lib/Target/VE/InstPrinter/VEInstPrinter.cpp
llvm/lib/Target/VE/InstPrinter/VEInstPrinter.h
llvm/lib/Target/VE/MCTargetDesc/VEMCAsmInfo.cpp
llvm/lib/Target/VE/MCTargetDesc/VEMCAsmInfo.h
llvm/lib/Target/VE/MCTargetDesc/VETargetStreamer.cpp
llvm/lib/Target/VE/MCTargetDesc/VETargetStreamer.h
llvm/lib/Target/VE/VE.td
llvm/lib/Target/VE/VEAsmPrinter.cpp
llvm/lib/Target/VE/VECallingConv.td
llvm/lib/Target/VE/VEFrameLowering.cpp
llvm/lib/Target/VE/VEFrameLowering.h
llvm/lib/Target/VE/VEISelDAGToDAG.cpp
llvm/lib/Target/VE/VEISelLowering.cpp
llvm/lib/Target/VE/VEISelLowering.h
llvm/lib/Target/VE/VEInstrFormats.td
llvm/lib/Target/VE/VEInstrInfo.cpp
llvm/lib/Target/VE/VEInstrInfo.h
llvm/lib/Target/VE/VEInstrInfo.td
llvm/lib/Target/VE/VEMCInstLower.cpp
llvm/lib/Target/VE/VERegisterInfo.cpp
llvm/lib/Target/VE/VERegisterInfo.h
llvm/lib/Target/VE/VERegisterInfo.td
llvm/lib/Target/VE/VESubtarget.cpp
llvm/lib/Target/VE/VESubtarget.h
llvm/lib/Target/VE/VETargetTransformInfo.h
llvm/test/CodeGen/VE/simple_prologue_epilogue.ll
Modified:
llvm/lib/Target/VE/CMakeLists.txt
llvm/lib/Target/VE/LLVMBuild.txt
llvm/lib/Target/VE/MCTargetDesc/CMakeLists.txt
llvm/lib/Target/VE/MCTargetDesc/LLVMBuild.txt
llvm/lib/Target/VE/MCTargetDesc/VEMCTargetDesc.cpp
llvm/lib/Target/VE/MCTargetDesc/VEMCTargetDesc.h
llvm/lib/Target/VE/VE.h
llvm/lib/Target/VE/VETargetMachine.cpp
llvm/lib/Target/VE/VETargetMachine.h
Removed:
################################################################################
diff --git a/llvm/lib/Target/VE/CMakeLists.txt b/llvm/lib/Target/VE/CMakeLists.txt
index a3eb8bae4ac4..661f0d41dc09 100644
--- a/llvm/lib/Target/VE/CMakeLists.txt
+++ b/llvm/lib/Target/VE/CMakeLists.txt
@@ -1,8 +1,25 @@
set(LLVM_TARGET_DEFINITIONS VE.td)
+tablegen(LLVM VEGenRegisterInfo.inc -gen-register-info)
+tablegen(LLVM VEGenInstrInfo.inc -gen-instr-info)
+tablegen(LLVM VEGenAsmWriter.inc -gen-asm-writer)
+tablegen(LLVM VEGenDAGISel.inc -gen-dag-isel)
+tablegen(LLVM VEGenSubtargetInfo.inc -gen-subtarget)
+tablegen(LLVM VEGenCallingConv.inc -gen-callingconv)
+add_public_tablegen_target(VECommonTableGen)
+
add_llvm_target(VECodeGen
+ VEAsmPrinter.cpp
+ VEFrameLowering.cpp
+ VEISelDAGToDAG.cpp
+ VEISelLowering.cpp
+ VEInstrInfo.cpp
+ VEMCInstLower.cpp
+ VERegisterInfo.cpp
+ VESubtarget.cpp
VETargetMachine.cpp
)
+add_subdirectory(InstPrinter)
add_subdirectory(TargetInfo)
add_subdirectory(MCTargetDesc)
diff --git a/llvm/lib/Target/VE/InstPrinter/CMakeLists.txt b/llvm/lib/Target/VE/InstPrinter/CMakeLists.txt
new file mode 100644
index 000000000000..7ddeebb9a7df
--- /dev/null
+++ b/llvm/lib/Target/VE/InstPrinter/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_llvm_component_library(LLVMVEAsmPrinter
+ VEInstPrinter.cpp
+ )
diff --git a/llvm/lib/Target/VE/InstPrinter/LLVMBuild.txt b/llvm/lib/Target/VE/InstPrinter/LLVMBuild.txt
new file mode 100644
index 000000000000..8cfaea7634e6
--- /dev/null
+++ b/llvm/lib/Target/VE/InstPrinter/LLVMBuild.txt
@@ -0,0 +1,22 @@
+;===- ./lib/Target/VE/InstPrinter/LLVMBuild.txt ----------------*- Conf -*--===;
+;
+; 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 is an LLVMBuild description file for the components in this subdirectory.
+;
+; For more information on the LLVMBuild system, please see:
+;
+; http://llvm.org/docs/LLVMBuild.html
+;
+;===------------------------------------------------------------------------===;
+
+[component_0]
+type = Library
+name = VEAsmPrinter
+parent = VE
+required_libraries = MC Support
+add_to_library_groups = VE
diff --git a/llvm/lib/Target/VE/InstPrinter/VEInstPrinter.cpp b/llvm/lib/Target/VE/InstPrinter/VEInstPrinter.cpp
new file mode 100644
index 000000000000..4e7bcd36c32a
--- /dev/null
+++ b/llvm/lib/Target/VE/InstPrinter/VEInstPrinter.cpp
@@ -0,0 +1,118 @@
+//===-- VEInstPrinter.cpp - Convert VE MCInst to assembly 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 VE MCInst to a .s file.
+//
+//===----------------------------------------------------------------------===//
+
+#include "VEInstPrinter.h"
+#include "VE.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "ve-asmprinter"
+
+// The generated AsmMatcher VEGenAsmWriter uses "VE" as the target
+// namespace.
+namespace llvm {
+namespace VE {
+using namespace VE;
+}
+} // namespace llvm
+
+#define GET_INSTRUCTION_NAME
+#define PRINT_ALIAS_INSTR
+#include "VEGenAsmWriter.inc"
+
+void VEInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
+ OS << '%' << StringRef(getRegisterName(RegNo)).lower();
+}
+
+void VEInstPrinter::printInst(const MCInst *MI, uint64_t Address,
+ StringRef Annot, const MCSubtargetInfo &STI,
+ raw_ostream &OS) {
+ if (!printAliasInstr(MI, STI, OS))
+ printInstruction(MI, Address, STI, OS);
+ printAnnotation(OS, Annot);
+}
+
+void VEInstPrinter::printOperand(const MCInst *MI, int opNum,
+ const MCSubtargetInfo &STI, raw_ostream &O) {
+ const MCOperand &MO = MI->getOperand(opNum);
+
+ if (MO.isReg()) {
+ printRegName(O, MO.getReg());
+ return;
+ }
+
+ if (MO.isImm()) {
+ switch (MI->getOpcode()) {
+ default:
+ // Expects signed 32bit literals
+ assert(isInt<32>(MO.getImm()) && "Immediate too large");
+ int32_t TruncatedImm = static_cast<int32_t>(MO.getImm());
+ O << TruncatedImm;
+ return;
+ }
+ }
+
+ assert(MO.isExpr() && "Unknown operand kind in printOperand");
+ MO.getExpr()->print(O, &MAI);
+}
+
+void VEInstPrinter::printMemASXOperand(const MCInst *MI, int opNum,
+ const MCSubtargetInfo &STI,
+ raw_ostream &O, const char *Modifier) {
+ // If this is an ADD operand, emit it like normal operands.
+ if (Modifier && !strcmp(Modifier, "arith")) {
+ printOperand(MI, opNum, STI, O);
+ O << ", ";
+ printOperand(MI, opNum + 1, STI, O);
+ return;
+ }
+
+ const MCOperand &MO = MI->getOperand(opNum + 1);
+ if (!MO.isImm() || MO.getImm() != 0) {
+ printOperand(MI, opNum + 1, STI, O);
+ }
+ O << "(,";
+ printOperand(MI, opNum, STI, O);
+ O << ")";
+}
+
+void VEInstPrinter::printMemASOperand(const MCInst *MI, int opNum,
+ const MCSubtargetInfo &STI,
+ raw_ostream &O, const char *Modifier) {
+ // If this is an ADD operand, emit it like normal operands.
+ if (Modifier && !strcmp(Modifier, "arith")) {
+ printOperand(MI, opNum, STI, O);
+ O << ", ";
+ printOperand(MI, opNum + 1, STI, O);
+ return;
+ }
+
+ const MCOperand &MO = MI->getOperand(opNum + 1);
+ if (!MO.isImm() || MO.getImm() != 0) {
+ printOperand(MI, opNum + 1, STI, O);
+ }
+ O << "(";
+ printOperand(MI, opNum, STI, O);
+ O << ")";
+}
+
+void VEInstPrinter::printCCOperand(const MCInst *MI, int opNum,
+ const MCSubtargetInfo &STI, raw_ostream &O) {
+ int CC = (int)MI->getOperand(opNum).getImm();
+ O << VECondCodeToString((VECC::CondCodes)CC);
+}
diff --git a/llvm/lib/Target/VE/InstPrinter/VEInstPrinter.h b/llvm/lib/Target/VE/InstPrinter/VEInstPrinter.h
new file mode 100644
index 000000000000..05a53d59e878
--- /dev/null
+++ b/llvm/lib/Target/VE/InstPrinter/VEInstPrinter.h
@@ -0,0 +1,49 @@
+//===-- VEInstPrinter.h - Convert VE MCInst to assembly 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 VE MCInst to a .s file.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_VE_INSTPRINTER_VEINSTPRINTER_H
+#define LLVM_LIB_TARGET_VE_INSTPRINTER_VEINSTPRINTER_H
+
+#include "llvm/MC/MCInstPrinter.h"
+
+namespace llvm {
+
+class VEInstPrinter : public MCInstPrinter {
+public:
+ VEInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
+ const MCRegisterInfo &MRI)
+ : MCInstPrinter(MAI, MII, MRI) {}
+
+ void printRegName(raw_ostream &OS, unsigned RegNo) const override;
+ void printInst(const MCInst *MI, uint64_t Address, StringRef Annot,
+ const MCSubtargetInfo &STI, raw_ostream &OS) override;
+
+ // Autogenerated by tblgen.
+ bool printAliasInstr(const MCInst *, const MCSubtargetInfo &, raw_ostream &);
+ void printInstruction(const MCInst *, uint64_t, const MCSubtargetInfo &,
+ raw_ostream &);
+ static const char *getRegisterName(unsigned RegNo);
+
+ void printOperand(const MCInst *MI, int opNum, const MCSubtargetInfo &STI,
+ raw_ostream &OS);
+ void printMemASXOperand(const MCInst *MI, int opNum,
+ const MCSubtargetInfo &STI, raw_ostream &OS,
+ const char *Modifier = nullptr);
+ void printMemASOperand(const MCInst *MI, int opNum,
+ const MCSubtargetInfo &STI, raw_ostream &OS,
+ const char *Modifier = nullptr);
+ void printCCOperand(const MCInst *MI, int opNum, const MCSubtargetInfo &STI,
+ raw_ostream &OS);
+};
+} // namespace llvm
+
+#endif
diff --git a/llvm/lib/Target/VE/LLVMBuild.txt b/llvm/lib/Target/VE/LLVMBuild.txt
index b45efd45c8ac..4e1a5ed898ca 100644
--- a/llvm/lib/Target/VE/LLVMBuild.txt
+++ b/llvm/lib/Target/VE/LLVMBuild.txt
@@ -15,19 +15,20 @@
;===------------------------------------------------------------------------===;
[common]
-subdirectories = MCTargetDesc TargetInfo
+subdirectories = InstPrinter MCTargetDesc TargetInfo
[component_0]
type = TargetGroup
name = VE
parent = Target
has_asmparser = 0
-has_asmprinter = 0
+has_asmprinter = 1
[component_1]
type = Library
name = VECodeGen
parent = VE
-required_libraries = Analysis AsmPrinter CodeGen Core MC SelectionDAG
+required_libraries = Analysis AsmPrinter CodeGen Core
+ MC SelectionDAG VEAsmPrinter
VEDesc VEInfo Support Target
add_to_library_groups = VE
diff --git a/llvm/lib/Target/VE/MCTargetDesc/CMakeLists.txt b/llvm/lib/Target/VE/MCTargetDesc/CMakeLists.txt
index fa2fefbe47f0..6be295e05650 100644
--- a/llvm/lib/Target/VE/MCTargetDesc/CMakeLists.txt
+++ b/llvm/lib/Target/VE/MCTargetDesc/CMakeLists.txt
@@ -1,3 +1,5 @@
-add_llvm_library(LLVMVEDesc
+add_llvm_component_library(LLVMVEDesc
+ VEMCAsmInfo.cpp
VEMCTargetDesc.cpp
+ VETargetStreamer.cpp
)
diff --git a/llvm/lib/Target/VE/MCTargetDesc/LLVMBuild.txt b/llvm/lib/Target/VE/MCTargetDesc/LLVMBuild.txt
index e585042e60bb..3fddd5268bee 100644
--- a/llvm/lib/Target/VE/MCTargetDesc/LLVMBuild.txt
+++ b/llvm/lib/Target/VE/MCTargetDesc/LLVMBuild.txt
@@ -18,5 +18,5 @@
type = Library
name = VEDesc
parent = VE
-required_libraries = MC VEInfo Support
+required_libraries = MC VEAsmPrinter VEInfo Support
add_to_library_groups = VE
diff --git a/llvm/lib/Target/VE/MCTargetDesc/VEMCAsmInfo.cpp b/llvm/lib/Target/VE/MCTargetDesc/VEMCAsmInfo.cpp
new file mode 100644
index 000000000000..9f29fc092c69
--- /dev/null
+++ b/llvm/lib/Target/VE/MCTargetDesc/VEMCAsmInfo.cpp
@@ -0,0 +1,40 @@
+//===- VEMCAsmInfo.cpp - VE asm properties --------------------------------===//
+//
+// 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 VEMCAsmInfo properties.
+//
+//===----------------------------------------------------------------------===//
+
+#include "VEMCAsmInfo.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCTargetOptions.h"
+
+using namespace llvm;
+
+void VEELFMCAsmInfo::anchor() {}
+
+VEELFMCAsmInfo::VEELFMCAsmInfo(const Triple &TheTriple) {
+
+ CodePointerSize = CalleeSaveStackSlotSize = 8;
+ MaxInstLength = MinInstAlignment = 8;
+
+ // VE uses ".*byte" directive for unaligned data.
+ Data8bitsDirective = "\t.byte\t";
+ Data16bitsDirective = "\t.2byte\t";
+ Data32bitsDirective = "\t.4byte\t";
+ Data64bitsDirective = "\t.8byte\t";
+
+ // Uses '.section' before '.bss' directive. VE requires this although
+ // assembler manual says sinple '.bss' is supported.
+ UsesELFSectionDirectiveForBSS = true;
+
+ SupportsDebugInformation = true;
+}
diff --git a/llvm/lib/Target/VE/MCTargetDesc/VEMCAsmInfo.h b/llvm/lib/Target/VE/MCTargetDesc/VEMCAsmInfo.h
new file mode 100644
index 000000000000..6557d68b383c
--- /dev/null
+++ b/llvm/lib/Target/VE/MCTargetDesc/VEMCAsmInfo.h
@@ -0,0 +1,31 @@
+//===- VEMCAsmInfo.h - VE 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 declaration of the VEMCAsmInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_VE_MCTARGETDESC_VEMCASMINFO_H
+#define LLVM_LIB_TARGET_VE_MCTARGETDESC_VEMCASMINFO_H
+
+#include "llvm/MC/MCAsmInfoELF.h"
+
+namespace llvm {
+
+class Triple;
+
+class VEELFMCAsmInfo : public MCAsmInfoELF {
+ void anchor() override;
+
+public:
+ explicit VEELFMCAsmInfo(const Triple &TheTriple);
+};
+
+} // namespace llvm
+
+#endif // LLVM_LIB_TARGET_VE_MCTARGETDESC_VEMCASMINFO_H
diff --git a/llvm/lib/Target/VE/MCTargetDesc/VEMCTargetDesc.cpp b/llvm/lib/Target/VE/MCTargetDesc/VEMCTargetDesc.cpp
index 7067f34a016f..b228617058a6 100644
--- a/llvm/lib/Target/VE/MCTargetDesc/VEMCTargetDesc.cpp
+++ b/llvm/lib/Target/VE/MCTargetDesc/VEMCTargetDesc.cpp
@@ -11,9 +11,96 @@
//===----------------------------------------------------------------------===//
#include "VEMCTargetDesc.h"
+#include "InstPrinter/VEInstPrinter.h"
+#include "VEMCAsmInfo.h"
+#include "VETargetStreamer.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/TargetRegistry.h"
using namespace llvm;
+#define GET_INSTRINFO_MC_DESC
+#include "VEGenInstrInfo.inc"
+
+#define GET_SUBTARGETINFO_MC_DESC
+#include "VEGenSubtargetInfo.inc"
+
+#define GET_REGINFO_MC_DESC
+#include "VEGenRegisterInfo.inc"
+
+static MCAsmInfo *createVEMCAsmInfo(const MCRegisterInfo &MRI, const Triple &TT,
+ const MCTargetOptions &Options) {
+ MCAsmInfo *MAI = new VEELFMCAsmInfo(TT);
+ unsigned Reg = MRI.getDwarfRegNum(VE::SX11, true);
+ MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(nullptr, Reg, 0);
+ MAI->addInitialFrameState(Inst);
+ return MAI;
+}
+
+static MCInstrInfo *createVEMCInstrInfo() {
+ MCInstrInfo *X = new MCInstrInfo();
+ InitVEMCInstrInfo(X);
+ return X;
+}
+
+static MCRegisterInfo *createVEMCRegisterInfo(const Triple &TT) {
+ MCRegisterInfo *X = new MCRegisterInfo();
+ InitVEMCRegisterInfo(X, VE::SX10);
+ return X;
+}
+
+static MCSubtargetInfo *createVEMCSubtargetInfo(const Triple &TT, StringRef CPU,
+ StringRef FS) {
+ if (CPU.empty())
+ CPU = "ve";
+ return createVEMCSubtargetInfoImpl(TT, CPU, FS);
+}
+
+static MCTargetStreamer *
+createObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {
+ return new VETargetELFStreamer(S);
+}
+
+static MCTargetStreamer *createTargetAsmStreamer(MCStreamer &S,
+ formatted_raw_ostream &OS,
+ MCInstPrinter *InstPrint,
+ bool isVerboseAsm) {
+ return new VETargetAsmStreamer(S, OS);
+}
+
+static MCInstPrinter *createVEMCInstPrinter(const Triple &T,
+ unsigned SyntaxVariant,
+ const MCAsmInfo &MAI,
+ const MCInstrInfo &MII,
+ const MCRegisterInfo &MRI) {
+ return new VEInstPrinter(MAI, MII, MRI);
+}
+
extern "C" void LLVMInitializeVETargetMC() {
- // TODO
+ // Register the MC asm info.
+ RegisterMCAsmInfoFn X(getTheVETarget(), createVEMCAsmInfo);
+
+ for (Target *T : {&getTheVETarget()}) {
+ // Register the MC instruction info.
+ TargetRegistry::RegisterMCInstrInfo(*T, createVEMCInstrInfo);
+
+ // Register the MC register info.
+ TargetRegistry::RegisterMCRegInfo(*T, createVEMCRegisterInfo);
+
+ // Register the MC subtarget info.
+ TargetRegistry::RegisterMCSubtargetInfo(*T, createVEMCSubtargetInfo);
+
+ // Register the object target streamer.
+ TargetRegistry::RegisterObjectTargetStreamer(*T,
+ createObjectTargetStreamer);
+
+ // Register the asm streamer.
+ TargetRegistry::RegisterAsmTargetStreamer(*T, createTargetAsmStreamer);
+
+ // Register the MCInstPrinter
+ TargetRegistry::RegisterMCInstPrinter(*T, createVEMCInstPrinter);
+ }
}
diff --git a/llvm/lib/Target/VE/MCTargetDesc/VEMCTargetDesc.h b/llvm/lib/Target/VE/MCTargetDesc/VEMCTargetDesc.h
index a7969042606c..24a5c8209be2 100644
--- a/llvm/lib/Target/VE/MCTargetDesc/VEMCTargetDesc.h
+++ b/llvm/lib/Target/VE/MCTargetDesc/VEMCTargetDesc.h
@@ -18,10 +18,36 @@
#include <memory>
namespace llvm {
-
+class MCAsmBackend;
+class MCCodeEmitter;
+class MCContext;
+class MCInstrInfo;
+class MCObjectWriter;
+class MCRegisterInfo;
+class MCSubtargetInfo;
+class MCTargetOptions;
class Target;
+class Triple;
+class StringRef;
+class raw_pwrite_stream;
+class raw_ostream;
+
Target &getTheVETarget();
-} // end llvm namespace
+} // namespace llvm
+
+// Defines symbolic names for VE registers. This defines a mapping from
+// register name to register number.
+//
+#define GET_REGINFO_ENUM
+#include "VEGenRegisterInfo.inc"
+
+// Defines symbolic names for the VE instructions.
+//
+#define GET_INSTRINFO_ENUM
+#include "VEGenInstrInfo.inc"
+
+#define GET_SUBTARGETINFO_ENUM
+#include "VEGenSubtargetInfo.inc"
#endif
diff --git a/llvm/lib/Target/VE/MCTargetDesc/VETargetStreamer.cpp b/llvm/lib/Target/VE/MCTargetDesc/VETargetStreamer.cpp
new file mode 100644
index 000000000000..dfe94bbaaa4b
--- /dev/null
+++ b/llvm/lib/Target/VE/MCTargetDesc/VETargetStreamer.cpp
@@ -0,0 +1,44 @@
+//===-- VETargetStreamer.cpp - VE Target Streamer Methods -----------------===//
+//
+// 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 VE specific target streamer methods.
+//
+//===----------------------------------------------------------------------===//
+
+#include "VETargetStreamer.h"
+#include "InstPrinter/VEInstPrinter.h"
+#include "llvm/Support/FormattedStream.h"
+
+using namespace llvm;
+
+// pin vtable to this file
+VETargetStreamer::VETargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {}
+
+void VETargetStreamer::anchor() {}
+
+VETargetAsmStreamer::VETargetAsmStreamer(MCStreamer &S,
+ formatted_raw_ostream &OS)
+ : VETargetStreamer(S), OS(OS) {}
+
+void VETargetAsmStreamer::emitVERegisterIgnore(unsigned reg) {
+ OS << "\t.register "
+ << "%" << StringRef(VEInstPrinter::getRegisterName(reg)).lower()
+ << ", #ignore\n";
+}
+
+void VETargetAsmStreamer::emitVERegisterScratch(unsigned reg) {
+ OS << "\t.register "
+ << "%" << StringRef(VEInstPrinter::getRegisterName(reg)).lower()
+ << ", #scratch\n";
+}
+
+VETargetELFStreamer::VETargetELFStreamer(MCStreamer &S) : VETargetStreamer(S) {}
+
+MCELFStreamer &VETargetELFStreamer::getStreamer() {
+ return static_cast<MCELFStreamer &>(Streamer);
+}
diff --git a/llvm/lib/Target/VE/MCTargetDesc/VETargetStreamer.h b/llvm/lib/Target/VE/MCTargetDesc/VETargetStreamer.h
new file mode 100644
index 000000000000..6f6a0d4b02d7
--- /dev/null
+++ b/llvm/lib/Target/VE/MCTargetDesc/VETargetStreamer.h
@@ -0,0 +1,47 @@
+//===-- VETargetStreamer.h - VE Target Streamer ----------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_VE_VETARGETSTREAMER_H
+#define LLVM_LIB_TARGET_VE_VETARGETSTREAMER_H
+
+#include "llvm/MC/MCELFStreamer.h"
+#include "llvm/MC/MCStreamer.h"
+
+namespace llvm {
+class VETargetStreamer : public MCTargetStreamer {
+ virtual void anchor();
+
+public:
+ VETargetStreamer(MCStreamer &S);
+ /// Emit ".register <reg>, #ignore".
+ virtual void emitVERegisterIgnore(unsigned reg) = 0;
+ /// Emit ".register <reg>, #scratch".
+ virtual void emitVERegisterScratch(unsigned reg) = 0;
+};
+
+// This part is for ascii assembly output
+class VETargetAsmStreamer : public VETargetStreamer {
+ formatted_raw_ostream &OS;
+
+public:
+ VETargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS);
+ void emitVERegisterIgnore(unsigned reg) override;
+ void emitVERegisterScratch(unsigned reg) override;
+};
+
+// This part is for ELF object output
+class VETargetELFStreamer : public VETargetStreamer {
+public:
+ VETargetELFStreamer(MCStreamer &S);
+ MCELFStreamer &getStreamer();
+ void emitVERegisterIgnore(unsigned reg) override {}
+ void emitVERegisterScratch(unsigned reg) override {}
+};
+} // namespace llvm
+
+#endif
diff --git a/llvm/lib/Target/VE/VE.h b/llvm/lib/Target/VE/VE.h
index 51d3e701f8ec..9b61f2b63f36 100644
--- a/llvm/lib/Target/VE/VE.h
+++ b/llvm/lib/Target/VE/VE.h
@@ -15,5 +15,95 @@
#define LLVM_LIB_TARGET_VE_VE_H
#include "MCTargetDesc/VEMCTargetDesc.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Target/TargetMachine.h"
+namespace llvm {
+class FunctionPass;
+class VETargetMachine;
+class formatted_raw_ostream;
+class AsmPrinter;
+class MCInst;
+class MachineInstr;
+
+FunctionPass *createVEISelDag(VETargetMachine &TM);
+FunctionPass *createVEPromoteToI1Pass();
+
+void LowerVEMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
+ AsmPrinter &AP);
+} // namespace llvm
+
+namespace llvm {
+// Enums corresponding to VE condition codes, both icc's and fcc's. These
+// values must be kept in sync with the ones in the .td file.
+namespace VECC {
+enum CondCodes {
+ // Integer comparison
+ CC_IG = 0, // Greater
+ CC_IL = 1, // Less
+ CC_INE = 2, // Not Equal
+ CC_IEQ = 3, // Equal
+ CC_IGE = 4, // Greater or Equal
+ CC_ILE = 5, // Less or Equal
+
+ // Floating point comparison
+ CC_AF = 0 + 6, // Never
+ CC_G = 1 + 6, // Greater
+ CC_L = 2 + 6, // Less
+ CC_NE = 3 + 6, // Not Equal
+ CC_EQ = 4 + 6, // Equal
+ CC_GE = 5 + 6, // Greater or Equal
+ CC_LE = 6 + 6, // Less or Equal
+ CC_NUM = 7 + 6, // Number
+ CC_NAN = 8 + 6, // NaN
+ CC_GNAN = 9 + 6, // Greater or NaN
+ CC_LNAN = 10 + 6, // Less or NaN
+ CC_NENAN = 11 + 6, // Not Equal or NaN
+ CC_EQNAN = 12 + 6, // Equal or NaN
+ CC_GENAN = 13 + 6, // Greater or Equal or NaN
+ CC_LENAN = 14 + 6, // Less or Equal or NaN
+ CC_AT = 15 + 6, // Always
+};
+}
+
+inline static const char *VECondCodeToString(VECC::CondCodes CC) {
+ switch (CC) {
+ case VECC::CC_IG: return "gt";
+ case VECC::CC_IL: return "lt";
+ case VECC::CC_INE: return "ne";
+ case VECC::CC_IEQ: return "eq";
+ case VECC::CC_IGE: return "ge";
+ case VECC::CC_ILE: return "le";
+ case VECC::CC_AF: return "af";
+ case VECC::CC_G: return "gt";
+ case VECC::CC_L: return "lt";
+ case VECC::CC_NE: return "ne";
+ case VECC::CC_EQ: return "eq";
+ case VECC::CC_GE: return "ge";
+ case VECC::CC_LE: return "le";
+ case VECC::CC_NUM: return "num";
+ case VECC::CC_NAN: return "nan";
+ case VECC::CC_GNAN: return "gtnan";
+ case VECC::CC_LNAN: return "ltnan";
+ case VECC::CC_NENAN: return "nenan";
+ case VECC::CC_EQNAN: return "eqnan";
+ case VECC::CC_GENAN: return "genan";
+ case VECC::CC_LENAN: return "lenan";
+ case VECC::CC_AT: return "at";
+ }
+ llvm_unreachable("Invalid cond code");
+}
+
+// Different to Hi_32/Lo_32 the HI32 and LO32 functions
+// preserve the correct numerical value
+// on the LLVM data type for MC immediates (int64_t).
+inline static int64_t HI32(int64_t imm) {
+ return (int32_t)(imm >> 32);
+}
+
+inline static int64_t LO32(int64_t imm) {
+ return (int32_t)(imm);
+}
+
+} // namespace llvm
#endif
diff --git a/llvm/lib/Target/VE/VE.td b/llvm/lib/Target/VE/VE.td
new file mode 100644
index 000000000000..7404321b1a06
--- /dev/null
+++ b/llvm/lib/Target/VE/VE.td
@@ -0,0 +1,56 @@
+//===-- VE.td - Describe the VE Target Machine -------------*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Target-independent interfaces which we are implementing
+//===----------------------------------------------------------------------===//
+
+include "llvm/Target/Target.td"
+
+//===----------------------------------------------------------------------===//
+// VE Subtarget features.
+//
+
+//===----------------------------------------------------------------------===//
+// Register File, Calling Conv, Instruction Descriptions
+//===----------------------------------------------------------------------===//
+
+include "VERegisterInfo.td"
+include "VECallingConv.td"
+include "VEInstrInfo.td"
+
+def VEInstrInfo : InstrInfo;
+
+//===----------------------------------------------------------------------===//
+// VE processors supported.
+//===----------------------------------------------------------------------===//
+
+class Proc<string Name, list<SubtargetFeature> Features>
+ : Processor<Name, NoItineraries, Features>;
+
+def : Proc<"ve", []>;
+
+//===----------------------------------------------------------------------===//
+// Declare the target which we are implementing
+//===----------------------------------------------------------------------===//
+
+def VEAsmWriter : AsmWriter {
+ string AsmWriterClassName = "InstPrinter";
+ int PassSubtarget = 1;
+ int Variant = 0;
+}
+
+def VE : Target {
+ // Pull in Instruction Info:
+ let InstructionSet = VEInstrInfo;
+ let AssemblyWriters = [VEAsmWriter];
+ let AllowRegisterRenaming = 1;
+}
diff --git a/llvm/lib/Target/VE/VEAsmPrinter.cpp b/llvm/lib/Target/VE/VEAsmPrinter.cpp
new file mode 100644
index 000000000000..918f2a1acdaf
--- /dev/null
+++ b/llvm/lib/Target/VE/VEAsmPrinter.cpp
@@ -0,0 +1,78 @@
+//===-- VEAsmPrinter.cpp - VE LLVM assembly writer ------------------------===//
+//
+// 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 VE assembly language.
+//
+//===----------------------------------------------------------------------===//
+
+#include "InstPrinter/VEInstPrinter.h"
+#include "MCTargetDesc/VETargetStreamer.h"
+#include "VE.h"
+#include "VEInstrInfo.h"
+#include "VETargetMachine.h"
+#include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineModuleInfoImpls.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
+#include "llvm/IR/Mangler.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstBuilder.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
+
+#define DEBUG_TYPE "ve-asmprinter"
+
+namespace {
+class VEAsmPrinter : public AsmPrinter {
+ VETargetStreamer &getTargetStreamer() {
+ return static_cast<VETargetStreamer &>(*OutStreamer->getTargetStreamer());
+ }
+
+public:
+ explicit VEAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer)
+ : AsmPrinter(TM, std::move(Streamer)) {}
+
+ StringRef getPassName() const override { return "VE Assembly Printer"; }
+
+ void EmitInstruction(const MachineInstr *MI) override;
+
+ static const char *getRegisterName(unsigned RegNo) {
+ return VEInstPrinter::getRegisterName(RegNo);
+ }
+};
+} // end of anonymous namespace
+
+void VEAsmPrinter::EmitInstruction(const MachineInstr *MI) {
+
+ switch (MI->getOpcode()) {
+ default:
+ break;
+ case TargetOpcode::DBG_VALUE:
+ // FIXME: Debug Value.
+ return;
+ }
+ MachineBasicBlock::const_instr_iterator I = MI->getIterator();
+ MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end();
+ do {
+ MCInst TmpInst;
+ LowerVEMachineInstrToMCInst(&*I, TmpInst, *this);
+ EmitToStreamer(*OutStreamer, TmpInst);
+ } while ((++I != E) && I->isInsideBundle()); // Delay slot check.
+}
+
+// Force static initialization.
+extern "C" void LLVMInitializeVEAsmPrinter() {
+ RegisterAsmPrinter<VEAsmPrinter> X(getTheVETarget());
+}
diff --git a/llvm/lib/Target/VE/VECallingConv.td b/llvm/lib/Target/VE/VECallingConv.td
new file mode 100644
index 000000000000..1a9097c79dd4
--- /dev/null
+++ b/llvm/lib/Target/VE/VECallingConv.td
@@ -0,0 +1,19 @@
+//===-- VECallingConv.td - Calling Conventions VE ----------*- 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 VE architectures.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Aurora VE
+//===----------------------------------------------------------------------===//
+
+// Callee-saved registers
+def CSR : CalleeSavedRegs<(add (sequence "SX%u", 18, 33))>;
+def CSR_NoRegs : CalleeSavedRegs<(add)>;
diff --git a/llvm/lib/Target/VE/VEFrameLowering.cpp b/llvm/lib/Target/VE/VEFrameLowering.cpp
new file mode 100644
index 000000000000..ef5b5f055911
--- /dev/null
+++ b/llvm/lib/Target/VE/VEFrameLowering.cpp
@@ -0,0 +1,325 @@
+//===-- VEFrameLowering.cpp - VE Frame Information ------------------------===//
+//
+// 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 VE implementation of TargetFrameLowering class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "VEFrameLowering.h"
+#include "VEInstrInfo.h"
+#include "VESubtarget.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/RegisterScavenging.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Function.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Target/TargetOptions.h"
+#include "llvm/Support/MathExtras.h"
+
+using namespace llvm;
+
+VEFrameLowering::VEFrameLowering(const VESubtarget &ST)
+ : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, Align(16), 0,
+ Align(16)) {}
+
+void VEFrameLowering::emitPrologueInsns(MachineFunction &MF,
+ MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MBBI,
+ int NumBytes,
+ bool RequireFPUpdate) const {
+
+ DebugLoc dl;
+ const VEInstrInfo &TII =
+ *static_cast<const VEInstrInfo *>(MF.getSubtarget().getInstrInfo());
+ // Insert following codes here as prologue
+ //
+ // st %fp, 0(,%sp)
+ // st %lr, 8(,%sp)
+ // st %got, 24(,%sp)
+ // st %plt, 32(,%sp)
+ // or %fp, 0, %sp
+
+ BuildMI(MBB, MBBI, dl, TII.get(VE::STSri))
+ .addReg(VE::SX11)
+ .addImm(0)
+ .addReg(VE::SX9);
+ BuildMI(MBB, MBBI, dl, TII.get(VE::STSri))
+ .addReg(VE::SX11)
+ .addImm(8)
+ .addReg(VE::SX10);
+ BuildMI(MBB, MBBI, dl, TII.get(VE::STSri))
+ .addReg(VE::SX11)
+ .addImm(24)
+ .addReg(VE::SX15);
+ BuildMI(MBB, MBBI, dl, TII.get(VE::STSri))
+ .addReg(VE::SX11)
+ .addImm(32)
+ .addReg(VE::SX16);
+ BuildMI(MBB, MBBI, dl, TII.get(VE::ORri), VE::SX9)
+ .addReg(VE::SX11)
+ .addImm(0);
+}
+
+void VEFrameLowering::emitEpilogueInsns(MachineFunction &MF,
+ MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MBBI,
+ int NumBytes,
+ bool RequireFPUpdate) const {
+
+ DebugLoc dl;
+ const VEInstrInfo &TII =
+ *static_cast<const VEInstrInfo *>(MF.getSubtarget().getInstrInfo());
+ // Insert following codes here as epilogue
+ //
+ // or %sp, 0, %fp
+ // ld %got, 32(,%sp)
+ // ld %plt, 24(,%sp)
+ // ld %lr, 8(,%sp)
+ // ld %fp, 0(,%sp)
+
+ BuildMI(MBB, MBBI, dl, TII.get(VE::ORri), VE::SX11)
+ .addReg(VE::SX9)
+ .addImm(0);
+ BuildMI(MBB, MBBI, dl, TII.get(VE::LDSri), VE::SX16)
+ .addReg(VE::SX11)
+ .addImm(32);
+ BuildMI(MBB, MBBI, dl, TII.get(VE::LDSri), VE::SX15)
+ .addReg(VE::SX11)
+ .addImm(24);
+ BuildMI(MBB, MBBI, dl, TII.get(VE::LDSri), VE::SX10)
+ .addReg(VE::SX11)
+ .addImm(8);
+ BuildMI(MBB, MBBI, dl, TII.get(VE::LDSri), VE::SX9)
+ .addReg(VE::SX11)
+ .addImm(0);
+}
+
+void VEFrameLowering::emitSPAdjustment(MachineFunction &MF,
+ MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MBBI,
+ int NumBytes) const {
+ DebugLoc dl;
+ const VEInstrInfo &TII =
+ *static_cast<const VEInstrInfo *>(MF.getSubtarget().getInstrInfo());
+
+ if (NumBytes >= -64 && NumBytes < 63) {
+ BuildMI(MBB, MBBI, dl, TII.get(VE::ADXri), VE::SX11)
+ .addReg(VE::SX11)
+ .addImm(NumBytes);
+ return;
+ }
+
+ // Emit following codes. This clobbers SX13 which we always know is
+ // available here.
+ // lea %s13,%lo(NumBytes)
+ // and %s13,%s13,(32)0
+ // lea.sl %sp,%hi(NumBytes)(%sp, %s13)
+ BuildMI(MBB, MBBI, dl, TII.get(VE::LEAzzi), VE::SX13)
+ .addImm(LO32(NumBytes));
+ BuildMI(MBB, MBBI, dl, TII.get(VE::ANDrm0), VE::SX13)
+ .addReg(VE::SX13)
+ .addImm(32);
+ BuildMI(MBB, MBBI, dl, TII.get(VE::LEASLrri), VE::SX11)
+ .addReg(VE::SX11)
+ .addReg(VE::SX13)
+ .addImm(HI32(NumBytes));
+}
+
+void VEFrameLowering::emitSPExtend(MachineFunction &MF, MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MBBI,
+ int NumBytes) const {
+ DebugLoc dl;
+ const VEInstrInfo &TII =
+ *static_cast<const VEInstrInfo *>(MF.getSubtarget().getInstrInfo());
+
+ // Emit following codes. It is not possible to insert multiple
+ // BasicBlocks in PEI pass, so we emit two pseudo instructions here.
+ //
+ // EXTEND_STACK // pseudo instrcution
+ // EXTEND_STACK_GUARD // pseudo instrcution
+ //
+ // EXTEND_STACK pseudo will be converted by ExpandPostRA pass into
+ // following instructions with multiple basic blocks later.
+ //
+ // thisBB:
+ // brge.l.t %sp, %sl, sinkBB
+ // syscallBB:
+ // ld %s61, 0x18(, %tp) // load param area
+ // or %s62, 0, %s0 // spill the value of %s0
+ // lea %s63, 0x13b // syscall # of grow
+ // shm.l %s63, 0x0(%s61) // store syscall # at addr:0
+ // shm.l %sl, 0x8(%s61) // store old limit at addr:8
+ // shm.l %sp, 0x10(%s61) // store new limit at addr:16
+ // monc // call monitor
+ // or %s0, 0, %s62 // restore the value of %s0
+ // sinkBB:
+ //
+ // EXTEND_STACK_GUARD pseudo will be simply eliminated by ExpandPostRA
+ // pass. This pseudo is required to be at the next of EXTEND_STACK
+ // pseudo in order to protect iteration loop in ExpandPostRA.
+
+ BuildMI(MBB, MBBI, dl, TII.get(VE::EXTEND_STACK));
+ BuildMI(MBB, MBBI, dl, TII.get(VE::EXTEND_STACK_GUARD));
+}
+
+void VEFrameLowering::emitPrologue(MachineFunction &MF,
+ MachineBasicBlock &MBB) const {
+ assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
+ MachineFrameInfo &MFI = MF.getFrameInfo();
+ const VESubtarget &Subtarget = MF.getSubtarget<VESubtarget>();
+ const VEInstrInfo &TII =
+ *static_cast<const VEInstrInfo *>(Subtarget.getInstrInfo());
+ const VERegisterInfo &RegInfo =
+ *static_cast<const VERegisterInfo *>(Subtarget.getRegisterInfo());
+ MachineBasicBlock::iterator MBBI = MBB.begin();
+ // Debug location must be unknown since the first debug location is used
+ // to determine the end of the prologue.
+ DebugLoc dl;
+ bool NeedsStackRealignment = RegInfo.needsStackRealignment(MF);
+
+ // FIXME: unfortunately, returning false from canRealignStack
+ // actually just causes needsStackRealignment to return false,
+ // rather than reporting an error, as would be sensible. This is
+ // poor, but fixing that bogosity is going to be a large project.
+ // For now, just see if it's lied, and report an error here.
+ if (!NeedsStackRealignment && MFI.getMaxAlignment() > getStackAlignment())
+ report_fatal_error("Function \"" + Twine(MF.getName()) +
+ "\" required "
+ "stack re-alignment, but LLVM couldn't handle it "
+ "(probably because it has a dynamic alloca).");
+
+ // Get the number of bytes to allocate from the FrameInfo
+ int NumBytes = (int)MFI.getStackSize();
+ // The VE ABI requires a reserved 176-byte area in the user's stack, starting
+ // at %sp + 16. This is for the callee Register Save Area (RSA).
+ //
+ // We therefore need to add that offset to the total stack size
+ // after all the stack objects are placed by
+ // PrologEpilogInserter calculateFrameObjectOffsets. However, since the stack
+ // needs to be aligned *after* the extra size is added, we need to disable
+ // calculateFrameObjectOffsets's built-in stack alignment, by having
+ // targetHandlesStackFrameRounding return true.
+
+ // Add the extra call frame stack size, if needed. (This is the same
+ // code as in PrologEpilogInserter, but also gets disabled by
+ // targetHandlesStackFrameRounding)
+ if (MFI.adjustsStack() && hasReservedCallFrame(MF))
+ NumBytes += MFI.getMaxCallFrameSize();
+
+ // Adds the VE subtarget-specific spill area to the stack
+ // size. Also ensures target-required alignment.
+ NumBytes = Subtarget.getAdjustedFrameSize(NumBytes);
+
+ // Finally, ensure that the size is sufficiently aligned for the
+ // data on the stack.
+ if (MFI.getMaxAlignment() > 0) {
+ NumBytes = alignTo(NumBytes, MFI.getMaxAlignment());
+ }
+
+ // Update stack size with corrected value.
+ MFI.setStackSize(NumBytes);
+
+ // Emit Prologue instructions to save %lr
+ emitPrologueInsns(MF, MBB, MBBI, NumBytes, true);
+
+ // Emit stack adjust instructions
+ emitSPAdjustment(MF, MBB, MBBI, -NumBytes);
+
+ // Emit stack extend instructions
+ emitSPExtend(MF, MBB, MBBI, -NumBytes);
+
+ unsigned regFP = RegInfo.getDwarfRegNum(VE::SX9, true);
+
+ // Emit ".cfi_def_cfa_register 30".
+ unsigned CFIIndex =
+ MF.addFrameInst(MCCFIInstruction::createDefCfaRegister(nullptr, regFP));
+ BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
+ .addCFIIndex(CFIIndex);
+
+ // Emit ".cfi_window_save".
+ CFIIndex = MF.addFrameInst(MCCFIInstruction::createWindowSave(nullptr));
+ BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
+ .addCFIIndex(CFIIndex);
+}
+
+MachineBasicBlock::iterator VEFrameLowering::eliminateCallFramePseudoInstr(
+ MachineFunction &MF, MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator I) const {
+ if (!hasReservedCallFrame(MF)) {
+ MachineInstr &MI = *I;
+ int Size = MI.getOperand(0).getImm();
+ if (MI.getOpcode() == VE::ADJCALLSTACKDOWN)
+ Size = -Size;
+
+ if (Size)
+ emitSPAdjustment(MF, MBB, I, Size);
+ }
+ return MBB.erase(I);
+}
+
+void VEFrameLowering::emitEpilogue(MachineFunction &MF,
+ MachineBasicBlock &MBB) const {
+ MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
+ DebugLoc dl = MBBI->getDebugLoc();
+ MachineFrameInfo &MFI = MF.getFrameInfo();
+
+ int NumBytes = (int)MFI.getStackSize();
+
+ // Emit Epilogue instructions to restore %lr
+ emitEpilogueInsns(MF, MBB, MBBI, NumBytes, true);
+}
+
+bool VEFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
+ // Reserve call frame if there are no variable sized objects on the stack.
+ return !MF.getFrameInfo().hasVarSizedObjects();
+}
+
+// hasFP - Return true if the specified function should have a dedicated frame
+// pointer register. This is true if the function has variable sized allocas or
+// if frame pointer elimination is disabled.
+bool VEFrameLowering::hasFP(const MachineFunction &MF) const {
+ const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
+
+ const MachineFrameInfo &MFI = MF.getFrameInfo();
+ return MF.getTarget().Options.DisableFramePointerElim(MF) ||
+ RegInfo->needsStackRealignment(MF) || MFI.hasVarSizedObjects() ||
+ MFI.isFrameAddressTaken();
+}
+
+int VEFrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI,
+ unsigned &FrameReg) const {
+ // Addressable stack objects are accessed using neg. offsets from
+ // %fp, or positive offsets from %sp.
+ int64_t FrameOffset = MF.getFrameInfo().getObjectOffset(FI);
+ FrameReg = VE::SX11; // %sp
+ return FrameOffset + MF.getFrameInfo().getStackSize();
+}
+
+bool VEFrameLowering::isLeafProc(MachineFunction &MF) const {
+
+ MachineRegisterInfo &MRI = MF.getRegInfo();
+ MachineFrameInfo &MFI = MF.getFrameInfo();
+
+ return !MFI.hasCalls() // No calls
+ && !MRI.isPhysRegUsed(VE::SX18) // Registers within limits
+ // (s18 is first CSR)
+ && !MRI.isPhysRegUsed(VE::SX11) // %sp un-used
+ && !hasFP(MF); // Don't need %fp
+}
+
+void VEFrameLowering::determineCalleeSaves(MachineFunction &MF,
+ BitVector &SavedRegs,
+ RegScavenger *RS) const {
+ TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
+
+ assert(isLeafProc(MF) && "TODO implement for non-leaf procs");
+}
diff --git a/llvm/lib/Target/VE/VEFrameLowering.h b/llvm/lib/Target/VE/VEFrameLowering.h
new file mode 100644
index 000000000000..97e31d21aa43
--- /dev/null
+++ b/llvm/lib/Target/VE/VEFrameLowering.h
@@ -0,0 +1,81 @@
+//===-- VEFrameLowering.h - Define frame lowering for VE --*- 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 VE-specific bits of TargetFrameLowering class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_VE_VEFRAMELOWERING_H
+#define LLVM_LIB_TARGET_VE_VEFRAMELOWERING_H
+
+#include "VE.h"
+#include "llvm/CodeGen/TargetFrameLowering.h"
+
+namespace llvm {
+
+class VESubtarget;
+class VEFrameLowering : public TargetFrameLowering {
+public:
+ explicit VEFrameLowering(const VESubtarget &ST);
+
+ /// emitProlog/emitEpilog - These methods insert prolog and epilog code into
+ /// the function.
+ void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
+ void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
+ void emitPrologueInsns(MachineFunction &MF, MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MBBI, int NumBytes,
+ bool RequireFPUpdate) const;
+ void emitEpilogueInsns(MachineFunction &MF, MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MBBI, int NumBytes,
+ bool RequireFPUpdate) const;
+
+ MachineBasicBlock::iterator
+ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator I) const override;
+
+ bool hasReservedCallFrame(const MachineFunction &MF) const override;
+ bool hasFP(const MachineFunction &MF) const override;
+ void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
+ RegScavenger *RS = nullptr) const override;
+
+ int getFrameIndexReference(const MachineFunction &MF, int FI,
+ unsigned &FrameReg) const override;
+
+ const SpillSlot *
+ getCalleeSavedSpillSlots(unsigned &NumEntries) const override {
+ static const SpillSlot Offsets[] = {
+ {VE::SX17, 40}, {VE::SX18, 48}, {VE::SX19, 56}, {VE::SX20, 64},
+ {VE::SX21, 72}, {VE::SX22, 80}, {VE::SX23, 88}, {VE::SX24, 96},
+ {VE::SX25, 104}, {VE::SX26, 112}, {VE::SX27, 120}, {VE::SX28, 128},
+ {VE::SX29, 136}, {VE::SX30, 144}, {VE::SX31, 152}, {VE::SX32, 160},
+ {VE::SX33, 168}};
+ NumEntries = array_lengthof(Offsets);
+ return Offsets;
+ }
+
+ /// targetHandlesStackFrameRounding - Returns true if the target is
+ /// responsible for rounding up the stack frame (probably at emitPrologue
+ /// time).
+ bool targetHandlesStackFrameRounding() const override { return true; }
+
+private:
+ // Returns true if MF is a leaf procedure.
+ bool isLeafProc(MachineFunction &MF) const;
+
+ // Emits code for adjusting SP in function prologue/epilogue.
+ void emitSPAdjustment(MachineFunction &MF, MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MBBI, int NumBytes) const;
+
+ // Emits code for extending SP in function prologue/epilogue.
+ void emitSPExtend(MachineFunction &MF, MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MBBI, int NumBytes) const;
+};
+
+} // namespace llvm
+
+#endif
diff --git a/llvm/lib/Target/VE/VEISelDAGToDAG.cpp b/llvm/lib/Target/VE/VEISelDAGToDAG.cpp
new file mode 100644
index 000000000000..43030993efb9
--- /dev/null
+++ b/llvm/lib/Target/VE/VEISelDAGToDAG.cpp
@@ -0,0 +1,70 @@
+//===-- VEISelDAGToDAG.cpp - A dag to dag inst selector for VE ------------===//
+//
+// 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 VE target.
+//
+//===----------------------------------------------------------------------===//
+
+#include "VETargetMachine.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/SelectionDAGISel.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+// Instruction Selector Implementation
+//===----------------------------------------------------------------------===//
+
+//===--------------------------------------------------------------------===//
+/// VEDAGToDAGISel - VE specific code to select VE machine
+/// instructions for SelectionDAG operations.
+///
+namespace {
+class VEDAGToDAGISel : public SelectionDAGISel {
+ /// Subtarget - Keep a pointer to the VE Subtarget around so that we can
+ /// make the right decision when generating code for
diff erent targets.
+ const VESubtarget *Subtarget;
+
+public:
+ explicit VEDAGToDAGISel(VETargetMachine &tm) : SelectionDAGISel(tm) {}
+
+ bool runOnMachineFunction(MachineFunction &MF) override {
+ Subtarget = &MF.getSubtarget<VESubtarget>();
+ return SelectionDAGISel::runOnMachineFunction(MF);
+ }
+
+ void Select(SDNode *N) override;
+
+ StringRef getPassName() const override {
+ return "VE DAG->DAG Pattern Instruction Selection";
+ }
+
+ // Include the pieces autogenerated from the target description.
+#include "VEGenDAGISel.inc"
+};
+} // end anonymous namespace
+
+void VEDAGToDAGISel::Select(SDNode *N) {
+ SDLoc dl(N);
+ if (N->isMachineOpcode()) {
+ N->setNodeId(-1);
+ return; // Already selected.
+ }
+
+ SelectCode(N);
+}
+
+/// createVEISelDag - This pass converts a legalized DAG into a
+/// VE-specific DAG, ready for instruction scheduling.
+///
+FunctionPass *llvm::createVEISelDag(VETargetMachine &TM) {
+ return new VEDAGToDAGISel(TM);
+}
diff --git a/llvm/lib/Target/VE/VEISelLowering.cpp b/llvm/lib/Target/VE/VEISelLowering.cpp
new file mode 100644
index 000000000000..aa6c3c08bd75
--- /dev/null
+++ b/llvm/lib/Target/VE/VEISelLowering.cpp
@@ -0,0 +1,137 @@
+//===-- VEISelLowering.cpp - VE 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 implements the interfaces that VE uses to lower LLVM code into a
+// selection DAG.
+//
+//===----------------------------------------------------------------------===//
+
+#include "VEISelLowering.h"
+#include "VERegisterInfo.h"
+#include "VETargetMachine.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/CodeGen/CallingConvLower.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/KnownBits.h"
+using namespace llvm;
+
+#define DEBUG_TYPE "ve-lower"
+
+//===----------------------------------------------------------------------===//
+// Calling Convention Implementation
+//===----------------------------------------------------------------------===//
+
+#include "VEGenCallingConv.inc"
+
+bool VETargetLowering::CanLowerReturn(
+ CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
+ const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context) const {
+ assert(!IsVarArg && "TODO implement var args");
+ assert(Outs.empty() && "TODO implement return values");
+ return true; // TODO support more than 'ret void'
+}
+
+SDValue
+VETargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
+ bool IsVarArg,
+ const SmallVectorImpl<ISD::OutputArg> &Outs,
+ const SmallVectorImpl<SDValue> &OutVals,
+ const SDLoc &DL, SelectionDAG &DAG) const {
+ assert(!IsVarArg && "TODO implement var args");
+ assert(Outs.empty() && "TODO implement return values");
+ assert(OutVals.empty() && "TODO implement return values");
+
+ SmallVector<SDValue, 4> RetOps(1, Chain);
+ RetOps[0] = Chain; // Update chain.
+ return DAG.getNode(VEISD::RET_FLAG, DL, MVT::Other, RetOps);
+}
+
+SDValue VETargetLowering::LowerFormalArguments(
+ SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
+ const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
+ SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+ assert(!IsVarArg && "TODO implement var args");
+ assert(Ins.empty() && "TODO implement input arguments");
+ return Chain;
+}
+
+// FIXME? Maybe this could be a TableGen attribute on some registers and
+// this table could be generated automatically from RegInfo.
+Register VETargetLowering::getRegisterByName(const char *RegName, LLT VT,
+ const MachineFunction &MF) const {
+ Register Reg = StringSwitch<Register>(RegName)
+ .Case("sp", VE::SX11) // Stack pointer
+ .Case("fp", VE::SX9) // Frame pointer
+ .Case("sl", VE::SX8) // Stack limit
+ .Case("lr", VE::SX10) // Link regsiter
+ .Case("tp", VE::SX14) // Thread pointer
+ .Case("outer", VE::SX12) // Outer regiser
+ .Case("info", VE::SX17) // Info area register
+ .Case("got", VE::SX15) // Global offset table register
+ .Case("plt", VE::SX16) // Procedure linkage table register
+ .Default(0);
+
+ if (Reg)
+ return Reg;
+
+ report_fatal_error("Invalid register name global variable");
+}
+
+//===----------------------------------------------------------------------===//
+// TargetLowering Implementation
+//===----------------------------------------------------------------------===//
+
+VETargetLowering::VETargetLowering(const TargetMachine &TM,
+ const VESubtarget &STI)
+ : TargetLowering(TM), Subtarget(&STI) {
+ // Instructions which use registers as conditionals examine all the
+ // bits (as does the pseudo SELECT_CC expansion). I don't think it
+ // matters much whether it's ZeroOrOneBooleanContent, or
+ // ZeroOrNegativeOneBooleanContent, so, arbitrarily choose the
+ // former.
+ setBooleanContents(ZeroOrOneBooleanContent);
+ setBooleanVectorContents(ZeroOrOneBooleanContent);
+
+ // Set up the register classes.
+ addRegisterClass(MVT::i64, &VE::I64RegClass);
+
+ setStackPointerRegisterToSaveRestore(VE::SX11);
+
+ // Set function alignment to 16 bytes
+ setMinFunctionAlignment(Align(16));
+
+ // VE stores all argument by 8 bytes alignment
+ setMinStackArgumentAlignment(Align(8));
+
+ computeRegisterProperties(Subtarget->getRegisterInfo());
+}
+
+const char *VETargetLowering::getTargetNodeName(unsigned Opcode) const {
+ switch ((VEISD::NodeType)Opcode) {
+ case VEISD::FIRST_NUMBER:
+ break;
+ case VEISD::RET_FLAG:
+ return "VEISD::RET_FLAG";
+ }
+ return nullptr;
+}
+
+EVT VETargetLowering::getSetCCResultType(const DataLayout &, LLVMContext &,
+ EVT VT) const {
+ return MVT::i64;
+}
diff --git a/llvm/lib/Target/VE/VEISelLowering.h b/llvm/lib/Target/VE/VEISelLowering.h
new file mode 100644
index 000000000000..39b3610a0c3a
--- /dev/null
+++ b/llvm/lib/Target/VE/VEISelLowering.h
@@ -0,0 +1,62 @@
+//===-- VEISelLowering.h - VE 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 VE uses to lower LLVM code into a
+// selection DAG.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_VE_VEISELLOWERING_H
+#define LLVM_LIB_TARGET_VE_VEISELLOWERING_H
+
+#include "VE.h"
+#include "llvm/CodeGen/TargetLowering.h"
+
+namespace llvm {
+class VESubtarget;
+
+namespace VEISD {
+enum NodeType : unsigned {
+ FIRST_NUMBER = ISD::BUILTIN_OP_END,
+ RET_FLAG, // Return with a flag operand.
+};
+}
+
+class VETargetLowering : public TargetLowering {
+ const VESubtarget *Subtarget;
+
+public:
+ VETargetLowering(const TargetMachine &TM, const VESubtarget &STI);
+
+ const char *getTargetNodeName(unsigned Opcode) const override;
+
+ Register getRegisterByName(const char *RegName, LLT VT,
+ const MachineFunction &MF) const override;
+
+ /// getSetCCResultType - Return the ISD::SETCC ValueType
+ EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,
+ EVT VT) const override;
+
+ SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
+ bool isVarArg,
+ const SmallVectorImpl<ISD::InputArg> &Ins,
+ const SDLoc &dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const override;
+
+ bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
+ bool isVarArg,
+ const SmallVectorImpl<ISD::OutputArg> &ArgsFlags,
+ LLVMContext &Context) const override;
+ SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
+ const SmallVectorImpl<ISD::OutputArg> &Outs,
+ const SmallVectorImpl<SDValue> &OutVals, const SDLoc &dl,
+ SelectionDAG &DAG) const override;
+};
+} // namespace llvm
+
+#endif // VE_ISELLOWERING_H
diff --git a/llvm/lib/Target/VE/VEInstrFormats.td b/llvm/lib/Target/VE/VEInstrFormats.td
new file mode 100644
index 000000000000..a8d3e786ba89
--- /dev/null
+++ b/llvm/lib/Target/VE/VEInstrFormats.td
@@ -0,0 +1,75 @@
+//===-- VEInstrFormats.td - VE Instruction 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
+//
+//===----------------------------------------------------------------------===//
+
+class InstVE<dag outs, dag ins, string asmstr, list<dag> pattern>
+ : Instruction {
+ field bits<64> Inst;
+
+ let Namespace = "VE";
+ let Size = 8;
+
+ bits<8> op;
+ let Inst{0-7} = op;
+
+ dag OutOperandList = outs;
+ dag InOperandList = ins;
+ let AsmString = asmstr;
+ let Pattern = pattern;
+
+ let DecoderNamespace = "VE";
+ field bits<64> SoftFail = 0;
+}
+
+class RM<bits<8>opVal, dag outs, dag ins, string asmstr, list<dag> pattern=[]>
+ : InstVE<outs, ins, asmstr, pattern> {
+ bits<1> cx = 0;
+ bits<7> sx;
+ bits<1> cy = 0;
+ bits<7> sy;
+ bits<1> cz = 0;
+ bits<7> sz;
+ bits<32> imm32 = 0;
+ let op = opVal;
+ let Inst{15} = cx;
+ let Inst{14-8} = sx;
+ let Inst{23} = cy;
+ let Inst{22-16} = sy;
+ let Inst{31} = cz;
+ let Inst{30-24} = sz;
+ let Inst{63-32} = imm32;
+}
+
+class RR<bits<8>opVal, dag outs, dag ins, string asmstr>
+ : RM<opVal, outs, ins, asmstr> {
+ bits<1> cw = 0;
+ bits<1> cw2 = 0;
+ bits<4> cfw = 0;
+ let imm32{0-23} = 0;
+ let imm32{24} = cw;
+ let imm32{25} = cw2;
+ let imm32{26-27} = 0;
+ let imm32{28-31} = cfw;
+}
+
+class CF<bits<8>opVal, dag outs, dag ins, string asmstr, list<dag> pattern=[]>
+ : RM<opVal, outs, ins, asmstr, pattern> {
+ bits<1> cx2;
+ bits<2> bpf;
+ bits<4> cf;
+ let cx = 0;
+ let sx{6} = cx2;
+ let sx{5-4} = bpf;
+ let sx{3-0} = cf;
+}
+
+// Pseudo instructions.
+class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern=[]>
+ : InstVE<outs, ins, asmstr, pattern> {
+ let isCodeGenOnly = 1;
+ let isPseudo = 1;
+}
diff --git a/llvm/lib/Target/VE/VEInstrInfo.cpp b/llvm/lib/Target/VE/VEInstrInfo.cpp
new file mode 100644
index 000000000000..bc382dcef7c3
--- /dev/null
+++ b/llvm/lib/Target/VE/VEInstrInfo.cpp
@@ -0,0 +1,133 @@
+//===-- VEInstrInfo.cpp - VE Instruction Information ----------------------===//
+//
+// 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 VE implementation of the TargetInstrInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "VEInstrInfo.h"
+#include "VE.h"
+#include "VESubtarget.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineMemOperand.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/TargetRegistry.h"
+
+#define DEBUG_TYPE "ve"
+
+using namespace llvm;
+
+#define GET_INSTRINFO_CTOR_DTOR
+#include "VEGenInstrInfo.inc"
+
+// Pin the vtable to this file.
+void VEInstrInfo::anchor() {}
+
+VEInstrInfo::VEInstrInfo(VESubtarget &ST)
+ : VEGenInstrInfo(VE::ADJCALLSTACKDOWN, VE::ADJCALLSTACKUP), RI(),
+ Subtarget(ST) {}
+
+bool VEInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
+ switch (MI.getOpcode()) {
+ case VE::EXTEND_STACK: {
+ return expandExtendStackPseudo(MI);
+ }
+ case VE::EXTEND_STACK_GUARD: {
+ MI.eraseFromParent(); // The pseudo instruction is gone now.
+ return true;
+ }
+ }
+ return false;
+}
+
+bool VEInstrInfo::expandExtendStackPseudo(MachineInstr &MI) const {
+ MachineBasicBlock &MBB = *MI.getParent();
+ MachineFunction &MF = *MBB.getParent();
+ const VEInstrInfo &TII =
+ *static_cast<const VEInstrInfo *>(MF.getSubtarget().getInstrInfo());
+ DebugLoc dl = MBB.findDebugLoc(MI);
+
+ // Create following instructions and multiple basic blocks.
+ //
+ // thisBB:
+ // brge.l.t %sp, %sl, sinkBB
+ // syscallBB:
+ // ld %s61, 0x18(, %tp) // load param area
+ // or %s62, 0, %s0 // spill the value of %s0
+ // lea %s63, 0x13b // syscall # of grow
+ // shm.l %s63, 0x0(%s61) // store syscall # at addr:0
+ // shm.l %sl, 0x8(%s61) // store old limit at addr:8
+ // shm.l %sp, 0x10(%s61) // store new limit at addr:16
+ // monc // call monitor
+ // or %s0, 0, %s62 // restore the value of %s0
+ // sinkBB:
+
+ // Create new MBB
+ MachineBasicBlock *BB = &MBB;
+ const BasicBlock *LLVM_BB = BB->getBasicBlock();
+ MachineBasicBlock *syscallMBB = MF.CreateMachineBasicBlock(LLVM_BB);
+ MachineBasicBlock *sinkMBB = MF.CreateMachineBasicBlock(LLVM_BB);
+ MachineFunction::iterator It = ++(BB->getIterator());
+ MF.insert(It, syscallMBB);
+ MF.insert(It, sinkMBB);
+
+ // Transfer the remainder of BB and its successor edges to sinkMBB.
+ sinkMBB->splice(sinkMBB->begin(), BB,
+ std::next(std::next(MachineBasicBlock::iterator(MI))),
+ BB->end());
+ sinkMBB->transferSuccessorsAndUpdatePHIs(BB);
+
+ // Next, add the true and fallthrough blocks as its successors.
+ BB->addSuccessor(syscallMBB);
+ BB->addSuccessor(sinkMBB);
+ BuildMI(BB, dl, TII.get(VE::BCRLrr))
+ .addImm(VECC::CC_IGE)
+ .addReg(VE::SX11) // %sp
+ .addReg(VE::SX8) // %sl
+ .addMBB(sinkMBB);
+
+ BB = syscallMBB;
+
+ // Update machine-CFG edges
+ BB->addSuccessor(sinkMBB);
+
+ BuildMI(BB, dl, TII.get(VE::LDSri), VE::SX61)
+ .addReg(VE::SX14)
+ .addImm(0x18);
+ BuildMI(BB, dl, TII.get(VE::ORri), VE::SX62)
+ .addReg(VE::SX0)
+ .addImm(0);
+ BuildMI(BB, dl, TII.get(VE::LEAzzi), VE::SX63)
+ .addImm(0x13b);
+ BuildMI(BB, dl, TII.get(VE::SHMri))
+ .addReg(VE::SX61)
+ .addImm(0)
+ .addReg(VE::SX63);
+ BuildMI(BB, dl, TII.get(VE::SHMri))
+ .addReg(VE::SX61)
+ .addImm(8)
+ .addReg(VE::SX8);
+ BuildMI(BB, dl, TII.get(VE::SHMri))
+ .addReg(VE::SX61)
+ .addImm(16)
+ .addReg(VE::SX11);
+ BuildMI(BB, dl, TII.get(VE::MONC));
+
+ BuildMI(BB, dl, TII.get(VE::ORri), VE::SX0)
+ .addReg(VE::SX62)
+ .addImm(0);
+
+ MI.eraseFromParent(); // The pseudo instruction is gone now.
+ return true;
+}
diff --git a/llvm/lib/Target/VE/VEInstrInfo.h b/llvm/lib/Target/VE/VEInstrInfo.h
new file mode 100644
index 000000000000..6a26d0e95275
--- /dev/null
+++ b/llvm/lib/Target/VE/VEInstrInfo.h
@@ -0,0 +1,48 @@
+//===-- VEInstrInfo.h - VE 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 VE implementation of the TargetInstrInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_VE_VEINSTRINFO_H
+#define LLVM_LIB_TARGET_VE_VEINSTRINFO_H
+
+#include "VERegisterInfo.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+
+#define GET_INSTRINFO_HEADER
+#include "VEGenInstrInfo.inc"
+
+namespace llvm {
+
+class VESubtarget;
+
+class VEInstrInfo : public VEGenInstrInfo {
+ const VERegisterInfo RI;
+ const VESubtarget &Subtarget;
+ virtual void anchor();
+
+public:
+ explicit VEInstrInfo(VESubtarget &ST);
+
+ /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As
+ /// such, whenever a client has an instance of instruction info, it should
+ /// always be able to get register info as well (through this method).
+ ///
+ const VERegisterInfo &getRegisterInfo() const { return RI; }
+
+ // Lower pseudo instructions after register allocation.
+ bool expandPostRAPseudo(MachineInstr &MI) const override;
+
+ bool expandExtendStackPseudo(MachineInstr &MI) const;
+};
+
+} // namespace llvm
+
+#endif
diff --git a/llvm/lib/Target/VE/VEInstrInfo.td b/llvm/lib/Target/VE/VEInstrInfo.td
new file mode 100644
index 000000000000..dc671aaa3f8d
--- /dev/null
+++ b/llvm/lib/Target/VE/VEInstrInfo.td
@@ -0,0 +1,288 @@
+//===-- VEInstrInfo.td - Target Description for VE Target -----------------===//
+//
+// 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 VE instructions in TableGen format.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Instruction format superclass
+//===----------------------------------------------------------------------===//
+
+include "VEInstrFormats.td"
+
+//===----------------------------------------------------------------------===//
+// Feature predicates.
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Instruction Pattern Stuff
+//===----------------------------------------------------------------------===//
+
+def simm7 : PatLeaf<(imm), [{ return isInt<7>(N->getSExtValue()); }]>;
+def simm32 : PatLeaf<(imm), [{ return isInt<32>(N->getSExtValue()); }]>;
+def uimm6 : PatLeaf<(imm), [{ return isUInt<6>(N->getZExtValue()); }]>;
+
+// ASX format of memory address
+def MEMri : Operand<iPTR> {
+ let PrintMethod = "printMemASXOperand";
+ let MIOperandInfo = (ops ptr_rc, i64imm);
+}
+
+// AS format of memory address
+def MEMASri : Operand<iPTR> {
+ let PrintMethod = "printMemASOperand";
+ let MIOperandInfo = (ops ptr_rc, i64imm);
+}
+
+// Branch targets have OtherVT type.
+def brtarget32 : Operand<OtherVT> {
+ let EncoderMethod = "getBranchTarget32OpValue";
+}
+
+def simm7Op64 : Operand<i64> {
+ let DecoderMethod = "DecodeSIMM7";
+}
+
+def simm32Op64 : Operand<i64> {
+ let DecoderMethod = "DecodeSIMM32";
+}
+
+def uimm6Op64 : Operand<i64> {
+ let DecoderMethod = "DecodeUIMM6";
+}
+
+// Operand for printing out a condition code.
+let PrintMethod = "printCCOperand" in
+ def CCOp : Operand<i32>;
+
+// These are target-independent nodes, but have target-specific formats.
+def SDT_SPCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i64>,
+ SDTCisVT<1, i64> ]>;
+def SDT_SPCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i64>,
+ SDTCisVT<1, i64> ]>;
+
+def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SPCallSeqStart,
+ [SDNPHasChain, SDNPOutGlue]>;
+def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_SPCallSeqEnd,
+ [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
+
+// def SDT_SPCall : SDTypeProfile<0, -1, [SDTCisVT<0, i64>]>;
+
+def retflag : SDNode<"VEISD::RET_FLAG", SDTNone,
+ [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
+//===----------------------------------------------------------------------===//
+// VE Flag Conditions
+//===----------------------------------------------------------------------===//
+
+// Note that these values must be kept in sync with the CCOp::CondCode enum
+// values.
+class CC_VAL<int N> : PatLeaf<(i32 N)>;
+def CC_IG : CC_VAL< 0>; // Greater
+def CC_IL : CC_VAL< 1>; // Less
+def CC_INE : CC_VAL< 2>; // Not Equal
+def CC_IEQ : CC_VAL< 3>; // Equal
+def CC_IGE : CC_VAL< 4>; // Greater or Equal
+def CC_ILE : CC_VAL< 5>; // Less or Equal
+def CC_AF : CC_VAL< 6>; // Always false
+def CC_G : CC_VAL< 7>; // Greater
+def CC_L : CC_VAL< 8>; // Less
+def CC_NE : CC_VAL< 9>; // Not Equal
+def CC_EQ : CC_VAL<10>; // Equal
+def CC_GE : CC_VAL<11>; // Greater or Equal
+def CC_LE : CC_VAL<12>; // Less or Equal
+def CC_NUM : CC_VAL<13>; // Number
+def CC_NAN : CC_VAL<14>; // NaN
+def CC_GNAN : CC_VAL<15>; // Greater or NaN
+def CC_LNAN : CC_VAL<16>; // Less or NaN
+def CC_NENAN : CC_VAL<17>; // Not Equal or NaN
+def CC_EQNAN : CC_VAL<18>; // Equal or NaN
+def CC_GENAN : CC_VAL<19>; // Greater or Equal or NaN
+def CC_LENAN : CC_VAL<20>; // Less or Equal or NaN
+def CC_AT : CC_VAL<21>; // Always true
+
+//===----------------------------------------------------------------------===//
+// VE Multiclasses for common instruction formats
+//===----------------------------------------------------------------------===//
+
+multiclass RMm<string opcStr, bits<8>opc,
+ RegisterClass RC, ValueType Ty, Operand immOp, Operand immOp2> {
+ def rri : RM<
+ opc, (outs RC:$sx), (ins RC:$sy, RC:$sz, immOp2:$imm32),
+ !strconcat(opcStr, " $sx, ${imm32}($sy, ${sz})")> {
+ let cy = 1;
+ let cz = 1;
+ let hasSideEffects = 0;
+ }
+ def zzi : RM<
+ opc, (outs RC:$sx), (ins immOp2:$imm32),
+ !strconcat(opcStr, " $sx, $imm32")> {
+ let cy = 0;
+ let sy = 0;
+ let cz = 0;
+ let sz = 0;
+ let hasSideEffects = 0;
+ }
+}
+
+// Multiclass for RR type instructions
+
+multiclass RRmrr<string opcStr, bits<8>opc,
+ RegisterClass RCo, ValueType Tyo,
+ RegisterClass RCi, ValueType Tyi> {
+ def rr : RR<opc, (outs RCo:$sx), (ins RCi:$sy, RCi:$sz),
+ !strconcat(opcStr, " $sx, $sy, $sz")>
+ { let cy = 1; let cz = 1; let hasSideEffects = 0; }
+}
+
+multiclass RRmri<string opcStr, bits<8>opc,
+ RegisterClass RCo, ValueType Tyo,
+ RegisterClass RCi, ValueType Tyi, Operand immOp> {
+ // VE calculates (OpNode $sy, $sz), but llvm requires to have immediate
+ // in RHS, so we use following definition.
+ def ri : RR<opc, (outs RCo:$sx), (ins RCi:$sz, immOp:$sy),
+ !strconcat(opcStr, " $sx, $sy, $sz")>
+ { let cy = 0; let cz = 1; let hasSideEffects = 0; }
+}
+
+multiclass RRmiz<string opcStr, bits<8>opc,
+ RegisterClass RCo, ValueType Tyo,
+ RegisterClass RCi, ValueType Tyi, Operand immOp> {
+ def zi : RR<opc, (outs RCo:$sx), (ins immOp:$sy),
+ !strconcat(opcStr, " $sx, $sy")>
+ { let cy = 0; let cz = 0; let sz = 0; let hasSideEffects = 0; }
+}
+
+multiclass RRNDmrm<string opcStr, bits<8>opc,
+ RegisterClass RCo, ValueType Tyo,
+ RegisterClass RCi, ValueType Tyi, Operand immOp2> {
+ def rm0 : RR<opc, (outs RCo:$sx), (ins RCi:$sy, immOp2:$sz),
+ !strconcat(opcStr, " $sx, $sy, (${sz})0")> {
+ let cy = 1;
+ let cz = 0;
+ let sz{6} = 1;
+ // (guess) tblgen conservatively assumes hasSideEffects when
+ // it fails to infer from a pattern.
+ let hasSideEffects = 0;
+ }
+}
+
+// Used by add, mul, div, and similar commutative instructions
+// The order of operands are "$sx, $sy, $sz"
+
+multiclass RRm<string opcStr, bits<8>opc,
+ RegisterClass RC, ValueType Ty, Operand immOp, Operand immOp2> :
+ RRmrr<opcStr, opc, RC, Ty, RC, Ty>,
+ RRmri<opcStr, opc, RC, Ty, RC, Ty, immOp>,
+ RRmiz<opcStr, opc, RC, Ty, RC, Ty, immOp>,
+ RRNDmrm<opcStr, opc, RC, Ty, RC, Ty, immOp2>;
+
+// Branch multiclass
+let isBranch = 1, isTerminator = 1, hasDelaySlot = 1 in
+multiclass BCRm<string opcStr, string opcStrAt, bits<8> opc,
+ RegisterClass RC, ValueType Ty, Operand immOp, Operand immOp2> {
+ def rr : CF<
+ opc, (outs),
+ (ins CCOp:$cf, RC:$sy, RC:$sz, brtarget32:$imm32),
+ !strconcat(opcStr, " $sy, $sz, $imm32")> {
+ let cy = 1;
+ let cz = 1;
+ let hasSideEffects = 0;
+ }
+}
+
+
+//===----------------------------------------------------------------------===//
+// Instructions
+//===----------------------------------------------------------------------===//
+
+// LEA and LEASL instruction (load 32 bit imm to low or high part)
+let cx = 0 in
+defm LEA : RMm<"lea", 0x06, I64, i64, simm7Op64, simm32Op64>;
+let cx = 1 in
+defm LEASL : RMm<"lea.sl", 0x06, I64, i64, simm7Op64, simm32Op64>;
+
+// 5.3.2.2. Fixed-Point Arithmetic Operation Instructions
+
+// ADX instruction
+let cx = 0 in
+defm ADX : RRm<"adds.l", 0x59, I64, i64, simm7Op64, uimm6Op64>;
+
+// 5.3.2.3. Logical Arithmetic Operation Instructions
+
+let cx = 0 in {
+ defm AND : RRm<"and", 0x44, I64, i64, simm7Op64, uimm6Op64>;
+ defm OR : RRm<"or", 0x45, I64, i64, simm7Op64, uimm6Op64>;
+}
+
+// Load and Store instructions
+// As 1st step, only uses sz and imm32 to represent $addr
+let mayLoad = 1, hasSideEffects = 0 in {
+let cy = 0, sy = 0, cz = 1 in {
+let cx = 0 in
+def LDSri : RM<
+ 0x01, (outs I64:$sx), (ins MEMri:$addr),
+ "ld $sx, $addr">;
+}
+}
+
+let mayStore = 1, hasSideEffects = 0 in {
+let cx = 0, cy = 0, sy = 0, cz = 1 in {
+def STSri : RM<
+ 0x11, (outs), (ins MEMri:$addr, I64:$sx),
+ "st $sx, $addr">;
+}
+}
+
+// Return instruction is also a special case of jump.
+let cx = 0, cx2 = 0, bpf = 0 /* NONE */, cf = 15 /* AT */, cy = 0, sy = 0,
+ cz = 1, sz = 0x10 /* SX10 */, imm32 = 0, Uses = [SX10],
+ isReturn = 1, isTerminator = 1, hasDelaySlot = 1, isBarrier = 1,
+ isCodeGenOnly = 1, hasSideEffects = 0 in
+def RET : CF<
+ 0x19, (outs), (ins),
+ "b.l (,%lr)",
+ [(retflag)]>;
+
+// Branch instruction
+let cx = 0, cx2 = 0, bpf = 0 /* NONE */ in
+defm BCRL : BCRm<"br${cf}.l", "br.l", 0x18, I64, i64, simm7Op64, uimm6Op64>;
+
+let cx = 0, cy = 0, cz = 1, hasSideEffects = 0 in {
+let sy = 3 in
+def SHMri : RM<
+ 0x31, (outs), (ins MEMASri:$addr, I64:$sx),
+ "shm.l $sx, $addr">;
+}
+
+let cx = 0, sx = 0, cy = 0, sy = 0, cz = 0, sz = 0, hasSideEffects = 0 in
+def MONC : RR<
+ 0x3F, (outs), (ins),
+ "monc">;
+
+//===----------------------------------------------------------------------===//
+// Pseudo Instructions
+//===----------------------------------------------------------------------===//
+
+let Defs = [SX11], Uses = [SX11], hasSideEffects = 0 in {
+def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i64imm:$amt, i64imm:$amt2),
+ "# ADJCALLSTACKDOWN $amt, $amt2",
+ [(callseq_start timm:$amt, timm:$amt2)]>;
+def ADJCALLSTACKUP : Pseudo<(outs), (ins i64imm:$amt1, i64imm:$amt2),
+ "# ADJCALLSTACKUP $amt1",
+ [(callseq_end timm:$amt1, timm:$amt2)]>;
+}
+
+let Defs = [SX8], Uses = [SX8, SX11], hasSideEffects = 0 in
+def EXTEND_STACK : Pseudo<(outs), (ins),
+ "# EXTEND STACK",
+ []>;
+let hasSideEffects = 0 in
+def EXTEND_STACK_GUARD : Pseudo<(outs), (ins),
+ "# EXTEND STACK GUARD",
+ []>;
diff --git a/llvm/lib/Target/VE/VEMCInstLower.cpp b/llvm/lib/Target/VE/VEMCInstLower.cpp
new file mode 100644
index 000000000000..6c8fc3536c34
--- /dev/null
+++ b/llvm/lib/Target/VE/VEMCInstLower.cpp
@@ -0,0 +1,69 @@
+//===-- VEMCInstLower.cpp - Convert VE MachineInstr to 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 VE MachineInstrs to their corresponding
+// MCInst records.
+//
+//===----------------------------------------------------------------------===//
+
+#include "VE.h"
+#include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/IR/Mangler.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCInst.h"
+
+using namespace llvm;
+
+static MCOperand LowerSymbolOperand(const MachineInstr *MI,
+ const MachineOperand &MO,
+ const MCSymbol *Symbol, AsmPrinter &AP) {
+
+ const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::create(Symbol, AP.OutContext);
+ return MCOperand::createExpr(MCSym);
+}
+
+static MCOperand LowerOperand(const MachineInstr *MI, const MachineOperand &MO,
+ AsmPrinter &AP) {
+ switch (MO.getType()) {
+ default:
+ report_fatal_error("unsupported operand type");
+
+ case MachineOperand::MO_Register:
+ if (MO.isImplicit())
+ break;
+ return MCOperand::createReg(MO.getReg());
+
+ case MachineOperand::MO_Immediate:
+ return MCOperand::createImm(MO.getImm());
+
+ case MachineOperand::MO_MachineBasicBlock:
+ return LowerSymbolOperand(MI, MO, MO.getMBB()->getSymbol(), AP);
+
+ case MachineOperand::MO_RegisterMask:
+ break;
+ }
+ return MCOperand();
+}
+
+void llvm::LowerVEMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
+ AsmPrinter &AP) {
+ OutMI.setOpcode(MI->getOpcode());
+
+ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+ const MachineOperand &MO = MI->getOperand(i);
+ MCOperand MCOp = LowerOperand(MI, MO, AP);
+
+ if (MCOp.isValid())
+ OutMI.addOperand(MCOp);
+ }
+}
diff --git a/llvm/lib/Target/VE/VERegisterInfo.cpp b/llvm/lib/Target/VE/VERegisterInfo.cpp
new file mode 100644
index 000000000000..e1ff614abc20
--- /dev/null
+++ b/llvm/lib/Target/VE/VERegisterInfo.cpp
@@ -0,0 +1,133 @@
+//===-- VERegisterInfo.cpp - VE Register Information ----------------------===//
+//
+// 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 VE implementation of the TargetRegisterInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "VERegisterInfo.h"
+#include "VE.h"
+#include "VESubtarget.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ErrorHandling.h"
+
+using namespace llvm;
+
+#define GET_REGINFO_TARGET_DESC
+#include "VEGenRegisterInfo.inc"
+
+// VE uses %s10 == %lp to keep return address
+VERegisterInfo::VERegisterInfo() : VEGenRegisterInfo(VE::SX10) {}
+
+const MCPhysReg *
+VERegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
+ return CSR_SaveList;
+}
+
+const uint32_t *VERegisterInfo::getCallPreservedMask(const MachineFunction &MF,
+ CallingConv::ID CC) const {
+ return CSR_RegMask;
+}
+
+const uint32_t *VERegisterInfo::getNoPreservedMask() const {
+ return CSR_NoRegs_RegMask;
+}
+
+BitVector VERegisterInfo::getReservedRegs(const MachineFunction &MF) const {
+ BitVector Reserved(getNumRegs());
+ Reserved.set(VE::SX8); // stack limit
+ Reserved.set(VE::SX9); // frame pointer
+ Reserved.set(VE::SX10); // link register (return address)
+ Reserved.set(VE::SX11); // stack pointer
+
+ Reserved.set(VE::SX12); // outer register
+ Reserved.set(VE::SX13); // id register for dynamic linker
+
+ Reserved.set(VE::SX14); // thread pointer
+ Reserved.set(VE::SX15); // global offset table register
+ Reserved.set(VE::SX16); // procedure linkage table register
+ Reserved.set(VE::SX17); // linkage-area register
+
+ // sx18-sx33 are callee-saved registers
+ // sx34-sx63 are temporary registers
+
+ return Reserved;
+}
+
+bool VERegisterInfo::isConstantPhysReg(unsigned PhysReg) const { return false; }
+
+const TargetRegisterClass *
+VERegisterInfo::getPointerRegClass(const MachineFunction &MF,
+ unsigned Kind) const {
+ return &VE::I64RegClass;
+}
+
+static void replaceFI(MachineFunction &MF, MachineBasicBlock::iterator II,
+ MachineInstr &MI, const DebugLoc &dl,
+ unsigned FIOperandNum, int Offset, unsigned FramePtr) {
+ // Replace frame index with a frame pointer reference directly.
+ // VE has 32 bit offset field, so no need to expand a target instruction.
+ // Directly encode it.
+ MI.getOperand(FIOperandNum).ChangeToRegister(FramePtr, false);
+ MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
+}
+
+void VERegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
+ int SPAdj, unsigned FIOperandNum,
+ RegScavenger *RS) const {
+ assert(SPAdj == 0 && "Unexpected");
+
+ MachineInstr &MI = *II;
+ DebugLoc dl = MI.getDebugLoc();
+ int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
+ MachineFunction &MF = *MI.getParent()->getParent();
+ const VEFrameLowering *TFI = getFrameLowering(MF);
+
+ unsigned FrameReg;
+ int Offset;
+ Offset = TFI->getFrameIndexReference(MF, FrameIndex, FrameReg);
+
+ Offset += MI.getOperand(FIOperandNum + 1).getImm();
+
+ replaceFI(MF, II, MI, dl, FIOperandNum, Offset, FrameReg);
+}
+
+Register VERegisterInfo::getFrameRegister(const MachineFunction &MF) const {
+ return VE::SX9;
+}
+
+// VE has no architectural need for stack realignment support,
+// except that LLVM unfortunately currently implements overaligned
+// stack objects by depending upon stack realignment support.
+// If that ever changes, this can probably be deleted.
+bool VERegisterInfo::canRealignStack(const MachineFunction &MF) const {
+ if (!TargetRegisterInfo::canRealignStack(MF))
+ return false;
+
+ // VE always has a fixed frame pointer register, so don't need to
+ // worry about needing to reserve it. [even if we don't have a frame
+ // pointer for our frame, it still cannot be used for other things,
+ // or register window traps will be SADNESS.]
+
+ // If there's a reserved call frame, we can use VE to access locals.
+ if (getFrameLowering(MF)->hasReservedCallFrame(MF))
+ return true;
+
+ // Otherwise, we'd need a base pointer, but those aren't implemented
+ // for VE at the moment.
+
+ return false;
+}
diff --git a/llvm/lib/Target/VE/VERegisterInfo.h b/llvm/lib/Target/VE/VERegisterInfo.h
new file mode 100644
index 000000000000..9cb475f5e174
--- /dev/null
+++ b/llvm/lib/Target/VE/VERegisterInfo.h
@@ -0,0 +1,49 @@
+//===-- VERegisterInfo.h - VE 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 VE implementation of the TargetRegisterInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_VE_VEREGISTERINFO_H
+#define LLVM_LIB_TARGET_VE_VEREGISTERINFO_H
+
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+
+#define GET_REGINFO_HEADER
+#include "VEGenRegisterInfo.inc"
+
+namespace llvm {
+struct VERegisterInfo : public VEGenRegisterInfo {
+public:
+ VERegisterInfo();
+
+ /// Code Generation virtual methods...
+ const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;
+ const uint32_t *getCallPreservedMask(const MachineFunction &MF,
+ CallingConv::ID CC) const override;
+ const uint32_t *getNoPreservedMask() const override;
+
+ BitVector getReservedRegs(const MachineFunction &MF) const override;
+ bool isConstantPhysReg(unsigned PhysReg) const override;
+
+ const TargetRegisterClass *getPointerRegClass(const MachineFunction &MF,
+ unsigned Kind) const override;
+
+ void eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
+ unsigned FIOperandNum,
+ RegScavenger *RS = nullptr) const override;
+
+ Register getFrameRegister(const MachineFunction &MF) const override;
+
+ bool canRealignStack(const MachineFunction &MF) const override;
+};
+
+} // namespace llvm
+
+#endif
diff --git a/llvm/lib/Target/VE/VERegisterInfo.td b/llvm/lib/Target/VE/VERegisterInfo.td
new file mode 100644
index 000000000000..ef5b9c09705a
--- /dev/null
+++ b/llvm/lib/Target/VE/VERegisterInfo.td
@@ -0,0 +1,37 @@
+//===-- VERegisterInfo.td - VE 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 VE register file
+//===----------------------------------------------------------------------===//
+
+class VEReg<bits<7> Enc, string n> : Register<n> {
+ let HWEncoding{15-7} = 0;
+ let HWEncoding{6-0} = Enc;
+ let Namespace = "VE";
+}
+
+// Registers are identified with 7-bit ID numbers.
+// R - 64-bit integer or floating-point registers
+class R<bits<7> Enc, string n, list<Register> subregs = [],
+ list<Register> aliases = []>: VEReg<Enc, n> {
+ let SubRegs = subregs;
+ let Aliases = aliases;
+}
+
+// Generic integer registers - 64 bits wide
+foreach I = 0-63 in
+ def SX#I : R<I, "S"#I, []>,
+ DwarfRegNum<[I]>;
+
+// Register classes.
+//
+// The register order is defined in terms of the preferred
+// allocation order.
+def I64 : RegisterClass<"VE", [i64], 64,
+ (sequence "SX%u", 0, 63)>;
diff --git a/llvm/lib/Target/VE/VESubtarget.cpp b/llvm/lib/Target/VE/VESubtarget.cpp
new file mode 100644
index 000000000000..861e88cdb583
--- /dev/null
+++ b/llvm/lib/Target/VE/VESubtarget.cpp
@@ -0,0 +1,99 @@
+//===-- VESubtarget.cpp - VE Subtarget Information ------------------------===//
+//
+// 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 VE specific subclass of TargetSubtargetInfo.
+//
+//===----------------------------------------------------------------------===//
+
+#include "VESubtarget.h"
+#include "VE.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/TargetRegistry.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "ve-subtarget"
+
+#define GET_SUBTARGETINFO_TARGET_DESC
+#define GET_SUBTARGETINFO_CTOR
+#include "VEGenSubtargetInfo.inc"
+
+void VESubtarget::anchor() {}
+
+VESubtarget &VESubtarget::initializeSubtargetDependencies(StringRef CPU,
+ StringRef FS) {
+ // Determine default and user specified characteristics
+ std::string CPUName = CPU;
+ if (CPUName.empty())
+ CPUName = "ve";
+
+ // Parse features string.
+ ParseSubtargetFeatures(CPUName, FS);
+
+ return *this;
+}
+
+VESubtarget::VESubtarget(const Triple &TT, const std::string &CPU,
+ const std::string &FS, const TargetMachine &TM)
+ : VEGenSubtargetInfo(TT, CPU, FS), TargetTriple(TT),
+ InstrInfo(initializeSubtargetDependencies(CPU, FS)), TLInfo(TM, *this),
+ FrameLowering(*this) {}
+
+int VESubtarget::getAdjustedFrameSize(int frameSize) const {
+
+ // VE stack frame:
+ //
+ // +----------------------------------------+
+ // | Locals and temporaries |
+ // +----------------------------------------+
+ // | Parameter area for callee |
+ // 176(fp) | |
+ // +----------------------------------------+
+ // | Register save area (RSA) for callee |
+ // | |
+ // 16(fp) | 20 * 8 bytes |
+ // +----------------------------------------+
+ // 8(fp) | Return address |
+ // +----------------------------------------+
+ // 0(fp) | Frame pointer of caller |
+ // --------+----------------------------------------+--------
+ // | Locals and temporaries for callee |
+ // +----------------------------------------+
+ // | Parameter area for callee of callee |
+ // +----------------------------------------+
+ // 16(sp) | RSA for callee of callee |
+ // +----------------------------------------+
+ // 8(sp) | Return address |
+ // +----------------------------------------+
+ // 0(sp) | Frame pointer of callee |
+ // +----------------------------------------+
+
+ // RSA frame:
+ // +----------------------------------------------+
+ // 168(fp) | %s33 |
+ // +----------------------------------------------+
+ // | %s19...%s32 |
+ // +----------------------------------------------+
+ // 48(fp) | %s18 |
+ // +----------------------------------------------+
+ // 40(fp) | Linkage area register (%s17) |
+ // +----------------------------------------------+
+ // 32(fp) | Procedure linkage table register (%plt=%s16) |
+ // +----------------------------------------------+
+ // 24(fp) | Global offset table register (%got=%s15) |
+ // +----------------------------------------------+
+ // 16(fp) | Thread pointer register (%tp=%s14) |
+ // +----------------------------------------------+
+
+ frameSize += 176; // for RSA, RA, and FP
+ frameSize = alignTo(frameSize, 16); // requires 16 bytes alignment
+
+ return frameSize;
+}
+
+bool VESubtarget::enableMachineScheduler() const { return true; }
diff --git a/llvm/lib/Target/VE/VESubtarget.h b/llvm/lib/Target/VE/VESubtarget.h
new file mode 100644
index 000000000000..e9637cc16023
--- /dev/null
+++ b/llvm/lib/Target/VE/VESubtarget.h
@@ -0,0 +1,73 @@
+//===-- VESubtarget.h - Define Subtarget for the VE -------------*- 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 VE specific subclass of TargetSubtargetInfo.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_VE_VESUBTARGET_H
+#define LLVM_LIB_TARGET_VE_VESUBTARGET_H
+
+#include "VEFrameLowering.h"
+#include "VEISelLowering.h"
+#include "VEInstrInfo.h"
+#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
+#include "llvm/CodeGen/TargetFrameLowering.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/IR/DataLayout.h"
+#include <string>
+
+#define GET_SUBTARGETINFO_HEADER
+#include "VEGenSubtargetInfo.inc"
+
+namespace llvm {
+class StringRef;
+
+class VESubtarget : public VEGenSubtargetInfo {
+ Triple TargetTriple;
+ virtual void anchor();
+
+ VEInstrInfo InstrInfo;
+ VETargetLowering TLInfo;
+ SelectionDAGTargetInfo TSInfo;
+ VEFrameLowering FrameLowering;
+
+public:
+ VESubtarget(const Triple &TT, const std::string &CPU, const std::string &FS,
+ const TargetMachine &TM);
+
+ const VEInstrInfo *getInstrInfo() const override { return &InstrInfo; }
+ const TargetFrameLowering *getFrameLowering() const override {
+ return &FrameLowering;
+ }
+ const VERegisterInfo *getRegisterInfo() const override {
+ return &InstrInfo.getRegisterInfo();
+ }
+ const VETargetLowering *getTargetLowering() const override { return &TLInfo; }
+ const SelectionDAGTargetInfo *getSelectionDAGInfo() const override {
+ return &TSInfo;
+ }
+
+ bool enableMachineScheduler() const override;
+
+ /// ParseSubtargetFeatures - Parses features string setting specified
+ /// subtarget options. Definition of function is auto generated by tblgen.
+ void ParseSubtargetFeatures(StringRef CPU, StringRef FS);
+ VESubtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS);
+
+ /// Given a actual stack size as determined by FrameInfo, this function
+ /// returns adjusted framesize which includes space for register window
+ /// spills and arguments.
+ int getAdjustedFrameSize(int stackSize) const;
+
+ bool isTargetLinux() const { return TargetTriple.isOSLinux(); }
+};
+
+} // namespace llvm
+
+#endif
diff --git a/llvm/lib/Target/VE/VETargetMachine.cpp b/llvm/lib/Target/VE/VETargetMachine.cpp
index 10fe9ba0e7eb..46f5c0dc1805 100644
--- a/llvm/lib/Target/VE/VETargetMachine.cpp
+++ b/llvm/lib/Target/VE/VETargetMachine.cpp
@@ -11,6 +11,11 @@
#include "VETargetMachine.h"
#include "VE.h"
+#include "VETargetTransformInfo.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
+#include "llvm/CodeGen/TargetPassConfig.h"
+#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Support/TargetRegistry.h"
using namespace llvm;
@@ -47,16 +52,57 @@ static Reloc::Model getEffectiveRelocModel(Optional<Reloc::Model> RM) {
return *RM;
}
+class VEELFTargetObjectFile : public TargetLoweringObjectFileELF {
+ void Initialize(MCContext &Ctx, const TargetMachine &TM) override {
+ TargetLoweringObjectFileELF::Initialize(Ctx, TM);
+ InitializeELF(TM.Options.UseInitArray);
+ }
+};
+
+static std::unique_ptr<TargetLoweringObjectFile> createTLOF() {
+ return std::make_unique<VEELFTargetObjectFile>();
+}
+
/// Create an Aurora VE architecture model
-VETargetMachine::VETargetMachine(
- const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
- const TargetOptions &Options, Optional<Reloc::Model> RM,
- Optional<CodeModel::Model> CM, CodeGenOpt::Level OL, bool JIT)
- : LLVMTargetMachine(
- T, computeDataLayout(TT), TT, CPU, FS, Options,
- getEffectiveRelocModel(RM),
- getEffectiveCodeModel(CM, CodeModel::Small),
- OL)
-{}
+VETargetMachine::VETargetMachine(const Target &T, const Triple &TT,
+ StringRef CPU, StringRef FS,
+ const TargetOptions &Options,
+ Optional<Reloc::Model> RM,
+ Optional<CodeModel::Model> CM,
+ CodeGenOpt::Level OL, bool JIT)
+ : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options,
+ getEffectiveRelocModel(RM),
+ getEffectiveCodeModel(CM, CodeModel::Small), OL),
+ TLOF(createTLOF()), Subtarget(TT, CPU, FS, *this) {
+ initAsmInfo();
+}
VETargetMachine::~VETargetMachine() {}
+
+TargetTransformInfo VETargetMachine::getTargetTransformInfo(const Function &F) {
+ return TargetTransformInfo(VETTIImpl(this, F));
+}
+
+namespace {
+/// VE Code Generator Pass Configuration Options.
+class VEPassConfig : public TargetPassConfig {
+public:
+ VEPassConfig(VETargetMachine &TM, PassManagerBase &PM)
+ : TargetPassConfig(TM, PM) {}
+
+ VETargetMachine &getVETargetMachine() const {
+ return getTM<VETargetMachine>();
+ }
+
+ bool addInstSelector() override;
+};
+} // namespace
+
+TargetPassConfig *VETargetMachine::createPassConfig(PassManagerBase &PM) {
+ return new VEPassConfig(*this, PM);
+}
+
+bool VEPassConfig::addInstSelector() {
+ addPass(createVEISelDag(getVETargetMachine()));
+ return false;
+}
diff --git a/llvm/lib/Target/VE/VETargetMachine.h b/llvm/lib/Target/VE/VETargetMachine.h
index ac6089036ff8..3191d59ec1c8 100644
--- a/llvm/lib/Target/VE/VETargetMachine.h
+++ b/llvm/lib/Target/VE/VETargetMachine.h
@@ -13,17 +13,43 @@
#ifndef LLVM_LIB_TARGET_VE_VETARGETMACHINE_H
#define LLVM_LIB_TARGET_VE_VETARGETMACHINE_H
+#include "VEInstrInfo.h"
+#include "VESubtarget.h"
#include "llvm/Target/TargetMachine.h"
namespace llvm {
class VETargetMachine : public LLVMTargetMachine {
+ std::unique_ptr<TargetLoweringObjectFile> TLOF;
+ VESubtarget Subtarget;
+ // Hold Strings that can be free'd all together with VETargetMachine
+ // e.g.: "GCC_except_tableXX" string.
+ std::list<std::string> StrList;
+
public:
VETargetMachine(const Target &T, const Triple &TT, StringRef CPU,
StringRef FS, const TargetOptions &Options,
Optional<Reloc::Model> RM, Optional<CodeModel::Model> CM,
CodeGenOpt::Level OL, bool JIT);
~VETargetMachine() override;
+
+ const VESubtarget *getSubtargetImpl() const { return &Subtarget; }
+ const VESubtarget *getSubtargetImpl(const Function &) const override {
+ return &Subtarget;
+ }
+ std::list<std::string> *getStrList() const {
+ return const_cast<std::list<std::string> *>(&StrList);
+ }
+
+ // Pass Pipeline Configuration
+ TargetPassConfig *createPassConfig(PassManagerBase &PM) override;
+ TargetLoweringObjectFile *getObjFileLowering() const override {
+ return TLOF.get();
+ }
+
+ bool isMachineVerifierClean() const override { return false; }
+
+ TargetTransformInfo getTargetTransformInfo(const Function &F) override;
};
} // namespace llvm
diff --git a/llvm/lib/Target/VE/VETargetTransformInfo.h b/llvm/lib/Target/VE/VETargetTransformInfo.h
new file mode 100644
index 000000000000..c267c4d9a578
--- /dev/null
+++ b/llvm/lib/Target/VE/VETargetTransformInfo.h
@@ -0,0 +1,50 @@
+//===- VETargetTransformInfo.h - VE specific TTI ------*- 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
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This file a TargetTransformInfo::Concept conforming object specific to the
+/// VE target machine. It uses the target's detailed information to
+/// provide more precise answers to certain TTI queries, while letting the
+/// target independent and default TTI implementations handle the rest.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_VE_VETARGETTRANSFORMINFO_H
+#define LLVM_LIB_TARGET_VE_VETARGETTRANSFORMINFO_H
+
+#include "VE.h"
+#include "VETargetMachine.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/CodeGen/BasicTTIImpl.h"
+
+namespace llvm {
+
+class VETTIImpl : public BasicTTIImplBase<VETTIImpl> {
+ using BaseT = BasicTTIImplBase<VETTIImpl>;
+ friend BaseT;
+
+ const VESubtarget *ST;
+ const VETargetLowering *TLI;
+
+ const VESubtarget *getST() const { return ST; }
+ const VETargetLowering *getTLI() const { return TLI; }
+
+public:
+ explicit VETTIImpl(const VETargetMachine *TM, const Function &F)
+ : BaseT(TM, F.getParent()->getDataLayout()), ST(TM->getSubtargetImpl(F)),
+ TLI(ST->getTargetLowering()) {}
+
+ unsigned getNumberOfRegisters(unsigned ClassID) const { return 64; }
+
+ unsigned getRegisterBitWidth(bool Vector) const { return 64; }
+
+ unsigned getMinVectorRegisterBitWidth() const { return 64; }
+};
+
+} // namespace llvm
+
+#endif // LLVM_LIB_TARGET_VE_VETARGETTRANSFORMINFO_H
diff --git a/llvm/test/CodeGen/VE/simple_prologue_epilogue.ll b/llvm/test/CodeGen/VE/simple_prologue_epilogue.ll
new file mode 100644
index 000000000000..8470e763f3b4
--- /dev/null
+++ b/llvm/test/CodeGen/VE/simple_prologue_epilogue.ll
@@ -0,0 +1,32 @@
+; RUN: llc < %s -mtriple=ve-unknown-unknown | FileCheck %s
+
+define void @func() {
+; CHECK-LABEL: func:
+; CHECK: # %bb.0:
+; CHECK-NEXT: st %s9, (,%s11)
+; CHECK-NEXT: st %s10, 8(,%s11)
+; CHECK-NEXT: st %s15, 24(,%s11)
+; CHECK-NEXT: st %s16, 32(,%s11)
+; CHECK-NEXT: or %s9, 0, %s11
+; CHECK-NEXT: lea %s13, -176
+; CHECK-NEXT: and %s13, %s13, (32)0
+; CHECK-NEXT: lea.sl %s11, -1(%s11, %s13)
+; CHECK-NEXT: brge.l %s11, %s8, .LBB0_2
+; CHECK-NEXT: # %bb.1:
+; CHECK-NEXT: ld %s61, 24(,%s14)
+; CHECK-NEXT: or %s62, 0, %s0
+; CHECK-NEXT: lea %s63, 315
+; CHECK-NEXT: shm.l %s63, (%s61)
+; CHECK-NEXT: shm.l %s8, 8(%s61)
+; CHECK-NEXT: shm.l %s11, 16(%s61)
+; CHECK-NEXT: monc
+; CHECK-NEXT: or %s0, 0, %s62
+; CHECK-NEXT: .LBB0_2:
+; CHECK-NEXT: or %s11, 0, %s9
+; CHECK-NEXT: ld %s16, 32(,%s11)
+; CHECK-NEXT: ld %s15, 24(,%s11)
+; CHECK-NEXT: ld %s10, 8(,%s11)
+; CHECK-NEXT: ld %s9, (,%s11)
+; CHECK-NEXT: b.l (,%lr)
+ ret void
+}
More information about the llvm-commits
mailing list