From: Colin LeMahieu Date: Fri, 24 Oct 2014 19:00:32 +0000 (+0000) Subject: [Hexagon] Resubmission of 220427 X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=8699f5390bc96ade71419b2d1c15589c88207883 [Hexagon] Resubmission of 220427 Modified library structure to deal with circular dependency between HexagonInstPrinter and HexagonMCInst. Adding encoding bits for add opcode. Adding llvm-mc tests. Removing unit tests. http://reviews.llvm.org/D5624 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@220584 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/Hexagon/CMakeLists.txt b/lib/Target/Hexagon/CMakeLists.txt index 72142440414..b437bc2dddb 100644 --- a/lib/Target/Hexagon/CMakeLists.txt +++ b/lib/Target/Hexagon/CMakeLists.txt @@ -40,6 +40,5 @@ add_llvm_target(HexagonCodeGen ) add_subdirectory(TargetInfo) -add_subdirectory(InstPrinter) add_subdirectory(MCTargetDesc) add_subdirectory(Disassembler) diff --git a/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp b/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp index 24dbf2a16b9..b709c835acf 100644 --- a/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp +++ b/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp @@ -48,6 +48,40 @@ public: }; } +static const uint16_t IntRegDecoderTable[] = { + Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3, Hexagon::R4, + Hexagon::R5, Hexagon::R6, Hexagon::R7, Hexagon::R8, Hexagon::R9, + Hexagon::R10, Hexagon::R11, Hexagon::R12, Hexagon::R13, Hexagon::R14, + Hexagon::R15, Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19, + Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23, Hexagon::R24, + Hexagon::R25, Hexagon::R26, Hexagon::R27, Hexagon::R28, Hexagon::R29, + Hexagon::R30, Hexagon::R31}; + +static const uint16_t PredRegDecoderTable[] = {Hexagon::P0, Hexagon::P1, + Hexagon::P2, Hexagon::P3}; + +static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t /*Address*/, + void const *Decoder) { + if (RegNo > 31) + return MCDisassembler::Fail; + + unsigned Register = IntRegDecoderTable[RegNo]; + Inst.addOperand(MCOperand::CreateReg(Register)); + return MCDisassembler::Success; +} + +static DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t /*Address*/, + void const *Decoder) { + if (RegNo > 3) + return MCDisassembler::Fail; + + unsigned Register = PredRegDecoderTable[RegNo]; + Inst.addOperand(MCOperand::CreateReg(Register)); + return MCDisassembler::Success; +} + #include "HexagonGenDisassemblerTables.inc" static MCDisassembler *createHexagonDisassembler(Target const &T, diff --git a/lib/Target/Hexagon/HexagonAsmPrinter.cpp b/lib/Target/Hexagon/HexagonAsmPrinter.cpp index 2e011bd1274..c705591075a 100644 --- a/lib/Target/Hexagon/HexagonAsmPrinter.cpp +++ b/lib/Target/Hexagon/HexagonAsmPrinter.cpp @@ -18,7 +18,7 @@ #include "HexagonMachineFunctionInfo.h" #include "HexagonSubtarget.h" #include "HexagonTargetMachine.h" -#include "InstPrinter/HexagonInstPrinter.h" +#include "MCTargetDesc/HexagonInstPrinter.h" #include "MCTargetDesc/HexagonMCInst.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" @@ -195,8 +195,8 @@ void HexagonAsmPrinter::EmitInstruction(const MachineInstr *MI) { unsigned Size = BundleMIs.size(); assert((Size+IgnoreCount) == MI->getBundleSize() && "Corrupt Bundle!"); for (unsigned Index = 0; Index < Size; Index++) { - HexagonMCInst MCI; - MCI.setPacketStart(Index == 0); + HexagonMCInst MCI (BundleMIs[Index]->getOpcode()); + MCI.setPacketBegin(Index == 0); MCI.setPacketEnd(Index == (Size-1)); HexagonLowerToMC(BundleMIs[Index], MCI, *this); @@ -204,9 +204,9 @@ void HexagonAsmPrinter::EmitInstruction(const MachineInstr *MI) { } } else { - HexagonMCInst MCI; + HexagonMCInst MCI(MI->getOpcode()); if (MI->getOpcode() == Hexagon::ENDLOOP0) { - MCI.setPacketStart(true); + MCI.setPacketBegin(true); MCI.setPacketEnd(true); } HexagonLowerToMC(MI, MCI, *this); diff --git a/lib/Target/Hexagon/HexagonInstrInfo.td b/lib/Target/Hexagon/HexagonInstrInfo.td index 42ecab9538a..c8240ded55e 100644 --- a/lib/Target/Hexagon/HexagonInstrInfo.td +++ b/lib/Target/Hexagon/HexagonInstrInfo.td @@ -92,6 +92,77 @@ def HexagonWrapperCombineII : def HexagonWrapperCombineRR : SDNode<"HexagonISD::WrapperCombineRR", SDTHexagonI64I32I32>; +let hasSideEffects = 0, hasNewValue = 1, InputType = "reg" in +class T_ALU32_3op MajOp, bits<3> MinOp, bit OpsRev, + bit IsComm> + : ALU32_rr<(outs IntRegs:$Rd), (ins IntRegs:$Rs, IntRegs:$Rt), + "$Rd = "#mnemonic#"($Rs, $Rt)", + [], "", ALU32_3op_tc_1_SLOT0123>, ImmRegRel, PredRel { + let isCommutable = IsComm; + let BaseOpcode = mnemonic#_rr; + let CextOpcode = mnemonic; + + bits<5> Rs; + bits<5> Rt; + bits<5> Rd; + + let IClass = 0b1111; + let Inst{27} = 0b0; + let Inst{26-24} = MajOp; + let Inst{23-21} = MinOp; + let Inst{20-16} = !if(OpsRev,Rt,Rs); + let Inst{12-8} = !if(OpsRev,Rs,Rt); + let Inst{4-0} = Rd; +} + +let hasSideEffects = 0, hasNewValue = 1 in +class T_ALU32_3op_pred MajOp, bits<3> MinOp, + bit OpsRev, bit PredNot, bit PredNew> + : ALU32_rr<(outs IntRegs:$Rd), (ins PredRegs:$Pu, IntRegs:$Rs, IntRegs:$Rt), + "if ("#!if(PredNot,"!","")#"$Pu"#!if(PredNew,".new","")#") "# + "$Rd = "#mnemonic#"($Rs, $Rt)", + [], "", ALU32_3op_tc_1_SLOT0123>, ImmRegRel, PredNewRel { + let isPredicated = 1; + let isPredicatedFalse = PredNot; + let isPredicatedNew = PredNew; + let BaseOpcode = mnemonic#_rr; + let CextOpcode = mnemonic; + + bits<2> Pu; + bits<5> Rs; + bits<5> Rt; + bits<5> Rd; + + let IClass = 0b1111; + let Inst{27} = 0b1; + let Inst{26-24} = MajOp; + let Inst{23-21} = MinOp; + let Inst{20-16} = !if(OpsRev,Rt,Rs); + let Inst{13} = PredNew; + let Inst{12-8} = !if(OpsRev,Rs,Rt); + let Inst{7} = PredNot; + let Inst{6-5} = Pu; + let Inst{4-0} = Rd; +} + +multiclass T_ALU32_3op_p MajOp, bits<3> MinOp, + bit OpsRev> { + def t : T_ALU32_3op_pred; + def f : T_ALU32_3op_pred; + def tnew : T_ALU32_3op_pred; + def fnew : T_ALU32_3op_pred; +} + +multiclass T_ALU32_3op_A2 MajOp, bits<3> MinOp, + bit OpsRev, bit IsComm> { + let isPredicable = 1 in + def A2_#NAME : T_ALU32_3op ; + defm A2_p#NAME : T_ALU32_3op_p; +} + +let isCodeGenOnly = 0 in +defm add : T_ALU32_3op_A2<"add", 0b011, 0b000, 0, 1>; + multiclass ALU32_Pbase { let isPredicatedNew = isPredNew in diff --git a/lib/Target/Hexagon/HexagonMCInstLower.cpp b/lib/Target/Hexagon/HexagonMCInstLower.cpp index 5e4346d4021..87149adc870 100644 --- a/lib/Target/Hexagon/HexagonMCInstLower.cpp +++ b/lib/Target/Hexagon/HexagonMCInstLower.cpp @@ -24,8 +24,8 @@ using namespace llvm; -static MCOperand GetSymbolRef(const MachineOperand& MO, const MCSymbol* Symbol, - HexagonAsmPrinter& Printer) { +static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol, + HexagonAsmPrinter &Printer) { MCContext &MC = Printer.OutContext; const MCExpr *ME; @@ -39,10 +39,10 @@ static MCOperand GetSymbolRef(const MachineOperand& MO, const MCSymbol* Symbol, } // Create an MCInst from a MachineInstr -void llvm::HexagonLowerToMC(const MachineInstr* MI, HexagonMCInst& MCI, - HexagonAsmPrinter& AP) { - MCI.setOpcode(MI->getOpcode()); - MCI.setDesc(MI->getDesc()); +void llvm::HexagonLowerToMC(const MachineInstr *MI, HexagonMCInst &MCI, + HexagonAsmPrinter &AP) { + assert(MCI.getOpcode() == static_cast(MI->getOpcode()) && + "MCI opcode should have been set on construction"); for (unsigned i = 0, e = MI->getNumOperands(); i < e; i++) { const MachineOperand &MO = MI->getOperand(i); @@ -54,7 +54,8 @@ void llvm::HexagonLowerToMC(const MachineInstr* MI, HexagonMCInst& MCI, llvm_unreachable("unknown operand type"); case MachineOperand::MO_Register: // Ignore all implicit register operands. - if (MO.isImplicit()) continue; + if (MO.isImplicit()) + continue; MCO = MCOperand::CreateReg(MO.getReg()); break; case MachineOperand::MO_FPImmediate: { @@ -68,16 +69,15 @@ void llvm::HexagonLowerToMC(const MachineInstr* MI, HexagonMCInst& MCI, MCO = MCOperand::CreateImm(MO.getImm()); break; case MachineOperand::MO_MachineBasicBlock: - MCO = MCOperand::CreateExpr - (MCSymbolRefExpr::Create(MO.getMBB()->getSymbol(), - AP.OutContext)); + MCO = MCOperand::CreateExpr( + MCSymbolRefExpr::Create(MO.getMBB()->getSymbol(), AP.OutContext)); break; case MachineOperand::MO_GlobalAddress: MCO = GetSymbolRef(MO, AP.getSymbol(MO.getGlobal()), AP); break; case MachineOperand::MO_ExternalSymbol: - MCO = GetSymbolRef(MO, AP.GetExternalSymbolSymbol(MO.getSymbolName()), - AP); + MCO = + GetSymbolRef(MO, AP.GetExternalSymbolSymbol(MO.getSymbolName()), AP); break; case MachineOperand::MO_JumpTableIndex: MCO = GetSymbolRef(MO, AP.GetJTISymbol(MO.getIndex()), AP); @@ -86,7 +86,8 @@ void llvm::HexagonLowerToMC(const MachineInstr* MI, HexagonMCInst& MCI, MCO = GetSymbolRef(MO, AP.GetCPISymbol(MO.getIndex()), AP); break; case MachineOperand::MO_BlockAddress: - MCO = GetSymbolRef(MO, AP.GetBlockAddressSymbol(MO.getBlockAddress()),AP); + MCO = + GetSymbolRef(MO, AP.GetBlockAddressSymbol(MO.getBlockAddress()), AP); break; } diff --git a/lib/Target/Hexagon/InstPrinter/CMakeLists.txt b/lib/Target/Hexagon/InstPrinter/CMakeLists.txt deleted file mode 100644 index 1ddaf9bac20..00000000000 --- a/lib/Target/Hexagon/InstPrinter/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -add_llvm_library(LLVMHexagonAsmPrinter - HexagonInstPrinter.cpp - ) diff --git a/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.cpp b/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.cpp deleted file mode 100644 index 1fd8d7052cf..00000000000 --- a/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.cpp +++ /dev/null @@ -1,254 +0,0 @@ -//===- HexagonInstPrinter.cpp - Convert Hexagon 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 Hexagon MCInst to a .s file. -// -//===----------------------------------------------------------------------===// - -#include "HexagonAsmPrinter.h" -#include "Hexagon.h" -#include "HexagonInstPrinter.h" -#include "MCTargetDesc/HexagonMCInst.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/MC/MCAsmInfo.h" -#include "llvm/MC/MCExpr.h" -#include "llvm/MC/MCInst.h" -#include "llvm/Support/raw_ostream.h" - -using namespace llvm; - -#define DEBUG_TYPE "asm-printer" - -#define GET_INSTRUCTION_NAME -#include "HexagonGenAsmWriter.inc" - -const char HexagonInstPrinter::PacketPadding = '\t'; -// Return the minimum value that a constant extendable operand can have -// without being extended. -static int getMinValue(uint64_t TSFlags) { - unsigned isSigned = - (TSFlags >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask; - unsigned bits = - (TSFlags >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask; - - if (isSigned) - return -1U << (bits - 1); - - return 0; -} - -// Return the maximum value that a constant extendable operand can have -// without being extended. -static int getMaxValue(uint64_t TSFlags) { - unsigned isSigned = - (TSFlags >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask; - unsigned bits = - (TSFlags >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask; - - if (isSigned) - return ~(-1U << (bits - 1)); - - return ~(-1U << bits); -} - -// Return true if the instruction must be extended. -static bool isExtended(uint64_t TSFlags) { - return (TSFlags >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask; -} - -// Currently just used in an assert statement -static bool isExtendable(uint64_t TSFlags) LLVM_ATTRIBUTE_UNUSED; -// Return true if the instruction may be extended based on the operand value. -static bool isExtendable(uint64_t TSFlags) { - return (TSFlags >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask; -} - -StringRef HexagonInstPrinter::getOpcodeName(unsigned Opcode) const { - return MII.getName(Opcode); -} - -StringRef HexagonInstPrinter::getRegName(unsigned RegNo) const { - return getRegisterName(RegNo); -} - -void HexagonInstPrinter::printInst(const MCInst *MI, raw_ostream &O, - StringRef Annot) { - printInst((const HexagonMCInst*)(MI), O, Annot); -} - -void HexagonInstPrinter::printInst(const HexagonMCInst *MI, raw_ostream &O, - StringRef Annot) { - const char startPacket = '{', - endPacket = '}'; - // TODO: add outer HW loop when it's supported too. - if (MI->getOpcode() == Hexagon::ENDLOOP0) { - // Ending a harware loop is different from ending an regular packet. - assert(MI->isPacketEnd() && "Loop-end must also end the packet"); - - if (MI->isPacketStart()) { - // There must be a packet to end a loop. - // FIXME: when shuffling is always run, this shouldn't be needed. - HexagonMCInst Nop; - StringRef NoAnnot; - - Nop.setOpcode (Hexagon::NOP); - Nop.setPacketStart (MI->isPacketStart()); - printInst (&Nop, O, NoAnnot); - } - - // Close the packet. - if (MI->isPacketEnd()) - O << PacketPadding << endPacket; - - printInstruction(MI, O); - } - else { - // Prefix the insn opening the packet. - if (MI->isPacketStart()) - O << PacketPadding << startPacket << '\n'; - - printInstruction(MI, O); - - // Suffix the insn closing the packet. - if (MI->isPacketEnd()) - // Suffix the packet in a new line always, since the GNU assembler has - // issues with a closing brace on the same line as CONST{32,64}. - O << '\n' << PacketPadding << endPacket; - } - - printAnnotation(O, Annot); -} - -void HexagonInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, - raw_ostream &O) const { - const MCOperand& MO = MI->getOperand(OpNo); - - if (MO.isReg()) { - O << getRegisterName(MO.getReg()); - } else if(MO.isExpr()) { - O << *MO.getExpr(); - } else if(MO.isImm()) { - printImmOperand(MI, OpNo, O); - } else { - llvm_unreachable("Unknown operand"); - } -} - -void HexagonInstPrinter::printImmOperand(const MCInst *MI, unsigned OpNo, - raw_ostream &O) const { - const MCOperand& MO = MI->getOperand(OpNo); - - if(MO.isExpr()) { - O << *MO.getExpr(); - } else if(MO.isImm()) { - O << MI->getOperand(OpNo).getImm(); - } else { - llvm_unreachable("Unknown operand"); - } -} - -void HexagonInstPrinter::printExtOperand(const MCInst *MI, unsigned OpNo, - raw_ostream &O) const { - const MCOperand &MO = MI->getOperand(OpNo); - const MCInstrDesc &MII = getMII().get(MI->getOpcode()); - - assert((isExtendable(MII.TSFlags) || isExtended(MII.TSFlags)) && - "Expecting an extendable operand"); - - if (MO.isExpr() || isExtended(MII.TSFlags)) { - O << "#"; - } else if (MO.isImm()) { - int ImmValue = MO.getImm(); - if (ImmValue < getMinValue(MII.TSFlags) || - ImmValue > getMaxValue(MII.TSFlags)) - O << "#"; - } - printOperand(MI, OpNo, O); -} - -void HexagonInstPrinter::printUnsignedImmOperand(const MCInst *MI, - unsigned OpNo, raw_ostream &O) const { - O << MI->getOperand(OpNo).getImm(); -} - -void HexagonInstPrinter::printNegImmOperand(const MCInst *MI, unsigned OpNo, - raw_ostream &O) const { - O << -MI->getOperand(OpNo).getImm(); -} - -void HexagonInstPrinter::printNOneImmOperand(const MCInst *MI, unsigned OpNo, - raw_ostream &O) const { - O << -1; -} - -void HexagonInstPrinter::printMEMriOperand(const MCInst *MI, unsigned OpNo, - raw_ostream &O) const { - const MCOperand& MO0 = MI->getOperand(OpNo); - const MCOperand& MO1 = MI->getOperand(OpNo + 1); - - O << getRegisterName(MO0.getReg()); - O << " + #" << MO1.getImm(); -} - -void HexagonInstPrinter::printFrameIndexOperand(const MCInst *MI, unsigned OpNo, - raw_ostream &O) const { - const MCOperand& MO0 = MI->getOperand(OpNo); - const MCOperand& MO1 = MI->getOperand(OpNo + 1); - - O << getRegisterName(MO0.getReg()) << ", #" << MO1.getImm(); -} - -void HexagonInstPrinter::printGlobalOperand(const MCInst *MI, unsigned OpNo, - raw_ostream &O) const { - assert(MI->getOperand(OpNo).isExpr() && "Expecting expression"); - - printOperand(MI, OpNo, O); -} - -void HexagonInstPrinter::printJumpTable(const MCInst *MI, unsigned OpNo, - raw_ostream &O) const { - assert(MI->getOperand(OpNo).isExpr() && "Expecting expression"); - - printOperand(MI, OpNo, O); -} - -void HexagonInstPrinter::printConstantPool(const MCInst *MI, unsigned OpNo, - raw_ostream &O) const { - assert(MI->getOperand(OpNo).isExpr() && "Expecting expression"); - - printOperand(MI, OpNo, O); -} - -void HexagonInstPrinter::printBranchOperand(const MCInst *MI, unsigned OpNo, - raw_ostream &O) const { - // Branches can take an immediate operand. This is used by the branch - // selection pass to print $+8, an eight byte displacement from the PC. - llvm_unreachable("Unknown branch operand."); -} - -void HexagonInstPrinter::printCallOperand(const MCInst *MI, unsigned OpNo, - raw_ostream &O) const { -} - -void HexagonInstPrinter::printAbsAddrOperand(const MCInst *MI, unsigned OpNo, - raw_ostream &O) const { -} - -void HexagonInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo, - raw_ostream &O) const { -} - -void HexagonInstPrinter::printSymbol(const MCInst *MI, unsigned OpNo, - raw_ostream &O, bool hi) const { - assert(MI->getOperand(OpNo).isImm() && "Unknown symbol operand"); - - O << '#' << (hi ? "HI" : "LO") << "(#"; - printOperand(MI, OpNo, O); - O << ')'; -} diff --git a/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.h b/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.h deleted file mode 100644 index 55ae95cd06d..00000000000 --- a/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.h +++ /dev/null @@ -1,87 +0,0 @@ -//===-- HexagonInstPrinter.h - Convert Hexagon 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 Hexagon MCInst to a .s file. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_LIB_TARGET_HEXAGON_INSTPRINTER_HEXAGONINSTPRINTER_H -#define LLVM_LIB_TARGET_HEXAGON_INSTPRINTER_HEXAGONINSTPRINTER_H - -#include "llvm/MC/MCInstPrinter.h" -#include "llvm/MC/MCInstrInfo.h" - -namespace llvm { - class HexagonMCInst; - - class HexagonInstPrinter : public MCInstPrinter { - public: - explicit HexagonInstPrinter(const MCAsmInfo &MAI, - const MCInstrInfo &MII, - const MCRegisterInfo &MRI) - : MCInstPrinter(MAI, MII, MRI), MII(MII) {} - - void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot) override; - void printInst(const HexagonMCInst *MI, raw_ostream &O, StringRef Annot); - virtual StringRef getOpcodeName(unsigned Opcode) const; - void printInstruction(const MCInst *MI, raw_ostream &O); - StringRef getRegName(unsigned RegNo) const; - static const char *getRegisterName(unsigned RegNo); - - void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) const; - void printImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) const; - void printExtOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) const; - void printUnsignedImmOperand(const MCInst *MI, unsigned OpNo, - raw_ostream &O) const; - void printNegImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) - const; - void printNOneImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) - const; - void printMEMriOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) - const; - void printFrameIndexOperand(const MCInst *MI, unsigned OpNo, - raw_ostream &O) const; - void printBranchOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) - const; - void printCallOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) - const; - void printAbsAddrOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) - const; - void printPredicateOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) - const; - void printGlobalOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) - const; - void printJumpTable(const MCInst *MI, unsigned OpNo, raw_ostream &O) const; - - void printConstantPool(const MCInst *MI, unsigned OpNo, - raw_ostream &O) const; - - void printSymbolHi(const MCInst *MI, unsigned OpNo, raw_ostream &O) const - { printSymbol(MI, OpNo, O, true); } - void printSymbolLo(const MCInst *MI, unsigned OpNo, raw_ostream &O) const - { printSymbol(MI, OpNo, O, false); } - - const MCInstrInfo &getMII() const { - return MII; - } - - protected: - void printSymbol(const MCInst *MI, unsigned OpNo, raw_ostream &O, bool hi) - const; - - static const char PacketPadding; - - private: - const MCInstrInfo &MII; - - }; - -} // end namespace llvm - -#endif diff --git a/lib/Target/Hexagon/InstPrinter/LLVMBuild.txt b/lib/Target/Hexagon/InstPrinter/LLVMBuild.txt deleted file mode 100644 index 8678401feee..00000000000 --- a/lib/Target/Hexagon/InstPrinter/LLVMBuild.txt +++ /dev/null @@ -1,23 +0,0 @@ -;===- ./lib/Target/Hexagon/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 = HexagonAsmPrinter -parent = Hexagon -required_libraries = MC Support -add_to_library_groups = Hexagon diff --git a/lib/Target/Hexagon/InstPrinter/Makefile b/lib/Target/Hexagon/InstPrinter/Makefile deleted file mode 100644 index 20331d8807e..00000000000 --- a/lib/Target/Hexagon/InstPrinter/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -##===- lib/Target/Hexagon/InstPrinter/Makefile ----------------------------===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -LEVEL = ../../../.. -LIBRARYNAME = LLVMHexagonAsmPrinter - -# Hack: we need to include 'main' Hexagon target directory to grab private headers -CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/.. - -include $(LEVEL)/Makefile.common diff --git a/lib/Target/Hexagon/LLVMBuild.txt b/lib/Target/Hexagon/LLVMBuild.txt index 1542447d147..6ffd26a2022 100644 --- a/lib/Target/Hexagon/LLVMBuild.txt +++ b/lib/Target/Hexagon/LLVMBuild.txt @@ -16,7 +16,7 @@ ;===------------------------------------------------------------------------===; [common] -subdirectories = Disassembler InstPrinter MCTargetDesc TargetInfo +subdirectories = Disassembler MCTargetDesc TargetInfo [component_0] type = TargetGroup @@ -28,5 +28,5 @@ has_asmprinter = 1 type = Library name = HexagonCodeGen parent = Hexagon -required_libraries = Analysis AsmPrinter CodeGen Core HexagonAsmPrinter HexagonDesc HexagonInfo MC SelectionDAG Support Target +required_libraries = Analysis AsmPrinter CodeGen Core HexagonDesc HexagonInfo MC SelectionDAG Support Target add_to_library_groups = Hexagon diff --git a/lib/Target/Hexagon/MCTargetDesc/CMakeLists.txt b/lib/Target/Hexagon/MCTargetDesc/CMakeLists.txt index 2b7cc851957..cb21eaf31dd 100644 --- a/lib/Target/Hexagon/MCTargetDesc/CMakeLists.txt +++ b/lib/Target/Hexagon/MCTargetDesc/CMakeLists.txt @@ -1,4 +1,5 @@ add_llvm_library(LLVMHexagonDesc + HexagonInstPrinter.cpp HexagonMCAsmInfo.cpp HexagonMCCodeEmitter.cpp HexagonMCInst.cpp diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.cpp new file mode 100644 index 00000000000..0765f185e61 --- /dev/null +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.cpp @@ -0,0 +1,253 @@ +//===- HexagonInstPrinter.cpp - Convert Hexagon 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 Hexagon MCInst to a .s file. +// +//===----------------------------------------------------------------------===// + +#include "HexagonAsmPrinter.h" +#include "Hexagon.h" +#include "HexagonInstPrinter.h" +#include "MCTargetDesc/HexagonMCInst.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCInst.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +#define DEBUG_TYPE "asm-printer" + +#define GET_INSTRUCTION_NAME +#include "HexagonGenAsmWriter.inc" + +const char HexagonInstPrinter::PacketPadding = '\t'; +// Return the minimum value that a constant extendable operand can have +// without being extended. +static int getMinValue(uint64_t TSFlags) { + unsigned isSigned = + (TSFlags >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask; + unsigned bits = + (TSFlags >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask; + + if (isSigned) + return -1U << (bits - 1); + + return 0; +} + +// Return the maximum value that a constant extendable operand can have +// without being extended. +static int getMaxValue(uint64_t TSFlags) { + unsigned isSigned = + (TSFlags >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask; + unsigned bits = + (TSFlags >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask; + + if (isSigned) + return ~(-1U << (bits - 1)); + + return ~(-1U << bits); +} + +// Return true if the instruction must be extended. +static bool isExtended(uint64_t TSFlags) { + return (TSFlags >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask; +} + +// Currently just used in an assert statement +static bool isExtendable(uint64_t TSFlags) LLVM_ATTRIBUTE_UNUSED; +// Return true if the instruction may be extended based on the operand value. +static bool isExtendable(uint64_t TSFlags) { + return (TSFlags >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask; +} + +StringRef HexagonInstPrinter::getOpcodeName(unsigned Opcode) const { + return MII.getName(Opcode); +} + +StringRef HexagonInstPrinter::getRegName(unsigned RegNo) const { + return getRegisterName(RegNo); +} + +void HexagonInstPrinter::printInst(const MCInst *MI, raw_ostream &O, + StringRef Annot) { + printInst((const HexagonMCInst*)(MI), O, Annot); +} + +void HexagonInstPrinter::printInst(const HexagonMCInst *MI, raw_ostream &O, + StringRef Annot) { + const char startPacket = '{', + endPacket = '}'; + // TODO: add outer HW loop when it's supported too. + if (MI->getOpcode() == Hexagon::ENDLOOP0) { + // Ending a harware loop is different from ending an regular packet. + assert(MI->isPacketEnd() && "Loop-end must also end the packet"); + + if (MI->isPacketBegin()) { + // There must be a packet to end a loop. + // FIXME: when shuffling is always run, this shouldn't be needed. + HexagonMCInst Nop (Hexagon::NOP); + StringRef NoAnnot; + + Nop.setPacketBegin (MI->isPacketBegin()); + printInst (&Nop, O, NoAnnot); + } + + // Close the packet. + if (MI->isPacketEnd()) + O << PacketPadding << endPacket; + + printInstruction(MI, O); + } + else { + // Prefix the insn opening the packet. + if (MI->isPacketBegin()) + O << PacketPadding << startPacket << '\n'; + + printInstruction(MI, O); + + // Suffix the insn closing the packet. + if (MI->isPacketEnd()) + // Suffix the packet in a new line always, since the GNU assembler has + // issues with a closing brace on the same line as CONST{32,64}. + O << '\n' << PacketPadding << endPacket; + } + + printAnnotation(O, Annot); +} + +void HexagonInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { + const MCOperand& MO = MI->getOperand(OpNo); + + if (MO.isReg()) { + O << getRegisterName(MO.getReg()); + } else if(MO.isExpr()) { + O << *MO.getExpr(); + } else if(MO.isImm()) { + printImmOperand(MI, OpNo, O); + } else { + llvm_unreachable("Unknown operand"); + } +} + +void HexagonInstPrinter::printImmOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { + const MCOperand& MO = MI->getOperand(OpNo); + + if(MO.isExpr()) { + O << *MO.getExpr(); + } else if(MO.isImm()) { + O << MI->getOperand(OpNo).getImm(); + } else { + llvm_unreachable("Unknown operand"); + } +} + +void HexagonInstPrinter::printExtOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { + const MCOperand &MO = MI->getOperand(OpNo); + const MCInstrDesc &MII = getMII().get(MI->getOpcode()); + + assert((isExtendable(MII.TSFlags) || isExtended(MII.TSFlags)) && + "Expecting an extendable operand"); + + if (MO.isExpr() || isExtended(MII.TSFlags)) { + O << "#"; + } else if (MO.isImm()) { + int ImmValue = MO.getImm(); + if (ImmValue < getMinValue(MII.TSFlags) || + ImmValue > getMaxValue(MII.TSFlags)) + O << "#"; + } + printOperand(MI, OpNo, O); +} + +void HexagonInstPrinter::printUnsignedImmOperand(const MCInst *MI, + unsigned OpNo, raw_ostream &O) const { + O << MI->getOperand(OpNo).getImm(); +} + +void HexagonInstPrinter::printNegImmOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { + O << -MI->getOperand(OpNo).getImm(); +} + +void HexagonInstPrinter::printNOneImmOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { + O << -1; +} + +void HexagonInstPrinter::printMEMriOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { + const MCOperand& MO0 = MI->getOperand(OpNo); + const MCOperand& MO1 = MI->getOperand(OpNo + 1); + + O << getRegisterName(MO0.getReg()); + O << " + #" << MO1.getImm(); +} + +void HexagonInstPrinter::printFrameIndexOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { + const MCOperand& MO0 = MI->getOperand(OpNo); + const MCOperand& MO1 = MI->getOperand(OpNo + 1); + + O << getRegisterName(MO0.getReg()) << ", #" << MO1.getImm(); +} + +void HexagonInstPrinter::printGlobalOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { + assert(MI->getOperand(OpNo).isExpr() && "Expecting expression"); + + printOperand(MI, OpNo, O); +} + +void HexagonInstPrinter::printJumpTable(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { + assert(MI->getOperand(OpNo).isExpr() && "Expecting expression"); + + printOperand(MI, OpNo, O); +} + +void HexagonInstPrinter::printConstantPool(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { + assert(MI->getOperand(OpNo).isExpr() && "Expecting expression"); + + printOperand(MI, OpNo, O); +} + +void HexagonInstPrinter::printBranchOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { + // Branches can take an immediate operand. This is used by the branch + // selection pass to print $+8, an eight byte displacement from the PC. + llvm_unreachable("Unknown branch operand."); +} + +void HexagonInstPrinter::printCallOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { +} + +void HexagonInstPrinter::printAbsAddrOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { +} + +void HexagonInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const { +} + +void HexagonInstPrinter::printSymbol(const MCInst *MI, unsigned OpNo, + raw_ostream &O, bool hi) const { + assert(MI->getOperand(OpNo).isImm() && "Unknown symbol operand"); + + O << '#' << (hi ? "HI" : "LO") << "(#"; + printOperand(MI, OpNo, O); + O << ')'; +} diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.h b/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.h new file mode 100644 index 00000000000..55ae95cd06d --- /dev/null +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.h @@ -0,0 +1,87 @@ +//===-- HexagonInstPrinter.h - Convert Hexagon 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 Hexagon MCInst to a .s file. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_HEXAGON_INSTPRINTER_HEXAGONINSTPRINTER_H +#define LLVM_LIB_TARGET_HEXAGON_INSTPRINTER_HEXAGONINSTPRINTER_H + +#include "llvm/MC/MCInstPrinter.h" +#include "llvm/MC/MCInstrInfo.h" + +namespace llvm { + class HexagonMCInst; + + class HexagonInstPrinter : public MCInstPrinter { + public: + explicit HexagonInstPrinter(const MCAsmInfo &MAI, + const MCInstrInfo &MII, + const MCRegisterInfo &MRI) + : MCInstPrinter(MAI, MII, MRI), MII(MII) {} + + void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot) override; + void printInst(const HexagonMCInst *MI, raw_ostream &O, StringRef Annot); + virtual StringRef getOpcodeName(unsigned Opcode) const; + void printInstruction(const MCInst *MI, raw_ostream &O); + StringRef getRegName(unsigned RegNo) const; + static const char *getRegisterName(unsigned RegNo); + + void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) const; + void printImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) const; + void printExtOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) const; + void printUnsignedImmOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const; + void printNegImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) + const; + void printNOneImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) + const; + void printMEMriOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) + const; + void printFrameIndexOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const; + void printBranchOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) + const; + void printCallOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) + const; + void printAbsAddrOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) + const; + void printPredicateOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) + const; + void printGlobalOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) + const; + void printJumpTable(const MCInst *MI, unsigned OpNo, raw_ostream &O) const; + + void printConstantPool(const MCInst *MI, unsigned OpNo, + raw_ostream &O) const; + + void printSymbolHi(const MCInst *MI, unsigned OpNo, raw_ostream &O) const + { printSymbol(MI, OpNo, O, true); } + void printSymbolLo(const MCInst *MI, unsigned OpNo, raw_ostream &O) const + { printSymbol(MI, OpNo, O, false); } + + const MCInstrInfo &getMII() const { + return MII; + } + + protected: + void printSymbol(const MCInst *MI, unsigned OpNo, raw_ostream &O, bool hi) + const; + + static const char PacketPadding; + + private: + const MCInstrInfo &MII; + + }; + +} // end namespace llvm + +#endif diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp index 4471977ab49..2ec0bd2ea86 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp @@ -38,7 +38,7 @@ enum class ParseField { duplex = 0x0, last0 = 0x1, last1 = 0x2, end = 0x3 }; uint32_t getPacketBits(HexagonMCInst const &HMI) { unsigned const ParseFieldOffset = 14; ParseField Field = HMI.isPacketEnd() ? ParseField::end : ParseField::last0; - return static_cast (Field) << ParseFieldOffset; + return static_cast(Field) << ParseFieldOffset; } void emitLittleEndian(uint64_t Binary, raw_ostream &OS) { OS << static_cast((Binary >> 0x00) & 0xff); @@ -57,8 +57,9 @@ void HexagonMCCodeEmitter::EncodeInstruction(MCInst const &MI, raw_ostream &OS, SmallVectorImpl &Fixups, MCSubtargetInfo const &STI) const { HexagonMCInst const &HMB = static_cast(MI); - uint64_t Binary = getBinaryCodeForInstr(HMB, Fixups, STI) | getPacketBits(HMB); - assert(HMB.getDesc().getSize() == 4 && "All instructions should be 32bit"); + uint64_t Binary = + getBinaryCodeForInstr(HMB, Fixups, STI) | getPacketBits(HMB); + Binary |= getPacketBits(HMB); emitLittleEndian(Binary, OS); ++MCNumEmitted; } diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.cpp index c842b9b7cf3..0f7a337ba61 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.cpp +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.cpp @@ -12,68 +12,52 @@ //===----------------------------------------------------------------------===// #include "HexagonInstrInfo.h" +#include "HexagonTargetMachine.h" #include "MCTargetDesc/HexagonBaseInfo.h" #include "MCTargetDesc/HexagonMCInst.h" #include "MCTargetDesc/HexagonMCTargetDesc.h" +#include "llvm/Support/TargetRegistry.h" using namespace llvm; -// Return the slots used by the insn. -unsigned HexagonMCInst::getUnits(const HexagonTargetMachine* TM) const { - const HexagonInstrInfo *QII = TM->getSubtargetImpl()->getInstrInfo(); - const InstrItineraryData *II = - TM->getSubtargetImpl()->getInstrItineraryData(); - const InstrStage* - IS = II->beginStage(QII->get(this->getOpcode()).getSchedClass()); - - return (IS->getUnits()); +HexagonMCInst::HexagonMCInst(unsigned op) + : packetBegin(false), packetEnd(false), + MCID(llvm::TheHexagonTarget.createMCInstrInfo()->get(op)) { + assert(MCID.getSize() == 4 && "All instructions should be 32bit"); + setOpcode(op); } -// Return the Hexagon ISA class for the insn. -unsigned HexagonMCInst::getType() const { - const uint64_t F = MCID->TSFlags; +bool HexagonMCInst::isPacketBegin() const { return packetBegin; } +bool HexagonMCInst::isPacketEnd() const { return packetEnd; } +void HexagonMCInst::setPacketEnd(bool Y) { packetEnd = Y; } +void HexagonMCInst::setPacketBegin(bool Y) { packetBegin = Y; } - return ((F >> HexagonII::TypePos) & HexagonII::TypeMask); -} - -// Return whether the insn is an actual insn. -bool HexagonMCInst::isCanon() const { - return (!MCID->isPseudo() && - !isPrefix() && - getType() != HexagonII::TypeENDLOOP); -} +unsigned HexagonMCInst::getUnits(HexagonTargetMachine const &TM) const { + const HexagonInstrInfo *QII = TM.getSubtargetImpl()->getInstrInfo(); + const InstrItineraryData *II = TM.getSubtargetImpl()->getInstrItineraryData(); + const InstrStage *IS = + II->beginStage(QII->get(this->getOpcode()).getSchedClass()); -// Return whether the insn is a prefix. -bool HexagonMCInst::isPrefix() const { - return (getType() == HexagonII::TypePREFIX); -} - -// Return whether the insn is solo, i.e., cannot be in a packet. -bool HexagonMCInst::isSolo() const { - const uint64_t F = MCID->TSFlags; - return ((F >> HexagonII::SoloPos) & HexagonII::SoloMask); + return (IS->getUnits()); } -// Return whether the insn is a new-value consumer. bool HexagonMCInst::isNewValue() const { - const uint64_t F = MCID->TSFlags; + const uint64_t F = MCID.TSFlags; return ((F >> HexagonII::NewValuePos) & HexagonII::NewValueMask); } -// Return whether the instruction is a legal new-value producer. bool HexagonMCInst::hasNewValue() const { - const uint64_t F = MCID->TSFlags; + const uint64_t F = MCID.TSFlags; return ((F >> HexagonII::hasNewValuePos) & HexagonII::hasNewValueMask); } -// Return the operand that consumes or produces a new value. -const MCOperand& HexagonMCInst::getNewValue() const { - const uint64_t F = MCID->TSFlags; - const unsigned O = (F >> HexagonII::NewValueOpPos) & - HexagonII::NewValueOpMask; - const MCOperand& MCO = getOperand(O); +MCOperand const &HexagonMCInst::getNewValue() const { + const uint64_t F = MCID.TSFlags; + const unsigned O = + (F >> HexagonII::NewValueOpPos) & HexagonII::NewValueOpMask; + const MCOperand &MCO = getOperand(O); - assert ((isNewValue() || hasNewValue()) && MCO.isReg()); + assert((isNewValue() || hasNewValue()) && MCO.isReg()); return (MCO); } @@ -84,7 +68,6 @@ const MCOperand& HexagonMCInst::getNewValue() const { // 2) For immediate extended operands, return true only if the value is // out-of-range. // 3) For global address, always return true. - bool HexagonMCInst::isConstExtended(void) const { if (isExtended()) return true; @@ -93,9 +76,9 @@ bool HexagonMCInst::isConstExtended(void) const { return false; short ExtOpNum = getCExtOpNum(); - int MinValue = getMinValue(); - int MaxValue = getMaxValue(); - const MCOperand& MO = getOperand(ExtOpNum); + int MinValue = getMinValue(); + int MaxValue = getMaxValue(); + const MCOperand &MO = getOperand(ExtOpNum); // We could be using an instruction with an extendable immediate and shoehorn // a global address into it. If it is a global address it will be constant @@ -114,62 +97,51 @@ bool HexagonMCInst::isConstExtended(void) const { return (ImmValue < MinValue || ImmValue > MaxValue); } -// Return whether the instruction must be always extended. bool HexagonMCInst::isExtended(void) const { - const uint64_t F = MCID->TSFlags; + const uint64_t F = MCID.TSFlags; return (F >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask; } -// Return true if the instruction may be extended based on the operand value. bool HexagonMCInst::isExtendable(void) const { - const uint64_t F = MCID->TSFlags; + const uint64_t F = MCID.TSFlags; return (F >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask; } -// Return number of bits in the constant extended operand. unsigned HexagonMCInst::getBitCount(void) const { - const uint64_t F = MCID->TSFlags; + const uint64_t F = MCID.TSFlags; return ((F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask); } -// Return constant extended operand number. unsigned short HexagonMCInst::getCExtOpNum(void) const { - const uint64_t F = MCID->TSFlags; + const uint64_t F = MCID.TSFlags; return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask); } -// Return whether the operand can be constant extended. bool HexagonMCInst::isOperandExtended(const unsigned short OperandNum) const { - const uint64_t F = MCID->TSFlags; - return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask) - == OperandNum; + const uint64_t F = MCID.TSFlags; + return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask) == + OperandNum; } -// Return the min value that a constant extendable operand can have -// without being extended. int HexagonMCInst::getMinValue(void) const { - const uint64_t F = MCID->TSFlags; - unsigned isSigned = (F >> HexagonII::ExtentSignedPos) - & HexagonII::ExtentSignedMask; - unsigned bits = (F >> HexagonII::ExtentBitsPos) - & HexagonII::ExtentBitsMask; + const uint64_t F = MCID.TSFlags; + unsigned isSigned = + (F >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask; + unsigned bits = (F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask; - if (isSigned) // if value is signed + if (isSigned) return -1U << (bits - 1); else return 0; } -// Return the max value that a constant extendable operand can have -// without being extended. int HexagonMCInst::getMaxValue(void) const { - const uint64_t F = MCID->TSFlags; - unsigned isSigned = (F >> HexagonII::ExtentSignedPos) - & HexagonII::ExtentSignedMask; - unsigned bits = (F >> HexagonII::ExtentBitsPos) - & HexagonII::ExtentBitsMask; + const uint64_t F = MCID.TSFlags; + unsigned isSigned = + (F >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask; + unsigned bits = (F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask; - if (isSigned) // if value is signed + if (isSigned) return ~(-1U << (bits - 1)); else return ~(-1U << bits); diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.h b/lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.h index 90fbbf3f60a..e456aefcefb 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.h +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.h @@ -14,87 +14,55 @@ #ifndef LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCINST_H #define LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCINST_H -#include "HexagonTargetMachine.h" #include "llvm/MC/MCInst.h" namespace llvm { - class MCOperand; - - class HexagonMCInst: public MCInst { - // MCID is set during instruction lowering. - // It is needed in order to access TSFlags for - // use in checking MC instruction properties. - const MCInstrDesc *MCID; - - // Packet start and end markers - unsigned packetStart: 1, packetEnd: 1; - - public: - explicit HexagonMCInst(): - MCInst(), MCID(nullptr), packetStart(0), packetEnd(0) {}; - HexagonMCInst(const MCInstrDesc& mcid): - MCInst(), MCID(&mcid), packetStart(0), packetEnd(0) {}; - - bool isPacketStart() const { return (packetStart); }; - bool isPacketEnd() const { return (packetEnd); }; - void setPacketStart(bool Y) { packetStart = Y; }; - void setPacketEnd(bool Y) { packetEnd = Y; }; - void resetPacket() { setPacketStart(false); setPacketEnd(false); }; - - // Return the slots used by the insn. - unsigned getUnits(const HexagonTargetMachine* TM) const; - - // Return the Hexagon ISA class for the insn. - unsigned getType() const; - - void setDesc(const MCInstrDesc& mcid) { MCID = &mcid; }; - const MCInstrDesc& getDesc(void) const { return *MCID; }; - - // Return whether the insn is an actual insn. - bool isCanon() const; - - // Return whether the insn is a prefix. - bool isPrefix() const; - - // Return whether the insn is solo, i.e., cannot be in a packet. - bool isSolo() const; - - // Return whether the instruction needs to be constant extended. - bool isConstExtended() const; - - // Return constant extended operand number. - unsigned short getCExtOpNum(void) const; - - // Return whether the insn is a new-value consumer. - bool isNewValue() const; - - // Return whether the instruction is a legal new-value producer. - bool hasNewValue() const; - - // Return the operand that consumes or produces a new value. - const MCOperand& getNewValue() const; - - // Return number of bits in the constant extended operand. - unsigned getBitCount(void) const; - - private: - // Return whether the instruction must be always extended. - bool isExtended() const; - - // Return true if the insn may be extended based on the operand value. - bool isExtendable() const; - - // Return true if the operand can be constant extended. - bool isOperandExtended(const unsigned short OperandNum) const; - - // Return the min value that a constant extendable operand can have - // without being extended. - int getMinValue() const; - - // Return the max value that a constant extendable operand can have - // without being extended. - int getMaxValue() const; - }; +class MCInstrDesc; +class MCOperand; +class HexagonTargetMachine; + +class HexagonMCInst : public MCInst { +public: + explicit HexagonMCInst(unsigned op); + + /// 10.6 Instruction Packets + bool isPacketBegin() const; + /// \brief Is this marked as last in packet. + bool isPacketEnd() const; + void setPacketBegin(bool Y); + /// \brief Mark this as last in packet. + void setPacketEnd(bool Y); + /// \brief Return the slots used. + unsigned getUnits(HexagonTargetMachine const &TM) const; + bool isConstExtended() const; + /// \brief Return constant extended operand number. + unsigned short getCExtOpNum(void) const; + /// \brief Return whether this is a new-value consumer. + bool isNewValue() const; + /// \brief Return whether this is a legal new-value producer. + bool hasNewValue() const; + /// \brief Return the operand that consumes or produces a new value. + MCOperand const &getNewValue() const; + /// \brief Return number of bits in the constant extended operand. + unsigned getBitCount(void) const; + +private: + /// \brief Return whether this must be always extended. + bool isExtended() const; + /// \brief Return true if this may be extended based on the operand value. + bool isExtendable() const; + /// \brief Return if the operand can be constant extended. + bool isOperandExtended(unsigned short const OperandNum) const; + /// \brief Return the min value that a constant extendable operand can have + /// without being extended. + int getMinValue() const; + /// \brief Return the max value that a constant extendable operand can have + /// without being extended. + int getMaxValue() const; + bool packetBegin; + bool packetEnd; + MCInstrDesc const &MCID; +}; } #endif diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp index 65cf42ae648..1ae25376469 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp @@ -13,7 +13,7 @@ #include "HexagonMCTargetDesc.h" #include "HexagonMCAsmInfo.h" -#include "InstPrinter/HexagonInstPrinter.h" +#include "MCTargetDesc/HexagonInstPrinter.h" #include "llvm/MC/MCCodeGenInfo.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" @@ -34,7 +34,7 @@ using namespace llvm; #define GET_REGINFO_MC_DESC #include "HexagonGenRegisterInfo.inc" -static MCInstrInfo *createHexagonMCInstrInfo() { +static llvm::MCInstrInfo *createHexagonMCInstrInfo() { MCInstrInfo *X = new MCInstrInfo(); InitHexagonMCInstrInfo(X); return X; diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.h b/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.h index 4ce429c4420..c99815ce477 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.h +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.h @@ -15,6 +15,8 @@ #define LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCTARGETDESC_H namespace llvm { +struct InstrItinerary; +struct InstrStage; class MCCodeEmitter; class MCContext; class MCInstrInfo; diff --git a/lib/Target/Hexagon/MCTargetDesc/LLVMBuild.txt b/lib/Target/Hexagon/MCTargetDesc/LLVMBuild.txt index 5ecdd504e8c..f559a21e3f9 100644 --- a/lib/Target/Hexagon/MCTargetDesc/LLVMBuild.txt +++ b/lib/Target/Hexagon/MCTargetDesc/LLVMBuild.txt @@ -19,5 +19,5 @@ type = Library name = HexagonDesc parent = Hexagon -required_libraries = HexagonAsmPrinter HexagonInfo MC Support +required_libraries = HexagonInfo MC Support add_to_library_groups = Hexagon diff --git a/lib/Target/Hexagon/Makefile b/lib/Target/Hexagon/Makefile index ccc0bbac588..de43415a3aa 100644 --- a/lib/Target/Hexagon/Makefile +++ b/lib/Target/Hexagon/Makefile @@ -14,12 +14,13 @@ TARGET = Hexagon BUILT_SOURCES = HexagonGenRegisterInfo.inc \ HexagonGenInstrInfo.inc \ HexagonGenAsmWriter.inc \ - HexagonGenDAGISel.inc HexagonGenSubtargetInfo.inc \ - HexagonGenCallingConv.inc \ - HexagonGenDFAPacketizer.inc \ - HexagonGenMCCodeEmitter.inc \ - HexagonGenDisassemblerTables.inc - -DIRS = InstPrinter TargetInfo MCTargetDesc Disassembler - -include $(LEVEL)/Makefile.common + HexagonGenDAGISel.inc \ + HexagonGenSubtargetInfo.inc \ + HexagonGenCallingConv.inc \ + HexagonGenDFAPacketizer.inc \ + HexagonGenMCCodeEmitter.inc \ + HexagonGenDisassemblerTables.inc + +DIRS = TargetInfo MCTargetDesc Disassembler + +include $(LEVEL)/Makefile.common diff --git a/test/MC/Disassembler/Hexagon/alu32.txt b/test/MC/Disassembler/Hexagon/alu32.txt new file mode 100644 index 00000000000..a04a8853715 --- /dev/null +++ b/test/MC/Disassembler/Hexagon/alu32.txt @@ -0,0 +1,4 @@ +# RUN: llvm-mc --triple hexagon -disassemble < %s | FileCheck %s + +0x11 0xdf 0x15 0xf3 +# CHECK: r17 = add(r21, r31) diff --git a/test/MC/Disassembler/Hexagon/lit.local.cfg b/test/MC/Disassembler/Hexagon/lit.local.cfg new file mode 100644 index 00000000000..1737c51a7b0 --- /dev/null +++ b/test/MC/Disassembler/Hexagon/lit.local.cfg @@ -0,0 +1,3 @@ +if 'Hexagon' not in config.root.targets: + config.unsupported = True + diff --git a/unittests/MC/CMakeLists.txt b/unittests/MC/CMakeLists.txt index 95a3fff2b52..271309c0859 100644 --- a/unittests/MC/CMakeLists.txt +++ b/unittests/MC/CMakeLists.txt @@ -7,9 +7,3 @@ add_llvm_unittest(MCTests StringTableBuilderTest.cpp YAMLTest.cpp ) - -foreach(t ${LLVM_TARGETS_TO_BUILD}) - if (IS_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/${t}") - add_subdirectory(${t}) - endif (IS_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/${t}") -endforeach() diff --git a/unittests/MC/Hexagon/HexagonMCCodeEmitterTest.cpp b/unittests/MC/Hexagon/HexagonMCCodeEmitterTest.cpp deleted file mode 100644 index 958a21fa3fc..00000000000 --- a/unittests/MC/Hexagon/HexagonMCCodeEmitterTest.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include "gtest/gtest.h" - -#include - -#include "llvm/MC/MCCodeEmitter.h" -#include "llvm/MC/MCContext.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Support/TargetRegistry.h" -#include "llvm/Support/TargetSelect.h" - -#include "MCTargetDesc/HexagonMCInst.h" -#include "MCTargetDesc/HexagonMCTargetDesc.h" - -namespace { -class TestEmitter { -public: - TestEmitter() : Triple("hexagon-unknown-elf") { - LLVMInitializeHexagonTargetInfo(); - LLVMInitializeHexagonTarget(); - LLVMInitializeHexagonTargetMC(); - std::string error; - Target = llvm::TargetRegistry::lookupTarget("hexagon", error); - assert(Target != nullptr && "Expected to find target"); - assert(error.empty() && "Error should be empty if we have a target"); - RegisterInfo = Target->createMCRegInfo(Triple); - assert(RegisterInfo != nullptr && "Expecting to find register info"); - AsmInfo = Target->createMCAsmInfo(*RegisterInfo, Triple); - assert(AsmInfo != nullptr && "Expecting to find asm info"); - Context = new llvm::MCContext(AsmInfo, RegisterInfo, nullptr); - assert(Context != nullptr && "Expecting to create a context"); - Subtarget = Target->createMCSubtargetInfo(Triple, "hexagonv4", ""); - assert(Subtarget != nullptr && "Expecting to find a subtarget"); - InstrInfo = Target->createMCInstrInfo(); - assert(InstrInfo != nullptr && "Expecting to find instr info"); - Emitter = Target->createMCCodeEmitter(*InstrInfo, *RegisterInfo, *Subtarget, - *Context); - assert(Emitter != nullptr); - } - std::string Triple; - llvm::Target const *Target; - llvm::MCRegisterInfo *RegisterInfo; - llvm::MCAsmInfo *AsmInfo; - llvm::MCContext *Context; - llvm::MCSubtargetInfo *Subtarget; - llvm::MCInstrInfo *InstrInfo; - llvm::MCCodeEmitter *Emitter; -}; -TestEmitter Emitter; -} - -TEST(HexagonMCCodeEmitter, emitter_creation) { - ASSERT_NE(nullptr, Emitter.Emitter); -}