forked from OSchip/llvm-project
[Hexagon] Adding encoding bits for add opcode.
Adding llvm-mc tests. Removing unit tests. http://reviews.llvm.org/D5624 llvm-svn: 220427
This commit is contained in:
parent
4f9c0eeff8
commit
73a51a1a68
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -92,6 +92,77 @@ def HexagonWrapperCombineII :
|
|||
def HexagonWrapperCombineRR :
|
||||
SDNode<"HexagonISD::WrapperCombineRR", SDTHexagonI64I32I32>;
|
||||
|
||||
let hasSideEffects = 0, hasNewValue = 1, InputType = "reg" in
|
||||
class T_ALU32_3op<string mnemonic, bits<3> 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<string mnemonic, bits<3> 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<string mnemonic, bits<3> MajOp, bits<3> MinOp,
|
||||
bit OpsRev> {
|
||||
def t : T_ALU32_3op_pred<mnemonic, MajOp, MinOp, OpsRev, 0, 0>;
|
||||
def f : T_ALU32_3op_pred<mnemonic, MajOp, MinOp, OpsRev, 1, 0>;
|
||||
def tnew : T_ALU32_3op_pred<mnemonic, MajOp, MinOp, OpsRev, 0, 1>;
|
||||
def fnew : T_ALU32_3op_pred<mnemonic, MajOp, MinOp, OpsRev, 1, 1>;
|
||||
}
|
||||
|
||||
multiclass T_ALU32_3op_A2<string mnemonic, bits<3> MajOp, bits<3> MinOp,
|
||||
bit OpsRev, bit IsComm> {
|
||||
let isPredicable = 1 in
|
||||
def A2_#NAME : T_ALU32_3op <mnemonic, MajOp, MinOp, OpsRev, IsComm>;
|
||||
defm A2_p#NAME : T_ALU32_3op_p<mnemonic, MajOp, MinOp, OpsRev>;
|
||||
}
|
||||
|
||||
let isCodeGenOnly = 0 in
|
||||
defm add : T_ALU32_3op_A2<"add", 0b011, 0b000, 0, 1>;
|
||||
|
||||
multiclass ALU32_Pbase<string mnemonic, RegisterClass RC, bit isNot,
|
||||
bit isPredNew> {
|
||||
let isPredicatedNew = isPredNew in
|
||||
|
|
|
@ -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<unsigned>(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;
|
||||
}
|
||||
|
||||
|
|
|
@ -91,14 +91,13 @@ void HexagonInstPrinter::printInst(const HexagonMCInst *MI, raw_ostream &O,
|
|||
// Ending a harware loop is different from ending an regular packet.
|
||||
assert(MI->isPacketEnd() && "Loop-end must also end the packet");
|
||||
|
||||
if (MI->isPacketStart()) {
|
||||
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;
|
||||
HexagonMCInst Nop (Hexagon::NOP);
|
||||
StringRef NoAnnot;
|
||||
|
||||
Nop.setOpcode (Hexagon::NOP);
|
||||
Nop.setPacketStart (MI->isPacketStart());
|
||||
Nop.setPacketBegin (MI->isPacketBegin());
|
||||
printInst (&Nop, O, NoAnnot);
|
||||
}
|
||||
|
||||
|
@ -110,7 +109,7 @@ void HexagonInstPrinter::printInst(const HexagonMCInst *MI, raw_ostream &O,
|
|||
}
|
||||
else {
|
||||
// Prefix the insn opening the packet.
|
||||
if (MI->isPacketStart())
|
||||
if (MI->isPacketBegin())
|
||||
O << PacketPadding << startPacket << '\n';
|
||||
|
||||
printInstruction(MI, O);
|
||||
|
|
|
@ -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 <uint32_t> (Field) << ParseFieldOffset;
|
||||
return static_cast<uint32_t>(Field) << ParseFieldOffset;
|
||||
}
|
||||
void emitLittleEndian(uint64_t Binary, raw_ostream &OS) {
|
||||
OS << static_cast<uint8_t>((Binary >> 0x00) & 0xff);
|
||||
|
@ -57,8 +57,9 @@ void HexagonMCCodeEmitter::EncodeInstruction(MCInst const &MI, raw_ostream &OS,
|
|||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
MCSubtargetInfo const &STI) const {
|
||||
HexagonMCInst const &HMB = static_cast<HexagonMCInst const &>(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;
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
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);
|
||||
}
|
||||
|
||||
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; }
|
||||
|
||||
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 (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;
|
||||
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);
|
||||
|
|
|
@ -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 MCInstrDesc;
|
||||
class MCOperand;
|
||||
class HexagonTargetMachine;
|
||||
|
||||
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;
|
||||
class HexagonMCInst : public MCInst {
|
||||
public:
|
||||
explicit HexagonMCInst(unsigned op);
|
||||
|
||||
// Packet start and end markers
|
||||
unsigned packetStart: 1, packetEnd: 1;
|
||||
/// 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;
|
||||
|
||||
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;
|
||||
};
|
||||
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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#define LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCTARGETDESC_H
|
||||
|
||||
namespace llvm {
|
||||
struct InstrItinerary;
|
||||
struct InstrStage;
|
||||
class MCCodeEmitter;
|
||||
class MCContext;
|
||||
class MCInstrInfo;
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
# RUN: llvm-mc --triple hexagon -disassemble < %s | FileCheck %s
|
||||
|
||||
0x11 0xdf 0x15 0xf3
|
||||
# CHECK: r17 = add(r21, r31)
|
|
@ -0,0 +1,3 @@
|
|||
if 'Hexagon' not in config.root.targets:
|
||||
config.unsupported = True
|
||||
|
|
@ -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()
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
#include "gtest/gtest.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#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);
|
||||
}
|
Loading…
Reference in New Issue