summaryrefslogtreecommitdiff
path: root/llvm/lib/Target/VE/MCTargetDesc
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/VE/MCTargetDesc')
-rw-r--r--llvm/lib/Target/VE/MCTargetDesc/VEAsmBackend.cpp224
-rw-r--r--llvm/lib/Target/VE/MCTargetDesc/VEELFObjectWriter.cpp135
-rw-r--r--llvm/lib/Target/VE/MCTargetDesc/VEFixupKinds.h61
-rw-r--r--llvm/lib/Target/VE/MCTargetDesc/VEInstPrinter.cpp227
-rw-r--r--llvm/lib/Target/VE/MCTargetDesc/VEInstPrinter.h62
-rw-r--r--llvm/lib/Target/VE/MCTargetDesc/VEMCAsmInfo.cpp1
-rw-r--r--llvm/lib/Target/VE/MCTargetDesc/VEMCCodeEmitter.cpp165
-rw-r--r--llvm/lib/Target/VE/MCTargetDesc/VEMCExpr.cpp225
-rw-r--r--llvm/lib/Target/VE/MCTargetDesc/VEMCExpr.h95
-rw-r--r--llvm/lib/Target/VE/MCTargetDesc/VEMCTargetDesc.cpp11
-rw-r--r--llvm/lib/Target/VE/MCTargetDesc/VEMCTargetDesc.h10
-rw-r--r--llvm/lib/Target/VE/MCTargetDesc/VETargetStreamer.cpp2
12 files changed, 1212 insertions, 6 deletions
diff --git a/llvm/lib/Target/VE/MCTargetDesc/VEAsmBackend.cpp b/llvm/lib/Target/VE/MCTargetDesc/VEAsmBackend.cpp
new file mode 100644
index 0000000000000..9a6ae90b5c73c
--- /dev/null
+++ b/llvm/lib/Target/VE/MCTargetDesc/VEAsmBackend.cpp
@@ -0,0 +1,224 @@
+//===-- VEAsmBackend.cpp - VE Assembler Backend ---------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "MCTargetDesc/VEFixupKinds.h"
+#include "MCTargetDesc/VEMCTargetDesc.h"
+#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/MC/MCELFObjectWriter.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCFixupKindInfo.h"
+#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/MC/MCValue.h"
+#include "llvm/Support/EndianStream.h"
+#include "llvm/Support/TargetRegistry.h"
+
+using namespace llvm;
+
+static uint64_t adjustFixupValue(unsigned Kind, uint64_t Value) {
+ switch (Kind) {
+ default:
+ llvm_unreachable("Unknown fixup kind!");
+ case FK_Data_1:
+ case FK_Data_2:
+ case FK_Data_4:
+ case FK_Data_8:
+ case FK_PCRel_1:
+ case FK_PCRel_2:
+ case FK_PCRel_4:
+ case FK_PCRel_8:
+ return Value;
+ case VE::fixup_ve_hi32:
+ case VE::fixup_ve_pc_hi32:
+ case VE::fixup_ve_got_hi32:
+ case VE::fixup_ve_gotoff_hi32:
+ case VE::fixup_ve_plt_hi32:
+ case VE::fixup_ve_tls_gd_hi32:
+ case VE::fixup_ve_tpoff_hi32:
+ return (Value >> 32) & 0xffffffff;
+ case VE::fixup_ve_reflong:
+ case VE::fixup_ve_lo32:
+ case VE::fixup_ve_pc_lo32:
+ case VE::fixup_ve_got_lo32:
+ case VE::fixup_ve_gotoff_lo32:
+ case VE::fixup_ve_plt_lo32:
+ case VE::fixup_ve_tls_gd_lo32:
+ case VE::fixup_ve_tpoff_lo32:
+ return Value & 0xffffffff;
+ }
+}
+
+/// getFixupKindNumBytes - The number of bytes the fixup may change.
+static unsigned getFixupKindNumBytes(unsigned Kind) {
+ switch (Kind) {
+ default:
+ llvm_unreachable("Unknown fixup kind!");
+ case FK_Data_1:
+ case FK_PCRel_1:
+ return 1;
+ case FK_Data_2:
+ case FK_PCRel_2:
+ return 2;
+ return 4;
+ case FK_Data_4:
+ case FK_PCRel_4:
+ case VE::fixup_ve_reflong:
+ case VE::fixup_ve_hi32:
+ case VE::fixup_ve_lo32:
+ case VE::fixup_ve_pc_hi32:
+ case VE::fixup_ve_pc_lo32:
+ case VE::fixup_ve_got_hi32:
+ case VE::fixup_ve_got_lo32:
+ case VE::fixup_ve_gotoff_hi32:
+ case VE::fixup_ve_gotoff_lo32:
+ case VE::fixup_ve_plt_hi32:
+ case VE::fixup_ve_plt_lo32:
+ case VE::fixup_ve_tls_gd_hi32:
+ case VE::fixup_ve_tls_gd_lo32:
+ case VE::fixup_ve_tpoff_hi32:
+ case VE::fixup_ve_tpoff_lo32:
+ return 4;
+ case FK_Data_8:
+ case FK_PCRel_8:
+ return 8;
+ }
+}
+
+namespace {
+class VEAsmBackend : public MCAsmBackend {
+protected:
+ const Target &TheTarget;
+
+public:
+ VEAsmBackend(const Target &T) : MCAsmBackend(support::little), TheTarget(T) {}
+
+ unsigned getNumFixupKinds() const override { return VE::NumTargetFixupKinds; }
+
+ const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override {
+ const static MCFixupKindInfo Infos[VE::NumTargetFixupKinds] = {
+ // name, offset, bits, flags
+ {"fixup_ve_reflong", 0, 32, 0},
+ {"fixup_ve_hi32", 0, 32, 0},
+ {"fixup_ve_lo32", 0, 32, 0},
+ {"fixup_ve_pc_hi32", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
+ {"fixup_ve_pc_lo32", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
+ {"fixup_ve_got_hi32", 0, 32, 0},
+ {"fixup_ve_got_lo32", 0, 32, 0},
+ {"fixup_ve_gotoff_hi32", 0, 32, 0},
+ {"fixup_ve_gotoff_lo32", 0, 32, 0},
+ {"fixup_ve_plt_hi32", 0, 32, 0},
+ {"fixup_ve_plt_lo32", 0, 32, 0},
+ {"fixup_ve_tls_gd_hi32", 0, 32, 0},
+ {"fixup_ve_tls_gd_lo32", 0, 32, 0},
+ {"fixup_ve_tpoff_hi32", 0, 32, 0},
+ {"fixup_ve_tpoff_lo32", 0, 32, 0},
+ };
+
+ if (Kind < FirstTargetFixupKind)
+ return MCAsmBackend::getFixupKindInfo(Kind);
+
+ assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
+ "Invalid kind!");
+ return Infos[Kind - FirstTargetFixupKind];
+ }
+
+ bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
+ const MCValue &Target) override {
+ switch ((VE::Fixups)Fixup.getKind()) {
+ default:
+ return false;
+ case VE::fixup_ve_tls_gd_hi32:
+ case VE::fixup_ve_tls_gd_lo32:
+ case VE::fixup_ve_tpoff_hi32:
+ case VE::fixup_ve_tpoff_lo32:
+ return true;
+ }
+ }
+
+ bool mayNeedRelaxation(const MCInst &Inst,
+ const MCSubtargetInfo &STI) const override {
+ // Not implemented yet. For example, if we have a branch with
+ // lager than SIMM32 immediate value, we want to relaxation such
+ // branch instructions.
+ return false;
+ }
+
+ /// fixupNeedsRelaxation - Target specific predicate for whether a given
+ /// fixup requires the associated instruction to be relaxed.
+ bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
+ const MCRelaxableFragment *DF,
+ const MCAsmLayout &Layout) const override {
+ // Not implemented yet. For example, if we have a branch with
+ // lager than SIMM32 immediate value, we want to relaxation such
+ // branch instructions.
+ return false;
+ }
+ void relaxInstruction(MCInst &Inst,
+ const MCSubtargetInfo &STI) const override {
+ // Aurora VE doesn't support relaxInstruction yet.
+ llvm_unreachable("relaxInstruction() should not be called");
+ }
+
+ bool writeNopData(raw_ostream &OS, uint64_t Count) const override {
+ if ((Count % 8) != 0)
+ return false;
+
+ for (uint64_t i = 0; i < Count; i += 8)
+ support::endian::write<uint64_t>(OS, 0x7900000000000000ULL,
+ support::little);
+
+ return true;
+ }
+};
+
+class ELFVEAsmBackend : public VEAsmBackend {
+ Triple::OSType OSType;
+
+public:
+ ELFVEAsmBackend(const Target &T, Triple::OSType OSType)
+ : VEAsmBackend(T), OSType(OSType) {}
+
+ void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
+ const MCValue &Target, MutableArrayRef<char> Data,
+ uint64_t Value, bool IsResolved,
+ const MCSubtargetInfo *STI) const override {
+ Value = adjustFixupValue(Fixup.getKind(), Value);
+ if (!Value)
+ return; // Doesn't change encoding.
+
+ MCFixupKindInfo Info = getFixupKindInfo(Fixup.getKind());
+
+ // Shift the value into position.
+ Value <<= Info.TargetOffset;
+
+ unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind());
+ unsigned Offset = Fixup.getOffset();
+ assert(Offset + NumBytes <= Data.size() && "Invalid fixup offset!");
+ // For each byte of the fragment that the fixup touches, mask in the bits
+ // from the fixup value. The Value has been "split up" into the
+ // appropriate bitfields above.
+ for (unsigned i = 0; i != NumBytes; ++i) {
+ unsigned Idx = Endian == support::little ? i : (NumBytes - 1) - i;
+ Data[Offset + Idx] |= static_cast<uint8_t>((Value >> (i * 8)) & 0xff);
+ }
+ }
+
+ std::unique_ptr<MCObjectTargetWriter>
+ createObjectTargetWriter() const override {
+ uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(OSType);
+ return createVEELFObjectWriter(OSABI);
+ }
+};
+} // end anonymous namespace
+
+MCAsmBackend *llvm::createVEAsmBackend(const Target &T,
+ const MCSubtargetInfo &STI,
+ const MCRegisterInfo &MRI,
+ const MCTargetOptions &Options) {
+ return new ELFVEAsmBackend(T, STI.getTargetTriple().getOS());
+}
diff --git a/llvm/lib/Target/VE/MCTargetDesc/VEELFObjectWriter.cpp b/llvm/lib/Target/VE/MCTargetDesc/VEELFObjectWriter.cpp
new file mode 100644
index 0000000000000..741e8320a9411
--- /dev/null
+++ b/llvm/lib/Target/VE/MCTargetDesc/VEELFObjectWriter.cpp
@@ -0,0 +1,135 @@
+//===-- VEELFObjectWriter.cpp - VE ELF 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "VEFixupKinds.h"
+#include "VEMCExpr.h"
+#include "VEMCTargetDesc.h"
+#include "llvm/MC/MCELFObjectWriter.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/MC/MCValue.h"
+#include "llvm/Support/ErrorHandling.h"
+
+using namespace llvm;
+
+namespace {
+class VEELFObjectWriter : public MCELFObjectTargetWriter {
+public:
+ VEELFObjectWriter(uint8_t OSABI)
+ : MCELFObjectTargetWriter(/* Is64Bit */ true, OSABI, ELF::EM_VE,
+ /* HasRelocationAddend */ true) {}
+
+ ~VEELFObjectWriter() override {}
+
+protected:
+ unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
+ const MCFixup &Fixup, bool IsPCRel) const override;
+
+ bool needsRelocateWithSymbol(const MCSymbol &Sym,
+ unsigned Type) const override;
+};
+} // namespace
+
+unsigned VEELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
+ const MCFixup &Fixup,
+ bool IsPCRel) const {
+ if (const VEMCExpr *SExpr = dyn_cast<VEMCExpr>(Fixup.getValue())) {
+ if (SExpr->getKind() == VEMCExpr::VK_VE_PC_LO32)
+ return ELF::R_VE_PC_LO32;
+ }
+
+ if (IsPCRel) {
+ switch (Fixup.getTargetKind()) {
+ default:
+ llvm_unreachable("Unimplemented fixup -> relocation");
+ case FK_PCRel_1:
+ llvm_unreachable("Unimplemented fixup fk_data_1 -> relocation");
+ case FK_PCRel_2:
+ llvm_unreachable("Unimplemented fixup fk_data_2 -> relocation");
+ // FIXME: relative kind?
+ case FK_PCRel_4:
+ return ELF::R_VE_REFLONG;
+ case FK_PCRel_8:
+ return ELF::R_VE_REFQUAD;
+ case VE::fixup_ve_pc_hi32:
+ return ELF::R_VE_PC_HI32;
+ case VE::fixup_ve_pc_lo32:
+ return ELF::R_VE_PC_LO32;
+ }
+ }
+
+ switch (Fixup.getTargetKind()) {
+ default:
+ llvm_unreachable("Unimplemented fixup -> relocation");
+ case FK_Data_1:
+ llvm_unreachable("Unimplemented fixup fk_data_1 -> relocation");
+ case FK_Data_2:
+ llvm_unreachable("Unimplemented fixup fk_data_2 -> relocation");
+ case FK_Data_4:
+ return ELF::R_VE_REFLONG;
+ case FK_Data_8:
+ return ELF::R_VE_REFQUAD;
+ case VE::fixup_ve_reflong:
+ return ELF::R_VE_REFLONG;
+ case VE::fixup_ve_hi32:
+ return ELF::R_VE_HI32;
+ case VE::fixup_ve_lo32:
+ return ELF::R_VE_LO32;
+ case VE::fixup_ve_pc_hi32:
+ llvm_unreachable("Unimplemented fixup pc_hi32 -> relocation");
+ case VE::fixup_ve_pc_lo32:
+ llvm_unreachable("Unimplemented fixup pc_lo32 -> relocation");
+ case VE::fixup_ve_got_hi32:
+ return ELF::R_VE_GOT_HI32;
+ case VE::fixup_ve_got_lo32:
+ return ELF::R_VE_GOT_LO32;
+ case VE::fixup_ve_gotoff_hi32:
+ return ELF::R_VE_GOTOFF_HI32;
+ case VE::fixup_ve_gotoff_lo32:
+ return ELF::R_VE_GOTOFF_LO32;
+ case VE::fixup_ve_plt_hi32:
+ return ELF::R_VE_PLT_HI32;
+ case VE::fixup_ve_plt_lo32:
+ return ELF::R_VE_PLT_LO32;
+ case VE::fixup_ve_tls_gd_hi32:
+ return ELF::R_VE_TLS_GD_HI32;
+ case VE::fixup_ve_tls_gd_lo32:
+ return ELF::R_VE_TLS_GD_LO32;
+ case VE::fixup_ve_tpoff_hi32:
+ return ELF::R_VE_TPOFF_HI32;
+ case VE::fixup_ve_tpoff_lo32:
+ return ELF::R_VE_TPOFF_LO32;
+ }
+
+ return ELF::R_VE_NONE;
+}
+
+bool VEELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym,
+ unsigned Type) const {
+ switch (Type) {
+ default:
+ return false;
+
+ // All relocations that use a GOT need a symbol, not an offset, as
+ // the offset of the symbol within the section is irrelevant to
+ // where the GOT entry is. Don't need to list all the TLS entries,
+ // as they're all marked as requiring a symbol anyways.
+ case ELF::R_VE_GOT_HI32:
+ case ELF::R_VE_GOT_LO32:
+ case ELF::R_VE_GOTOFF_HI32:
+ case ELF::R_VE_GOTOFF_LO32:
+ case ELF::R_VE_TLS_GD_HI32:
+ case ELF::R_VE_TLS_GD_LO32:
+ return true;
+ }
+}
+
+std::unique_ptr<MCObjectTargetWriter>
+llvm::createVEELFObjectWriter(uint8_t OSABI) {
+ return std::make_unique<VEELFObjectWriter>(OSABI);
+}
diff --git a/llvm/lib/Target/VE/MCTargetDesc/VEFixupKinds.h b/llvm/lib/Target/VE/MCTargetDesc/VEFixupKinds.h
new file mode 100644
index 0000000000000..5d5dc1c5c891a
--- /dev/null
+++ b/llvm/lib/Target/VE/MCTargetDesc/VEFixupKinds.h
@@ -0,0 +1,61 @@
+//===-- VEFixupKinds.h - VE Specific Fixup Entries --------------*- 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_MCTARGETDESC_VEFIXUPKINDS_H
+#define LLVM_LIB_TARGET_VE_MCTARGETDESC_VEFIXUPKINDS_H
+
+#include "llvm/MC/MCFixup.h"
+
+namespace llvm {
+namespace VE {
+enum Fixups {
+ /// fixup_ve_reflong - 32-bit fixup corresponding to foo
+ fixup_ve_reflong = FirstTargetFixupKind,
+
+ /// fixup_ve_hi32 - 32-bit fixup corresponding to foo@hi
+ fixup_ve_hi32,
+
+ /// fixup_ve_lo32 - 32-bit fixup corresponding to foo@lo
+ fixup_ve_lo32,
+
+ /// fixup_ve_pc_hi32 - 32-bit fixup corresponding to foo@pc_hi
+ fixup_ve_pc_hi32,
+
+ /// fixup_ve_pc_lo32 - 32-bit fixup corresponding to foo@pc_lo
+ fixup_ve_pc_lo32,
+
+ /// fixup_ve_got_hi32 - 32-bit fixup corresponding to foo@got_hi
+ fixup_ve_got_hi32,
+
+ /// fixup_ve_got_lo32 - 32-bit fixup corresponding to foo@got_lo
+ fixup_ve_got_lo32,
+
+ /// fixup_ve_gotoff_hi32 - 32-bit fixup corresponding to foo@gotoff_hi
+ fixup_ve_gotoff_hi32,
+
+ /// fixup_ve_gotoff_lo32 - 32-bit fixup corresponding to foo@gotoff_lo
+ fixup_ve_gotoff_lo32,
+
+ /// fixup_ve_plt_hi32/lo32
+ fixup_ve_plt_hi32,
+ fixup_ve_plt_lo32,
+
+ /// fixups for Thread Local Storage
+ fixup_ve_tls_gd_hi32,
+ fixup_ve_tls_gd_lo32,
+ fixup_ve_tpoff_hi32,
+ fixup_ve_tpoff_lo32,
+
+ // Marker
+ LastTargetFixupKind,
+ NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
+};
+} // namespace VE
+} // namespace llvm
+
+#endif
diff --git a/llvm/lib/Target/VE/MCTargetDesc/VEInstPrinter.cpp b/llvm/lib/Target/VE/MCTargetDesc/VEInstPrinter.cpp
new file mode 100644
index 0000000000000..1fe9423e01b80
--- /dev/null
+++ b/llvm/lib/Target/VE/MCTargetDesc/VEInstPrinter.cpp
@@ -0,0 +1,227 @@
+//===-- 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 {
+ // Generic registers have identical register name among register classes.
+ unsigned AltIdx = VE::AsmName;
+ // Misc registers have each own name, so no use alt-names.
+ if (MRI.getRegClass(VE::MISCRegClassID).contains(RegNo))
+ AltIdx = VE::NoRegAltName;
+ OS << '%' << getRegisterName(RegNo, AltIdx);
+}
+
+void VEInstPrinter::printInst(const MCInst *MI, uint64_t Address,
+ StringRef Annot, const MCSubtargetInfo &STI,
+ raw_ostream &OS) {
+ if (!printAliasInstr(MI, Address, 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
+ 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;
+ }
+
+ if (MI->getOperand(OpNum + 2).isImm() &&
+ MI->getOperand(OpNum + 2).getImm() == 0) {
+ // don't print "+0"
+ } else {
+ printOperand(MI, OpNum + 2, STI, O);
+ }
+ if (MI->getOperand(OpNum + 1).isImm() &&
+ MI->getOperand(OpNum + 1).getImm() == 0 &&
+ MI->getOperand(OpNum).isImm() && MI->getOperand(OpNum).getImm() == 0) {
+ if (MI->getOperand(OpNum + 2).isImm() &&
+ MI->getOperand(OpNum + 2).getImm() == 0) {
+ O << "0";
+ } else {
+ // don't print "+0,+0"
+ }
+ } else {
+ O << "(";
+ if (MI->getOperand(OpNum + 1).isImm() &&
+ MI->getOperand(OpNum + 1).getImm() == 0) {
+ // don't print "+0"
+ } else {
+ printOperand(MI, OpNum + 1, STI, O);
+ }
+ if (MI->getOperand(OpNum).isImm() && MI->getOperand(OpNum).getImm() == 0) {
+ // don't print "+0"
+ } else {
+ O << ", ";
+ printOperand(MI, OpNum, STI, O);
+ }
+ O << ")";
+ }
+}
+
+void VEInstPrinter::printMemASOperandASX(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;
+ }
+
+ if (MI->getOperand(OpNum + 1).isImm() &&
+ MI->getOperand(OpNum + 1).getImm() == 0) {
+ // don't print "+0"
+ } else {
+ printOperand(MI, OpNum + 1, STI, O);
+ }
+ if (MI->getOperand(OpNum).isImm() && MI->getOperand(OpNum).getImm() == 0) {
+ if (MI->getOperand(OpNum + 1).isImm() &&
+ MI->getOperand(OpNum + 1).getImm() == 0) {
+ O << "0";
+ } else {
+ // don't print "(0)"
+ }
+ } else {
+ O << "(, ";
+ printOperand(MI, OpNum, STI, O);
+ O << ")";
+ }
+}
+
+void VEInstPrinter::printMemASOperandRRM(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;
+ }
+
+ if (MI->getOperand(OpNum + 1).isImm() &&
+ MI->getOperand(OpNum + 1).getImm() == 0) {
+ // don't print "+0"
+ } else {
+ printOperand(MI, OpNum + 1, STI, O);
+ }
+ if (MI->getOperand(OpNum).isImm() && MI->getOperand(OpNum).getImm() == 0) {
+ if (MI->getOperand(OpNum + 1).isImm() &&
+ MI->getOperand(OpNum + 1).getImm() == 0) {
+ O << "0";
+ } else {
+ // don't print "(0)"
+ }
+ } else {
+ O << "(";
+ printOperand(MI, OpNum, STI, O);
+ O << ")";
+ }
+}
+
+void VEInstPrinter::printMemASOperandHM(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;
+ }
+
+ if (MI->getOperand(OpNum + 1).isImm() &&
+ MI->getOperand(OpNum + 1).getImm() == 0) {
+ // don't print "+0"
+ } else {
+ printOperand(MI, OpNum + 1, STI, O);
+ }
+ O << "(";
+ if (MI->getOperand(OpNum).isReg())
+ printOperand(MI, OpNum, STI, O);
+ O << ")";
+}
+
+void VEInstPrinter::printMImmOperand(const MCInst *MI, int OpNum,
+ const MCSubtargetInfo &STI,
+ raw_ostream &O) {
+ int MImm = (int)MI->getOperand(OpNum).getImm() & 0x7f;
+ if (MImm > 63)
+ O << "(" << MImm - 64 << ")0";
+ else
+ O << "(" << MImm << ")1";
+}
+
+void VEInstPrinter::printCCOperand(const MCInst *MI, int OpNum,
+ const MCSubtargetInfo &STI, raw_ostream &O) {
+ int CC = (int)MI->getOperand(OpNum).getImm();
+ O << VECondCodeToString((VECC::CondCode)CC);
+}
+
+void VEInstPrinter::printRDOperand(const MCInst *MI, int OpNum,
+ const MCSubtargetInfo &STI, raw_ostream &O) {
+ int RD = (int)MI->getOperand(OpNum).getImm();
+ O << VERDToString((VERD::RoundingMode)RD);
+}
diff --git a/llvm/lib/Target/VE/MCTargetDesc/VEInstPrinter.h b/llvm/lib/Target/VE/MCTargetDesc/VEInstPrinter.h
new file mode 100644
index 0000000000000..657cc513b3c50
--- /dev/null
+++ b/llvm/lib/Target/VE/MCTargetDesc/VEInstPrinter.h
@@ -0,0 +1,62 @@
+//===-- 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 "VEMCTargetDesc.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 *, uint64_t Address,
+ const MCSubtargetInfo &, raw_ostream &);
+ void printInstruction(const MCInst *, uint64_t, const MCSubtargetInfo &,
+ raw_ostream &);
+ static const char *getRegisterName(unsigned RegNo,
+ unsigned AltIdx = VE::NoRegAltName);
+
+ 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 printMemASOperandASX(const MCInst *MI, int OpNum,
+ const MCSubtargetInfo &STI, raw_ostream &OS,
+ const char *Modifier = nullptr);
+ void printMemASOperandRRM(const MCInst *MI, int OpNum,
+ const MCSubtargetInfo &STI, raw_ostream &OS,
+ const char *Modifier = nullptr);
+ void printMemASOperandHM(const MCInst *MI, int OpNum,
+ const MCSubtargetInfo &STI, raw_ostream &OS,
+ const char *Modifier = nullptr);
+ void printMImmOperand(const MCInst *MI, int OpNum, const MCSubtargetInfo &STI,
+ raw_ostream &OS);
+ void printCCOperand(const MCInst *MI, int OpNum, const MCSubtargetInfo &STI,
+ raw_ostream &OS);
+ void printRDOperand(const MCInst *MI, int OpNum, const MCSubtargetInfo &STI,
+ raw_ostream &OS);
+};
+} // namespace llvm
+
+#endif
diff --git a/llvm/lib/Target/VE/MCTargetDesc/VEMCAsmInfo.cpp b/llvm/lib/Target/VE/MCTargetDesc/VEMCAsmInfo.cpp
index 9f29fc092c697..76824335239b7 100644
--- a/llvm/lib/Target/VE/MCTargetDesc/VEMCAsmInfo.cpp
+++ b/llvm/lib/Target/VE/MCTargetDesc/VEMCAsmInfo.cpp
@@ -37,4 +37,5 @@ VEELFMCAsmInfo::VEELFMCAsmInfo(const Triple &TheTriple) {
UsesELFSectionDirectiveForBSS = true;
SupportsDebugInformation = true;
+ UseIntegratedAssembler = false;
}
diff --git a/llvm/lib/Target/VE/MCTargetDesc/VEMCCodeEmitter.cpp b/llvm/lib/Target/VE/MCTargetDesc/VEMCCodeEmitter.cpp
new file mode 100644
index 0000000000000..d50d8fcae9daa
--- /dev/null
+++ b/llvm/lib/Target/VE/MCTargetDesc/VEMCCodeEmitter.cpp
@@ -0,0 +1,165 @@
+//===-- VEMCCodeEmitter.cpp - Convert VE code to machine code -------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the VEMCCodeEmitter class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MCTargetDesc/VEFixupKinds.h"
+#include "VE.h"
+#include "VEMCExpr.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCFixup.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/Support/EndianStream.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+#include <cstdint>
+
+using namespace llvm;
+
+#define DEBUG_TYPE "mccodeemitter"
+
+STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
+
+namespace {
+
+class VEMCCodeEmitter : public MCCodeEmitter {
+ const MCInstrInfo &MCII;
+ MCContext &Ctx;
+
+public:
+ VEMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx)
+ : MCII(mcii), Ctx(ctx) {}
+ VEMCCodeEmitter(const VEMCCodeEmitter &) = delete;
+ VEMCCodeEmitter &operator=(const VEMCCodeEmitter &) = delete;
+ ~VEMCCodeEmitter() override = default;
+
+ void encodeInstruction(const MCInst &MI, raw_ostream &OS,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const override;
+
+ // getBinaryCodeForInstr - TableGen'erated function for getting the
+ // binary encoding for an instruction.
+ uint64_t getBinaryCodeForInstr(const MCInst &MI,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
+
+ /// getMachineOpValue - Return binary encoding of operand. If the machine
+ /// operand requires relocation, record the relocation and return zero.
+ unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
+
+ uint64_t getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
+ uint64_t getCCOpValue(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
+ uint64_t getRDOpValue(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
+
+private:
+ FeatureBitset computeAvailableFeatures(const FeatureBitset &FB) const;
+ void
+ verifyInstructionPredicates(const MCInst &MI,
+ const FeatureBitset &AvailableFeatures) const;
+};
+
+} // end anonymous namespace
+
+void VEMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ verifyInstructionPredicates(MI,
+ computeAvailableFeatures(STI.getFeatureBits()));
+
+ uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
+ support::endian::write<uint64_t>(OS, Bits, support::little);
+
+ ++MCNumEmitted; // Keep track of the # of mi's emitted.
+}
+
+unsigned VEMCCodeEmitter::getMachineOpValue(const MCInst &MI,
+ const MCOperand &MO,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ if (MO.isReg())
+ return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
+
+ if (MO.isImm())
+ return MO.getImm();
+
+ assert(MO.isExpr());
+ const MCExpr *Expr = MO.getExpr();
+ if (const VEMCExpr *SExpr = dyn_cast<VEMCExpr>(Expr)) {
+ MCFixupKind Kind = (MCFixupKind)SExpr->getFixupKind();
+ Fixups.push_back(MCFixup::create(0, Expr, Kind));
+ return 0;
+ }
+
+ int64_t Res;
+ if (Expr->evaluateAsAbsolute(Res))
+ return Res;
+
+ llvm_unreachable("Unhandled expression!");
+ return 0;
+}
+
+uint64_t
+VEMCCodeEmitter::getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ const MCOperand &MO = MI.getOperand(OpNo);
+ if (MO.isReg() || MO.isImm())
+ return getMachineOpValue(MI, MO, Fixups, STI);
+
+ Fixups.push_back(
+ MCFixup::create(0, MO.getExpr(), (MCFixupKind)VE::fixup_ve_pc_lo32));
+ return 0;
+}
+
+uint64_t VEMCCodeEmitter::getCCOpValue(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ const MCOperand &MO = MI.getOperand(OpNo);
+ if (MO.isImm())
+ return VECondCodeToVal(
+ static_cast<VECC::CondCode>(getMachineOpValue(MI, MO, Fixups, STI)));
+ return 0;
+}
+
+uint64_t VEMCCodeEmitter::getRDOpValue(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ const MCOperand &MO = MI.getOperand(OpNo);
+ if (MO.isImm())
+ return VERDToVal(static_cast<VERD::RoundingMode>(
+ getMachineOpValue(MI, MO, Fixups, STI)));
+ return 0;
+}
+
+#define ENABLE_INSTR_PREDICATE_VERIFIER
+#include "VEGenMCCodeEmitter.inc"
+
+MCCodeEmitter *llvm::createVEMCCodeEmitter(const MCInstrInfo &MCII,
+ const MCRegisterInfo &MRI,
+ MCContext &Ctx) {
+ return new VEMCCodeEmitter(MCII, Ctx);
+}
diff --git a/llvm/lib/Target/VE/MCTargetDesc/VEMCExpr.cpp b/llvm/lib/Target/VE/MCTargetDesc/VEMCExpr.cpp
new file mode 100644
index 0000000000000..a3ce3b3309be8
--- /dev/null
+++ b/llvm/lib/Target/VE/MCTargetDesc/VEMCExpr.cpp
@@ -0,0 +1,225 @@
+//===-- VEMCExpr.cpp - VE specific MC expression classes ------------------===//
+//
+// 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 implementation of the assembly expression modifiers
+// accepted by the VE architecture (e.g. "%hi", "%lo", ...).
+//
+//===----------------------------------------------------------------------===//
+
+#include "VEMCExpr.h"
+#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCObjectStreamer.h"
+#include "llvm/MC/MCSymbolELF.h"
+#include "llvm/BinaryFormat/ELF.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "vemcexpr"
+
+const VEMCExpr *VEMCExpr::create(VariantKind Kind, const MCExpr *Expr,
+ MCContext &Ctx) {
+ return new (Ctx) VEMCExpr(Kind, Expr);
+}
+
+void VEMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
+
+ bool closeParen = printVariantKind(OS, Kind);
+
+ const MCExpr *Expr = getSubExpr();
+ Expr->print(OS, MAI);
+
+ if (closeParen)
+ OS << ')';
+ printVariantKindSuffix(OS, Kind);
+}
+
+bool VEMCExpr::printVariantKind(raw_ostream &OS, VariantKind Kind) {
+ switch (Kind) {
+ case VK_VE_None:
+ case VK_VE_REFLONG:
+ return false;
+
+ case VK_VE_HI32:
+ case VK_VE_LO32:
+ case VK_VE_PC_HI32:
+ case VK_VE_PC_LO32:
+ case VK_VE_GOT_HI32:
+ case VK_VE_GOT_LO32:
+ case VK_VE_GOTOFF_HI32:
+ case VK_VE_GOTOFF_LO32:
+ case VK_VE_PLT_HI32:
+ case VK_VE_PLT_LO32:
+ case VK_VE_TLS_GD_HI32:
+ case VK_VE_TLS_GD_LO32:
+ case VK_VE_TPOFF_HI32:
+ case VK_VE_TPOFF_LO32:
+ // Use suffix for these variant kinds
+ return false;
+ }
+ return true;
+}
+
+void VEMCExpr::printVariantKindSuffix(raw_ostream &OS, VariantKind Kind) {
+ switch (Kind) {
+ case VK_VE_None:
+ case VK_VE_REFLONG:
+ break;
+ case VK_VE_HI32:
+ OS << "@hi";
+ break;
+ case VK_VE_LO32:
+ OS << "@lo";
+ break;
+ case VK_VE_PC_HI32:
+ OS << "@pc_hi";
+ break;
+ case VK_VE_PC_LO32:
+ OS << "@pc_lo";
+ break;
+ case VK_VE_GOT_HI32:
+ OS << "@got_hi";
+ break;
+ case VK_VE_GOT_LO32:
+ OS << "@got_lo";
+ break;
+ case VK_VE_GOTOFF_HI32:
+ OS << "@gotoff_hi";
+ break;
+ case VK_VE_GOTOFF_LO32:
+ OS << "@gotoff_lo";
+ break;
+ case VK_VE_PLT_HI32:
+ OS << "@plt_hi";
+ break;
+ case VK_VE_PLT_LO32:
+ OS << "@plt_lo";
+ break;
+ case VK_VE_TLS_GD_HI32:
+ OS << "@tls_gd_hi";
+ break;
+ case VK_VE_TLS_GD_LO32:
+ OS << "@tls_gd_lo";
+ break;
+ case VK_VE_TPOFF_HI32:
+ OS << "@tpoff_hi";
+ break;
+ case VK_VE_TPOFF_LO32:
+ OS << "@tpoff_lo";
+ break;
+ }
+}
+
+VEMCExpr::VariantKind VEMCExpr::parseVariantKind(StringRef name) {
+ return StringSwitch<VEMCExpr::VariantKind>(name)
+ .Case("hi", VK_VE_HI32)
+ .Case("lo", VK_VE_LO32)
+ .Case("pc_hi", VK_VE_PC_HI32)
+ .Case("pc_lo", VK_VE_PC_LO32)
+ .Case("got_hi", VK_VE_GOT_HI32)
+ .Case("got_lo", VK_VE_GOT_LO32)
+ .Case("gotoff_hi", VK_VE_GOTOFF_HI32)
+ .Case("gotoff_lo", VK_VE_GOTOFF_LO32)
+ .Case("plt_hi", VK_VE_PLT_HI32)
+ .Case("plt_lo", VK_VE_PLT_LO32)
+ .Case("tls_gd_hi", VK_VE_TLS_GD_HI32)
+ .Case("tls_gd_lo", VK_VE_TLS_GD_LO32)
+ .Case("tpoff_hi", VK_VE_TPOFF_HI32)
+ .Case("tpoff_lo", VK_VE_TPOFF_LO32)
+ .Default(VK_VE_None);
+}
+
+VE::Fixups VEMCExpr::getFixupKind(VEMCExpr::VariantKind Kind) {
+ switch (Kind) {
+ default:
+ llvm_unreachable("Unhandled VEMCExpr::VariantKind");
+ case VK_VE_REFLONG:
+ return VE::fixup_ve_reflong;
+ case VK_VE_HI32:
+ return VE::fixup_ve_hi32;
+ case VK_VE_LO32:
+ return VE::fixup_ve_lo32;
+ case VK_VE_PC_HI32:
+ return VE::fixup_ve_pc_hi32;
+ case VK_VE_PC_LO32:
+ return VE::fixup_ve_pc_lo32;
+ case VK_VE_GOT_HI32:
+ return VE::fixup_ve_got_hi32;
+ case VK_VE_GOT_LO32:
+ return VE::fixup_ve_got_lo32;
+ case VK_VE_GOTOFF_HI32:
+ return VE::fixup_ve_gotoff_hi32;
+ case VK_VE_GOTOFF_LO32:
+ return VE::fixup_ve_gotoff_lo32;
+ case VK_VE_PLT_HI32:
+ return VE::fixup_ve_plt_hi32;
+ case VK_VE_PLT_LO32:
+ return VE::fixup_ve_plt_lo32;
+ case VK_VE_TLS_GD_HI32:
+ return VE::fixup_ve_tls_gd_hi32;
+ case VK_VE_TLS_GD_LO32:
+ return VE::fixup_ve_tls_gd_lo32;
+ case VK_VE_TPOFF_HI32:
+ return VE::fixup_ve_tpoff_hi32;
+ case VK_VE_TPOFF_LO32:
+ return VE::fixup_ve_tpoff_lo32;
+ }
+}
+
+bool VEMCExpr::evaluateAsRelocatableImpl(MCValue &Res,
+ const MCAsmLayout *Layout,
+ const MCFixup *Fixup) const {
+ return getSubExpr()->evaluateAsRelocatable(Res, Layout, Fixup);
+}
+
+static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) {
+ switch (Expr->getKind()) {
+ case MCExpr::Target:
+ llvm_unreachable("Can't handle nested target expr!");
+ break;
+
+ case MCExpr::Constant:
+ break;
+
+ case MCExpr::Binary: {
+ const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
+ fixELFSymbolsInTLSFixupsImpl(BE->getLHS(), Asm);
+ fixELFSymbolsInTLSFixupsImpl(BE->getRHS(), Asm);
+ break;
+ }
+
+ case MCExpr::SymbolRef: {
+ // We're known to be under a TLS fixup, so any symbol should be
+ // modified. There should be only one.
+ const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);
+ cast<MCSymbolELF>(SymRef.getSymbol()).setType(ELF::STT_TLS);
+ break;
+ }
+
+ case MCExpr::Unary:
+ fixELFSymbolsInTLSFixupsImpl(cast<MCUnaryExpr>(Expr)->getSubExpr(), Asm);
+ break;
+ }
+}
+
+void VEMCExpr::visitUsedExpr(MCStreamer &Streamer) const {
+ Streamer.visitUsedExpr(*getSubExpr());
+}
+
+void VEMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {
+ switch (getKind()) {
+ default:
+ return;
+ case VK_VE_TLS_GD_HI32:
+ case VK_VE_TLS_GD_LO32:
+ case VK_VE_TPOFF_HI32:
+ case VK_VE_TPOFF_LO32:
+ break;
+ }
+ fixELFSymbolsInTLSFixupsImpl(getSubExpr(), Asm);
+}
diff --git a/llvm/lib/Target/VE/MCTargetDesc/VEMCExpr.h b/llvm/lib/Target/VE/MCTargetDesc/VEMCExpr.h
new file mode 100644
index 0000000000000..2b0c44576099d
--- /dev/null
+++ b/llvm/lib/Target/VE/MCTargetDesc/VEMCExpr.h
@@ -0,0 +1,95 @@
+//====- VEMCExpr.h - VE specific MC expression classes --------*- 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 describes VE-specific MCExprs, used for modifiers like
+// "%hi" or "%lo" etc.,
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_VE_MCTARGETDESC_VEMCEXPR_H
+#define LLVM_LIB_TARGET_VE_MCTARGETDESC_VEMCEXPR_H
+
+#include "VEFixupKinds.h"
+#include "llvm/MC/MCExpr.h"
+
+namespace llvm {
+
+class StringRef;
+class VEMCExpr : public MCTargetExpr {
+public:
+ enum VariantKind {
+ VK_VE_None,
+ VK_VE_REFLONG,
+ VK_VE_HI32,
+ VK_VE_LO32,
+ VK_VE_PC_HI32,
+ VK_VE_PC_LO32,
+ VK_VE_GOT_HI32,
+ VK_VE_GOT_LO32,
+ VK_VE_GOTOFF_HI32,
+ VK_VE_GOTOFF_LO32,
+ VK_VE_PLT_HI32,
+ VK_VE_PLT_LO32,
+ VK_VE_TLS_GD_HI32,
+ VK_VE_TLS_GD_LO32,
+ VK_VE_TPOFF_HI32,
+ VK_VE_TPOFF_LO32,
+ };
+
+private:
+ const VariantKind Kind;
+ const MCExpr *Expr;
+
+ explicit VEMCExpr(VariantKind Kind, const MCExpr *Expr)
+ : Kind(Kind), Expr(Expr) {}
+
+public:
+ /// @name Construction
+ /// @{
+
+ static const VEMCExpr *create(VariantKind Kind, const MCExpr *Expr,
+ MCContext &Ctx);
+ /// @}
+ /// @name Accessors
+ /// @{
+
+ /// getOpcode - Get the kind of this expression.
+ VariantKind getKind() const { return Kind; }
+
+ /// getSubExpr - Get the child of this expression.
+ const MCExpr *getSubExpr() const { return Expr; }
+
+ /// getFixupKind - Get the fixup kind of this expression.
+ VE::Fixups getFixupKind() const { return getFixupKind(Kind); }
+
+ /// @}
+ void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override;
+ bool evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout,
+ const MCFixup *Fixup) const override;
+ void visitUsedExpr(MCStreamer &Streamer) const override;
+ MCFragment *findAssociatedFragment() const override {
+ return getSubExpr()->findAssociatedFragment();
+ }
+
+ void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const override;
+
+ static bool classof(const MCExpr *E) {
+ return E->getKind() == MCExpr::Target;
+ }
+
+ static bool classof(const VEMCExpr *) { return true; }
+
+ static VariantKind parseVariantKind(StringRef name);
+ static bool printVariantKind(raw_ostream &OS, VariantKind Kind);
+ static void printVariantKindSuffix(raw_ostream &OS, VariantKind Kind);
+ static VE::Fixups getFixupKind(VariantKind Kind);
+};
+
+} // namespace llvm
+
+#endif
diff --git a/llvm/lib/Target/VE/MCTargetDesc/VEMCTargetDesc.cpp b/llvm/lib/Target/VE/MCTargetDesc/VEMCTargetDesc.cpp
index b228617058a6a..a39cffc8f4a65 100644
--- a/llvm/lib/Target/VE/MCTargetDesc/VEMCTargetDesc.cpp
+++ b/llvm/lib/Target/VE/MCTargetDesc/VEMCTargetDesc.cpp
@@ -11,7 +11,8 @@
//===----------------------------------------------------------------------===//
#include "VEMCTargetDesc.h"
-#include "InstPrinter/VEInstPrinter.h"
+#include "TargetInfo/VETargetInfo.h"
+#include "VEInstPrinter.h"
#include "VEMCAsmInfo.h"
#include "VETargetStreamer.h"
#include "llvm/MC/MCInstrInfo.h"
@@ -35,7 +36,7 @@ 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);
+ MCCFIInstruction Inst = MCCFIInstruction::cfiDefCfa(nullptr, Reg, 0);
MAI->addInitialFrameState(Inst);
return MAI;
}
@@ -93,6 +94,12 @@ extern "C" void LLVMInitializeVETargetMC() {
// Register the MC subtarget info.
TargetRegistry::RegisterMCSubtargetInfo(*T, createVEMCSubtargetInfo);
+ // Register the MC Code Emitter.
+ TargetRegistry::RegisterMCCodeEmitter(*T, createVEMCCodeEmitter);
+
+ // Register the asm backend.
+ TargetRegistry::RegisterMCAsmBackend(*T, createVEAsmBackend);
+
// Register the object target streamer.
TargetRegistry::RegisterObjectTargetStreamer(*T,
createObjectTargetStreamer);
diff --git a/llvm/lib/Target/VE/MCTargetDesc/VEMCTargetDesc.h b/llvm/lib/Target/VE/MCTargetDesc/VEMCTargetDesc.h
index 24a5c8209be27..7fb8a556aa749 100644
--- a/llvm/lib/Target/VE/MCTargetDesc/VEMCTargetDesc.h
+++ b/llvm/lib/Target/VE/MCTargetDesc/VEMCTargetDesc.h
@@ -22,7 +22,7 @@ class MCAsmBackend;
class MCCodeEmitter;
class MCContext;
class MCInstrInfo;
-class MCObjectWriter;
+class MCObjectTargetWriter;
class MCRegisterInfo;
class MCSubtargetInfo;
class MCTargetOptions;
@@ -32,8 +32,12 @@ class StringRef;
class raw_pwrite_stream;
class raw_ostream;
-Target &getTheVETarget();
-
+MCCodeEmitter *createVEMCCodeEmitter(const MCInstrInfo &MCII,
+ const MCRegisterInfo &MRI, MCContext &Ctx);
+MCAsmBackend *createVEAsmBackend(const Target &T, const MCSubtargetInfo &STI,
+ const MCRegisterInfo &MRI,
+ const MCTargetOptions &Options);
+std::unique_ptr<MCObjectTargetWriter> createVEELFObjectWriter(uint8_t OSABI);
} // namespace llvm
// Defines symbolic names for VE registers. This defines a mapping from
diff --git a/llvm/lib/Target/VE/MCTargetDesc/VETargetStreamer.cpp b/llvm/lib/Target/VE/MCTargetDesc/VETargetStreamer.cpp
index dfe94bbaaa4bf..29f5afb67ac14 100644
--- a/llvm/lib/Target/VE/MCTargetDesc/VETargetStreamer.cpp
+++ b/llvm/lib/Target/VE/MCTargetDesc/VETargetStreamer.cpp
@@ -11,7 +11,7 @@
//===----------------------------------------------------------------------===//
#include "VETargetStreamer.h"
-#include "InstPrinter/VEInstPrinter.h"
+#include "VEInstPrinter.h"
#include "llvm/Support/FormattedStream.h"
using namespace llvm;