-
Notifications
You must be signed in to change notification settings - Fork 12.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Nios2] final infrastructure to provide compilation of a return from …
…a function This patch includes all missing functionality needed to provide first compilation of a simple program that just returns from a function. I've added a test case that checks for "ret" instruction printed in assembly output. Patch by Andrei Grischenko (andrei.l.grischenko@intel.com) Differential revision: https://reviews.llvm.org/D39688 llvm-svn: 320035
- Loading branch information
Nikolai Bozhenov
committed
Dec 7, 2017
1 parent
44cfc51
commit 1cf9c54
Showing
47 changed files
with
1,876 additions
and
109 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| add_llvm_library(LLVMNios2AsmPrinter Nios2InstPrinter.cpp) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| ;===- ./lib/Target/Nios2/InstPrinter/LLVMBuild.txt -------------*- Conf -*--===; | ||
| ; | ||
| ; The LLVM Compiler Infrastructure | ||
| ; | ||
| ; This file is distributed under the University of Illinois Open Source | ||
| ; License. See LICENSE.TXT for details. | ||
| ; | ||
| ;===------------------------------------------------------------------------===; | ||
| ; | ||
| ; 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 = Nios2AsmPrinter | ||
| parent = Nios2 | ||
| required_libraries = MC Support | ||
| add_to_library_groups = Nios2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| //===-- Nios2InstPrinter.cpp - Convert Nios2 MCInst to assembly syntax-----===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This class prints an Nios2 MCInst to a .s file. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "Nios2InstPrinter.h" | ||
|
|
||
| #include "Nios2InstrInfo.h" | ||
| #include "llvm/MC/MCExpr.h" | ||
| #include "llvm/MC/MCInst.h" | ||
| #include "llvm/MC/MCInstrInfo.h" | ||
| #include "llvm/Support/raw_ostream.h" | ||
| using namespace llvm; | ||
|
|
||
| #define DEBUG_TYPE "asm-printer" | ||
|
|
||
| #define PRINT_ALIAS_INSTR | ||
| #include "Nios2GenAsmWriter.inc" | ||
|
|
||
| void Nios2InstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const { | ||
| OS << getRegisterName(RegNo); | ||
| } | ||
|
|
||
| void Nios2InstPrinter::printInst(const MCInst *MI, raw_ostream &O, | ||
| StringRef Annot, const MCSubtargetInfo &STI) { | ||
| // Try to print any aliases first. | ||
| if (!printAliasInstr(MI, STI, O)) | ||
| printInstruction(MI, STI, O); | ||
| printAnnotation(O, Annot); | ||
| } | ||
|
|
||
| void Nios2InstPrinter::printOperand(const MCInst *MI, int OpNo, | ||
| const MCSubtargetInfo &STI, | ||
| raw_ostream &O) { | ||
| const MCOperand &Op = MI->getOperand(OpNo); | ||
| if (Op.isReg()) { | ||
| printRegName(O, Op.getReg()); | ||
| return; | ||
| } | ||
|
|
||
| if (Op.isImm()) { | ||
| O << Op.getImm(); | ||
| return; | ||
| } | ||
|
|
||
| assert(Op.isExpr() && "unknown operand kind in printOperand"); | ||
| Op.getExpr()->print(O, &MAI, true); | ||
| } | ||
|
|
||
| void Nios2InstPrinter::printMemOperand(const MCInst *MI, int opNum, | ||
| const MCSubtargetInfo &STI, | ||
| raw_ostream &O, const char *Modifier) { | ||
| // Load/Store memory operands -- imm($reg) | ||
| printOperand(MI, opNum + 1, STI, O); | ||
| O << "("; | ||
| printOperand(MI, opNum, STI, O); | ||
| O << ")"; | ||
| } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| //= Nios2InstPrinter.h - Convert Nios2 MCInst to assembly syntax -*- C++ -*-==// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This class prints a Nios2 MCInst to a .s file. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_LIB_TARGET_NIOS2_INSTPRINTER_NIOS2INSTPRINTER_H | ||
| #define LLVM_LIB_TARGET_NIOS2_INSTPRINTER_NIOS2INSTPRINTER_H | ||
|
|
||
| #include "llvm/MC/MCInstPrinter.h" | ||
|
|
||
| namespace llvm { | ||
|
|
||
| class Nios2InstPrinter : public MCInstPrinter { | ||
| public: | ||
| Nios2InstPrinter(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, raw_ostream &O, StringRef Annot, | ||
| const MCSubtargetInfo &STI) override; | ||
|
|
||
| // Autogenerated by tblgen. | ||
| void printInstruction(const MCInst *MI, const MCSubtargetInfo &STI, | ||
| raw_ostream &O); | ||
| static const char *getRegisterName(unsigned RegNo); | ||
|
|
||
| bool printAliasInstr(const MCInst *MI, const MCSubtargetInfo &STI, | ||
| raw_ostream &O); | ||
|
|
||
| void printCustomAliasOperand(const MCInst *MI, unsigned OpIdx, | ||
| unsigned PrintMethodIdx, | ||
| const MCSubtargetInfo &STI, raw_ostream &O); | ||
| void printOperand(const MCInst *MI, int opNum, const MCSubtargetInfo &STI, | ||
| raw_ostream &OS); | ||
| void printMemOperand(const MCInst *MI, int opNum, const MCSubtargetInfo &STI, | ||
| raw_ostream &OS, const char *Modifier = nullptr); | ||
| }; | ||
| } // end namespace llvm | ||
|
|
||
| #endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,9 @@ | ||
| #MCTargetDesc / CMakeLists.txt | ||
| add_llvm_library(LLVMNios2Desc Nios2MCTargetDesc.cpp) | ||
| add_llvm_library(LLVMNios2Desc | ||
| Nios2AsmBackend.cpp | ||
| Nios2ELFObjectWriter.cpp | ||
| Nios2MCAsmInfo.cpp | ||
| Nios2MCExpr.cpp | ||
| Nios2MCTargetDesc.cpp | ||
| Nios2TargetStreamer.cpp) | ||
|
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,131 @@ | ||
| //===-- Nios2AsmBackend.cpp - Nios2 Asm Backend --------------------------===// | ||
| // | ||
| // The LLVM Compiler Infrastructure | ||
| // | ||
| // This file is distributed under the University of Illinois Open Source | ||
| // License. See LICENSE.TXT for details. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file implements the Nios2AsmBackend class. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
|
|
||
| #include "MCTargetDesc/Nios2AsmBackend.h" | ||
| #include "MCTargetDesc/Nios2FixupKinds.h" | ||
| #include "MCTargetDesc/Nios2MCTargetDesc.h" | ||
| #include "llvm/MC/MCAssembler.h" | ||
| #include "llvm/MC/MCELFObjectWriter.h" | ||
| #include "llvm/MC/MCFixupKindInfo.h" | ||
| #include "llvm/MC/MCObjectWriter.h" | ||
|
|
||
| using namespace llvm; | ||
|
|
||
| // Prepare value for the target space for it | ||
| static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value) { | ||
|
|
||
| unsigned Kind = Fixup.getKind(); | ||
|
|
||
| // Add/subtract and shift | ||
| switch (Kind) { | ||
| default: | ||
| return 0; | ||
| case Nios2::fixup_Nios2_LO16: | ||
| break; | ||
| case Nios2::fixup_Nios2_HI16: | ||
| // Get the higher 16-bits. Also add 1 if bit 15 is 1. | ||
| Value = ((Value + 0x8000) >> 16) & 0xffff; | ||
| break; | ||
| } | ||
|
|
||
| return Value; | ||
| } | ||
|
|
||
| // Calculate index for Nios2 specific little endian byte order | ||
| static unsigned calculateLEIndex(unsigned i) { | ||
| assert(i <= 3 && "Index out of range!"); | ||
|
|
||
| return (1 - i / 2) * 2 + i % 2; | ||
| } | ||
|
|
||
| /// ApplyFixup - Apply the \p Value for given \p Fixup into the provided | ||
| /// data fragment, at the offset specified by the fixup and following the | ||
| /// fixup kind as appropriate. | ||
| void Nios2AsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, | ||
| const MCValue &Target, | ||
| MutableArrayRef<char> Data, uint64_t Value, | ||
| bool IsResolved) const { | ||
| MCFixupKind Kind = Fixup.getKind(); | ||
| Value = adjustFixupValue(Fixup, Value); | ||
|
|
||
| if (!Value) | ||
| return; // Doesn't change encoding. | ||
|
|
||
| // Where do we start in the object | ||
| unsigned Offset = Fixup.getOffset(); | ||
| // Number of bytes we need to fixup | ||
| unsigned NumBytes = (getFixupKindInfo(Kind).TargetSize + 7) / 8; | ||
| // Grab current value, if any, from bits. | ||
| uint64_t CurVal = 0; | ||
|
|
||
| for (unsigned i = 0; i != NumBytes; ++i) { | ||
| unsigned Idx = calculateLEIndex(i); | ||
| CurVal |= (uint64_t)((uint8_t)Data[Offset + Idx]) << (i * 8); | ||
| } | ||
|
|
||
| uint64_t Mask = ((uint64_t)(-1) >> (64 - getFixupKindInfo(Kind).TargetSize)); | ||
| CurVal |= Value & Mask; | ||
|
|
||
| // Write out the fixed up bytes back to the code/data bits. | ||
| for (unsigned i = 0; i != NumBytes; ++i) { | ||
| unsigned Idx = calculateLEIndex(i); | ||
| Data[Offset + Idx] = (uint8_t)((CurVal >> (i * 8)) & 0xff); | ||
| } | ||
| } | ||
|
|
||
| Optional<MCFixupKind> Nios2AsmBackend::getFixupKind(StringRef Name) const { | ||
| return StringSwitch<Optional<MCFixupKind>>(Name) | ||
| .Case("R_NIOS2_NONE", (MCFixupKind)Nios2::fixup_Nios2_32) | ||
| .Case("R_NIOS2_32", FK_Data_4) | ||
| .Default(MCAsmBackend::getFixupKind(Name)); | ||
| } | ||
|
|
||
| //@getFixupKindInfo { | ||
| const MCFixupKindInfo & | ||
| Nios2AsmBackend::getFixupKindInfo(MCFixupKind Kind) const { | ||
| const static MCFixupKindInfo Infos[Nios2::NumTargetFixupKinds] = { | ||
| // This table *must* be in same the order of fixup_* kinds in | ||
| // Nios2FixupKinds.h. | ||
| // | ||
| // name offset bits flags | ||
| {"fixup_Nios2_32", 0, 32, 0}, | ||
| {"fixup_Nios2_HI16", 0, 16, 0}, | ||
| {"fixup_Nios2_LO16", 0, 16, 0}}; | ||
|
|
||
| if (Kind < FirstTargetFixupKind) | ||
| return MCAsmBackend::getFixupKindInfo(Kind); | ||
|
|
||
| assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && | ||
| "Invalid kind!"); | ||
| return Infos[Kind - FirstTargetFixupKind]; | ||
| } | ||
|
|
||
| std::unique_ptr<MCObjectWriter> | ||
| Nios2AsmBackend::createObjectWriter(raw_pwrite_stream &OS) const { | ||
| return createNios2ELFObjectWriter(OS, | ||
| MCELFObjectTargetWriter::getOSABI(OSType)); | ||
| } | ||
|
|
||
| bool Nios2AsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const { | ||
| return true; | ||
| } | ||
|
|
||
| // MCAsmBackend | ||
| MCAsmBackend *llvm::createNios2AsmBackend(const Target &T, | ||
| const MCRegisterInfo &MRI, | ||
| const Triple &TT, StringRef CPU, | ||
| const MCTargetOptions &Options) { | ||
|
|
||
| return new Nios2AsmBackend(T, TT.getOS()); | ||
| } |
Oops, something went wrong.