mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-26 21:20:37 +00:00
Hexagon: Move HexagonMCInst.h to MCTargetDesc/HexagonMCInst.h.
Add HexagonMCInst class which adds various Hexagon VLIW annotations. In addition, this class also includes some APIs related to the constant extenders. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175634 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
6139b55222
commit
d6c98ae638
@ -21,9 +21,10 @@
|
||||
|
||||
namespace llvm {
|
||||
class FunctionPass;
|
||||
class ModulePass;
|
||||
class TargetMachine;
|
||||
class MachineInstr;
|
||||
class MCInst;
|
||||
class HexagonMCInst;
|
||||
class HexagonAsmPrinter;
|
||||
class HexagonTargetMachine;
|
||||
class raw_ostream;
|
||||
@ -54,7 +55,7 @@ namespace llvm {
|
||||
TargetAsmBackend *createHexagonAsmBackend(const Target &,
|
||||
const std::string &);
|
||||
*/
|
||||
void HexagonLowerToMC(const MachineInstr *MI, MCInst &MCI,
|
||||
void HexagonLowerToMC(const MachineInstr *MI, HexagonMCInst &MCI,
|
||||
HexagonAsmPrinter &AP);
|
||||
} // end namespace llvm;
|
||||
|
||||
|
@ -14,12 +14,12 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "asm-printer"
|
||||
#include "HexagonAsmPrinter.h"
|
||||
#include "Hexagon.h"
|
||||
#include "HexagonMCInst.h"
|
||||
#include "HexagonAsmPrinter.h"
|
||||
#include "HexagonMachineFunctionInfo.h"
|
||||
#include "HexagonSubtarget.h"
|
||||
#include "HexagonTargetMachine.h"
|
||||
#include "HexagonSubtarget.h"
|
||||
#include "MCTargetDesc/HexagonMCInst.h"
|
||||
#include "InstPrinter/HexagonInstPrinter.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
@ -220,8 +220,8 @@ void HexagonAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
||||
assert((Size+IgnoreCount) == MI->getBundleSize() && "Corrupt Bundle!");
|
||||
for (unsigned Index = 0; Index < Size; Index++) {
|
||||
HexagonMCInst MCI;
|
||||
MCI.setStartPacket(Index == 0);
|
||||
MCI.setEndPacket(Index == (Size-1));
|
||||
MCI.setPacketStart(Index == 0);
|
||||
MCI.setPacketEnd(Index == (Size-1));
|
||||
|
||||
HexagonLowerToMC(BundleMIs[Index], MCI, *this);
|
||||
OutStreamer.EmitInstruction(MCI);
|
||||
@ -230,8 +230,8 @@ void HexagonAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
||||
else {
|
||||
HexagonMCInst MCI;
|
||||
if (MI->getOpcode() == Hexagon::ENDLOOP0) {
|
||||
MCI.setStartPacket(true);
|
||||
MCI.setEndPacket(true);
|
||||
MCI.setPacketStart(true);
|
||||
MCI.setPacketEnd(true);
|
||||
}
|
||||
HexagonLowerToMC(MI, MCI, *this);
|
||||
OutStreamer.EmitInstruction(MCI);
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "Hexagon.h"
|
||||
#include "HexagonAsmPrinter.h"
|
||||
#include "HexagonMachineFunctionInfo.h"
|
||||
#include "MCTargetDesc/HexagonMCInst.h"
|
||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/MC/MCExpr.h"
|
||||
@ -38,9 +39,10 @@ static MCOperand GetSymbolRef(const MachineOperand& MO, const MCSymbol* Symbol,
|
||||
}
|
||||
|
||||
// Create an MCInst from a MachineInstr
|
||||
void llvm::HexagonLowerToMC(const MachineInstr* MI, MCInst& MCI,
|
||||
void llvm::HexagonLowerToMC(const MachineInstr* MI, HexagonMCInst& MCI,
|
||||
HexagonAsmPrinter& AP) {
|
||||
MCI.setOpcode(MI->getOpcode());
|
||||
MCI.setDesc(MI->getDesc());
|
||||
|
||||
for (unsigned i = 0, e = MI->getNumOperands(); i < e; i++) {
|
||||
const MachineOperand &MO = MI->getOperand(i);
|
||||
|
@ -12,14 +12,14 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "asm-printer"
|
||||
#include "HexagonInstPrinter.h"
|
||||
#include "Hexagon.h"
|
||||
#include "HexagonAsmPrinter.h"
|
||||
#include "HexagonMCInst.h"
|
||||
#include "Hexagon.h"
|
||||
#include "HexagonInstPrinter.h"
|
||||
#include "MCTargetDesc/HexagonMCInst.h"
|
||||
#include "llvm/MC/MCInst.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"
|
||||
#include <cstdio>
|
||||
|
||||
@ -28,6 +28,8 @@ using namespace llvm;
|
||||
#define GET_INSTRUCTION_NAME
|
||||
#include "HexagonGenAsmWriter.inc"
|
||||
|
||||
const char HexagonInstPrinter::PacketPadding = '\t';
|
||||
|
||||
StringRef HexagonInstPrinter::getOpcodeName(unsigned Opcode) const {
|
||||
return MII.getName(Opcode);
|
||||
}
|
||||
@ -43,43 +45,42 @@ void HexagonInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
|
||||
|
||||
void HexagonInstPrinter::printInst(const HexagonMCInst *MI, raw_ostream &O,
|
||||
StringRef Annot) {
|
||||
const char packetPadding[] = " ";
|
||||
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->isEndPacket() && "Loop end must also end the packet");
|
||||
assert(MI->isPacketEnd() && "Loop-end must also end the packet");
|
||||
|
||||
if (MI->isStartPacket()) {
|
||||
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.setStartPacket (MI->isStartPacket());
|
||||
Nop.setPacketStart (MI->isPacketStart());
|
||||
printInst (&Nop, O, NoAnnot);
|
||||
}
|
||||
|
||||
// Close the packet.
|
||||
if (MI->isEndPacket())
|
||||
O << packetPadding << endPacket;
|
||||
if (MI->isPacketEnd())
|
||||
O << PacketPadding << endPacket;
|
||||
|
||||
printInstruction(MI, O);
|
||||
}
|
||||
else {
|
||||
// Prefix the insn opening the packet.
|
||||
if (MI->isStartPacket())
|
||||
O << packetPadding << startPacket << '\n';
|
||||
if (MI->isPacketStart())
|
||||
O << PacketPadding << startPacket << '\n';
|
||||
|
||||
printInstruction(MI, O);
|
||||
|
||||
// Suffix the insn closing the packet.
|
||||
if (MI->isEndPacket())
|
||||
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;
|
||||
O << '\n' << PacketPadding << endPacket;
|
||||
}
|
||||
|
||||
printAnnotation(O, Annot);
|
||||
@ -102,12 +103,23 @@ void HexagonInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
|
||||
|
||||
void HexagonInstPrinter::printImmOperand(const MCInst *MI, unsigned OpNo,
|
||||
raw_ostream &O) const {
|
||||
O << MI->getOperand(OpNo).getImm();
|
||||
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 {
|
||||
O << MI->getOperand(OpNo).getImm();
|
||||
const HexagonMCInst *HMCI = static_cast<const HexagonMCInst*>(MI);
|
||||
if (HMCI->isConstExtended())
|
||||
O << "#";
|
||||
printOperand(MI, OpNo, O);
|
||||
}
|
||||
|
||||
void HexagonInstPrinter::printUnsignedImmOperand(const MCInst *MI,
|
||||
|
@ -14,16 +14,18 @@
|
||||
#ifndef HEXAGONINSTPRINTER_H
|
||||
#define HEXAGONINSTPRINTER_H
|
||||
|
||||
#include "HexagonMCInst.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) {}
|
||||
: MCInstPrinter(MAI, MII, MRI), MII(MII) {}
|
||||
|
||||
virtual void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot);
|
||||
void printInst(const HexagonMCInst *MI, raw_ostream &O, StringRef Annot);
|
||||
@ -65,10 +67,19 @@ namespace llvm {
|
||||
void printSymbolLo(const MCInst *MI, unsigned OpNo, raw_ostream &O) const
|
||||
{ printSymbol(MI, OpNo, O, false); }
|
||||
|
||||
bool isConstExtended(const MCInst *MI) const;
|
||||
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
|
||||
|
@ -19,5 +19,5 @@
|
||||
type = Library
|
||||
name = HexagonAsmPrinter
|
||||
parent = Hexagon
|
||||
required_libraries = MC Support
|
||||
required_libraries = HexagonDesc MC Support
|
||||
add_to_library_groups = Hexagon
|
||||
|
@ -1,6 +1,7 @@
|
||||
add_llvm_library(LLVMHexagonDesc
|
||||
HexagonMCTargetDesc.cpp
|
||||
HexagonMCAsmInfo.cpp
|
||||
HexagonMCInst.cpp
|
||||
HexagonMCTargetDesc.cpp
|
||||
)
|
||||
|
||||
add_dependencies(LLVMHexagonDesc HexagonCommonTableGen)
|
||||
|
175
lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.cpp
Normal file
175
lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.cpp
Normal file
@ -0,0 +1,175 @@
|
||||
//===- HexagonMCInst.cpp - Hexagon sub-class of MCInst --------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This class extends MCInst to allow some Hexagon VLIW annotations.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "HexagonInstrInfo.h"
|
||||
#include "MCTargetDesc/HexagonBaseInfo.h"
|
||||
#include "MCTargetDesc/HexagonMCInst.h"
|
||||
#include "MCTargetDesc/HexagonMCTargetDesc.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
// Return the slots used by the insn.
|
||||
unsigned HexagonMCInst::getUnits(const HexagonTargetMachine* TM) const {
|
||||
const HexagonInstrInfo* QII = TM->getInstrInfo();
|
||||
const InstrItineraryData* II = TM->getInstrItineraryData();
|
||||
const InstrStage*
|
||||
IS = II->beginStage(QII->get(this->getOpcode()).getSchedClass());
|
||||
|
||||
return (IS->getUnits());
|
||||
}
|
||||
|
||||
// Return the Hexagon ISA class for the insn.
|
||||
unsigned HexagonMCInst::getType() const {
|
||||
const uint64_t F = MCID->TSFlags;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// 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 whether the insn is a new-value consumer.
|
||||
bool HexagonMCInst::isNewValue() const {
|
||||
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;
|
||||
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);
|
||||
|
||||
assert ((isNewValue() || hasNewValue()) && MCO.isReg());
|
||||
return (MCO);
|
||||
}
|
||||
|
||||
// Return whether the instruction needs to be constant extended.
|
||||
// 1) Always return true if the instruction has 'isExtended' flag set.
|
||||
//
|
||||
// isExtendable:
|
||||
// 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;
|
||||
|
||||
if (!isExtendable())
|
||||
return false;
|
||||
|
||||
short ExtOpNum = getCExtOpNum();
|
||||
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
|
||||
// extended. We do this for COMBINE.
|
||||
// We currently only handle isGlobal() because it is the only kind of
|
||||
// object we are going to end up with here for now.
|
||||
// In the future we probably should add isSymbol(), etc.
|
||||
if (MO.isExpr())
|
||||
return true;
|
||||
|
||||
// If the extendable operand is not 'Immediate' type, the instruction should
|
||||
// have 'isExtended' flag set.
|
||||
assert(MO.isImm() && "Extendable operand must be Immediate type");
|
||||
|
||||
int ImmValue = MO.getImm();
|
||||
return (ImmValue < MinValue || ImmValue > MaxValue);
|
||||
}
|
||||
|
||||
// Return whether the instruction must be always extended.
|
||||
bool HexagonMCInst::isExtended(void) const {
|
||||
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;
|
||||
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;
|
||||
return ((F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask);
|
||||
}
|
||||
|
||||
// Return constant extended operand number.
|
||||
unsigned short HexagonMCInst::getCExtOpNum(void) const {
|
||||
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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
if (isSigned) // if value is signed
|
||||
return -1 << (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;
|
||||
|
||||
if (isSigned) // if value is signed
|
||||
return ~(-1 << (bits - 1));
|
||||
else
|
||||
return ~(-1 << bits);
|
||||
}
|
100
lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.h
Normal file
100
lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.h
Normal file
@ -0,0 +1,100 @@
|
||||
//===- HexagonMCInst.h - Hexagon sub-class of MCInst ----------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This class extends MCInst to allow some VLIW annotations.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef HEXAGONMCINST_H
|
||||
#define 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(0), 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;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -13,11 +13,13 @@
|
||||
|
||||
#include "HexagonMCTargetDesc.h"
|
||||
#include "HexagonMCAsmInfo.h"
|
||||
#include "InstPrinter/HexagonInstPrinter.h"
|
||||
#include "llvm/MC/MachineLocation.h"
|
||||
#include "llvm/MC/MCCodeGenInfo.h"
|
||||
#include "llvm/MC/MCInstrInfo.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
#include "llvm/MC/MCStreamer.h"
|
||||
#include "llvm/MC/MCSubtargetInfo.h"
|
||||
#include "llvm/MC/MachineLocation.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
|
||||
|
57
test/CodeGen/Hexagon/cext-check.ll
Normal file
57
test/CodeGen/Hexagon/cext-check.ll
Normal file
@ -0,0 +1,57 @@
|
||||
; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s
|
||||
; Check that we constant extended instructions only when necessary.
|
||||
|
||||
define i32 @cext_test1(i32* %a) nounwind {
|
||||
; CHECK: r{{[0-9]+}}{{ *}}={{ *}}memw(r{{[0-9]+}}+##8000)
|
||||
; CHECK: r{{[0-9]+}}{{ *}}={{ *}}add(r{{[0-9]+}}{{ *}},{{ *}}##300000)
|
||||
; CHECK-NOT: r{{[0-9]+}}{{ *}}={{ *}}memw(r{{[0-9]+}}+##4092)
|
||||
; CHECK-NOT: r{{[0-9]+}}{{ *}}={{ *}}add(r{{[0-9]+}}{{ *}},{{ *}}##300)
|
||||
entry:
|
||||
%0 = load i32* %a, align 4
|
||||
%tobool = icmp ne i32 %0, 0
|
||||
br i1 %tobool, label %if.then, label %if.end
|
||||
|
||||
if.then:
|
||||
%arrayidx1 = getelementptr inbounds i32* %a, i32 2000
|
||||
%1 = load i32* %arrayidx1, align 4
|
||||
%add = add nsw i32 %1, 300000
|
||||
br label %return
|
||||
|
||||
if.end:
|
||||
%arrayidx2 = getelementptr inbounds i32* %a, i32 1023
|
||||
%2 = load i32* %arrayidx2, align 4
|
||||
%add3 = add nsw i32 %2, 300
|
||||
br label %return
|
||||
|
||||
return:
|
||||
%retval.0 = phi i32 [ %add, %if.then ], [ %add3, %if.end ]
|
||||
ret i32 %retval.0
|
||||
}
|
||||
|
||||
define i32 @cext_test2(i8* %a) nounwind {
|
||||
; CHECK-NOT: r{{[0-9]+}}{{ *}}={{ *}}memub(r{{[0-9]+}}+##1023)
|
||||
; CHECK: r{{[0-9]+}}{{ *}}={{ *}}add(r{{[0-9]+}}{{ *}},{{ *}}##300000)
|
||||
; CHECK: r{{[0-9]+}}{{ *}}={{ *}}memub(r{{[0-9]+}}+##1024)
|
||||
; CHECK-NOT: r{{[0-9]+}}{{ *}}={{ *}}add(r{{[0-9]+}}{{ *}},{{ *}}##6000)
|
||||
entry:
|
||||
%tobool = icmp ne i8* %a, null
|
||||
br i1 %tobool, label %if.then, label %if.end
|
||||
|
||||
if.then:
|
||||
%arrayidx = getelementptr inbounds i8* %a, i32 1023
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 300000
|
||||
br label %return
|
||||
|
||||
if.end:
|
||||
%arrayidx1 = getelementptr inbounds i8* %a, i32 1024
|
||||
%1 = load i8* %arrayidx1, align 1
|
||||
%conv2 = zext i8 %1 to i32
|
||||
%add3 = add nsw i32 %conv2, 6000
|
||||
br label %return
|
||||
|
||||
return:
|
||||
%retval.0 = phi i32 [ %add, %if.then ], [ %add3, %if.end ]
|
||||
ret i32 %retval.0
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s
|
||||
; Check that we generate dual stores in one packet in V4
|
||||
|
||||
; CHECK: memw(r{{[0-9]+}}{{ *}}+{{ *}}#{{[0-9]+}}){{ *}}={{ *}}#100000
|
||||
; CHECK-NEXT: memw(r{{[0-9]+}}{{ *}}+{{ *}}#{{[0-9]+}}){{ *}}={{ *}}#500000
|
||||
; CHECK: memw(r{{[0-9]+}}{{ *}}+{{ *}}#{{[0-9]+}}){{ *}}={{ *}}##100000
|
||||
; CHECK-NEXT: memw(r{{[0-9]+}}{{ *}}+{{ *}}#{{[0-9]+}}){{ *}}={{ *}}##500000
|
||||
; CHECK-NEXT: }
|
||||
|
||||
@Reg = global i32 0, align 4
|
||||
|
Loading…
Reference in New Issue
Block a user