//
//===----------------------------------------------------------------------===//
+#include "HexagonMCTargetDesc.h"
+#include "Hexagon.h"
#include "HexagonMCAsmInfo.h"
#include "HexagonMCELFStreamer.h"
-#include "HexagonMCTargetDesc.h"
#include "MCTargetDesc/HexagonInstPrinter.h"
#include "llvm/MC/MCCodeGenInfo.h"
#include "llvm/MC/MCContext.h"
#define GET_REGINFO_MC_DESC
#include "HexagonGenRegisterInfo.inc"
+cl::opt<bool> llvm::HexagonDisableCompound
+ ("mno-compound",
+ cl::desc("Disable looking for compound instructions for Hexagon"));
+
+cl::opt<bool> llvm::HexagonDisableDuplex
+ ("mno-pairing",
+ cl::desc("Disable looking for duplex instructions for Hexagon"));
+
+StringRef HEXAGON_MC::selectHexagonCPU(const Triple &TT, StringRef CPU) {
+ if (CPU.empty())
+ CPU = "hexagonv60";
+ return CPU;
+}
+
MCInstrInfo *llvm::createHexagonMCInstrInfo() {
MCInstrInfo *X = new MCInstrInfo();
InitHexagonMCInstrInfo(X);
return X;
}
-static MCRegisterInfo *createHexagonMCRegisterInfo(StringRef TT) {
+static MCRegisterInfo *createHexagonMCRegisterInfo(const Triple &TT) {
MCRegisterInfo *X = new MCRegisterInfo();
InitHexagonMCRegisterInfo(X, Hexagon::R0);
return X;
static MCSubtargetInfo *
createHexagonMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
- MCSubtargetInfo *X = new MCSubtargetInfo();
- InitHexagonMCSubtargetInfo(X, TT, CPU, FS);
- return X;
+ CPU = HEXAGON_MC::selectHexagonCPU(TT, CPU);
+ return createHexagonMCSubtargetInfoImpl(TT, CPU, FS);
+}
+
+namespace {
+class HexagonTargetAsmStreamer : public HexagonTargetStreamer {
+public:
+ HexagonTargetAsmStreamer(MCStreamer &S,
+ formatted_raw_ostream &, bool,
+ MCInstPrinter &)
+ : HexagonTargetStreamer(S) {}
+ void prettyPrintAsm(MCInstPrinter &InstPrinter, raw_ostream &OS,
+ const MCInst &Inst, const MCSubtargetInfo &STI) override {
+ assert(HexagonMCInstrInfo::isBundle(Inst));
+ assert(HexagonMCInstrInfo::bundleSize(Inst) <= HEXAGON_PACKET_SIZE);
+ std::string Buffer;
+ {
+ raw_string_ostream TempStream(Buffer);
+ InstPrinter.printInst(&Inst, TempStream, "", STI);
+ }
+ StringRef Contents(Buffer);
+ auto PacketBundle = Contents.rsplit('\n');
+ auto HeadTail = PacketBundle.first.split('\n');
+ StringRef Separator = "\n";
+ StringRef Indent = "\t\t";
+ OS << "\t{\n";
+ while (!HeadTail.first.empty()) {
+ StringRef InstTxt;
+ auto Duplex = HeadTail.first.split('\v');
+ if (!Duplex.second.empty()) {
+ OS << Indent << Duplex.first << Separator;
+ InstTxt = Duplex.second;
+ } else if (!HeadTail.first.trim().startswith("immext")) {
+ InstTxt = Duplex.first;
+ }
+ if (!InstTxt.empty())
+ OS << Indent << InstTxt << Separator;
+ HeadTail = HeadTail.second.split('\n');
+ }
+ OS << "\t}" << PacketBundle.second;
+ }
+};
}
namespace {
return MAI;
}
-static MCCodeGenInfo *createHexagonMCCodeGenInfo(StringRef TT, Reloc::Model RM,
+static MCCodeGenInfo *createHexagonMCCodeGenInfo(const Triple &TT,
+ Reloc::Model RM,
CodeModel::Model CM,
CodeGenOpt::Level OL) {
MCCodeGenInfo *X = new MCCodeGenInfo();
- // For the time being, use static relocations, since there's really no
- // support for PIC yet.
- X->initMCCodeGenInfo(Reloc::Static, CM, OL);
+ if (RM == Reloc::Default)
+ RM = Reloc::Static;
+ X->initMCCodeGenInfo(RM, CM, OL);
return X;
}
return nullptr;
}
+static MCTargetStreamer *createMCAsmTargetStreamer(MCStreamer &S,
+ formatted_raw_ostream &OS,
+ MCInstPrinter *InstPrint,
+ bool IsVerboseAsm) {
+ return new HexagonTargetAsmStreamer(S, OS, IsVerboseAsm, *InstPrint);
+}
+
static MCStreamer *createMCStreamer(Triple const &T, MCContext &Context,
MCAsmBackend &MAB, raw_pwrite_stream &OS,
MCCodeEmitter *Emitter, bool RelaxAll) {
// Register the obj streamer
TargetRegistry::RegisterELFStreamer(TheHexagonTarget, createMCStreamer);
+ // Register the asm streamer
+ TargetRegistry::RegisterAsmTargetStreamer(TheHexagonTarget,
+ createMCAsmTargetStreamer);
+
// Register the MC Inst Printer
TargetRegistry::RegisterMCInstPrinter(TheHexagonTarget,
createHexagonMCInstPrinter);