Support for Hexagon VLIW Packetizer.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155365 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Sirish Pande 2012-04-23 17:49:20 +00:00
parent 9f6852dcc2
commit 0dac3919e5
22 changed files with 7878 additions and 684 deletions

View File

@ -28,6 +28,7 @@ add_llvm_target(HexagonCodeGen
HexagonSubtarget.cpp
HexagonTargetMachine.cpp
HexagonTargetObjectFile.cpp
HexagonVLIWPacketizer.cpp
)
add_subdirectory(TargetInfo)

View File

@ -40,6 +40,7 @@ namespace llvm {
FunctionPass *createHexagonHardwareLoops();
FunctionPass *createHexagonPeephole();
FunctionPass *createHexagonFixupHwLoops();
FunctionPass *createHexagonPacketizer();
/* TODO: object output.
MCCodeEmitter *createHexagonMCCodeEmitter(const Target &,

View File

@ -13,11 +13,11 @@
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "asm-printer"
#include "Hexagon.h"
#include "HexagonAsmPrinter.h"
#include "HexagonMachineFunctionInfo.h"
#include "HexagonMCInst.h"
#include "HexagonTargetMachine.h"
#include "HexagonSubtarget.h"
#include "InstPrinter/HexagonInstPrinter.h"
@ -54,6 +54,7 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include <map>
using namespace llvm;
@ -77,8 +78,7 @@ void HexagonAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
const MachineOperand &MO = MI->getOperand(OpNo);
switch (MO.getType()) {
default:
assert(0 && "<unknown operand type>");
default: llvm_unreachable ("<unknown operand type>");
case MachineOperand::MO_Register:
O << HexagonInstPrinter::getRegisterName(MO.getReg());
return;
@ -196,10 +196,45 @@ void HexagonAsmPrinter::printPredicateOperand(const MachineInstr *MI,
/// the current output stream.
///
void HexagonAsmPrinter::EmitInstruction(const MachineInstr *MI) {
MCInst MCI;
if (MI->isBundle()) {
std::vector<const MachineInstr*> BundleMIs;
HexagonLowerToMC(MI, MCI, *this);
OutStreamer.EmitInstruction(MCI);
const MachineBasicBlock *MBB = MI->getParent();
MachineBasicBlock::const_instr_iterator MII = MI;
++MII;
unsigned int IgnoreCount = 0;
while (MII != MBB->end() && MII->isInsideBundle()) {
const MachineInstr *MInst = MII;
if (MInst->getOpcode() == TargetOpcode::DBG_VALUE ||
MInst->getOpcode() == TargetOpcode::IMPLICIT_DEF) {
IgnoreCount++;
++MII;
continue;
}
//BundleMIs.push_back(&*MII);
BundleMIs.push_back(MInst);
++MII;
}
unsigned Size = BundleMIs.size();
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));
HexagonLowerToMC(BundleMIs[Index], MCI, *this);
OutStreamer.EmitInstruction(MCI);
}
}
else {
HexagonMCInst MCI;
if (MI->getOpcode() == Hexagon::ENDLOOP0) {
MCI.setStartPacket(true);
MCI.setEndPacket(true);
}
HexagonLowerToMC(MI, MCI, *this);
OutStreamer.EmitInstruction(MCI);
}
return;
}
@ -242,17 +277,17 @@ void HexagonAsmPrinter::printJumpTable(const MachineInstr *MI, int OpNo,
raw_ostream &O) {
const MachineOperand &MO = MI->getOperand(OpNo);
assert( (MO.getType() == MachineOperand::MO_JumpTableIndex) &&
"Expecting jump table index");
"Expecting jump table index");
// Hexagon_TODO: Do we need name mangling?
O << *GetJTISymbol(MO.getIndex());
}
void HexagonAsmPrinter::printConstantPool(const MachineInstr *MI, int OpNo,
raw_ostream &O) {
raw_ostream &O) {
const MachineOperand &MO = MI->getOperand(OpNo);
assert( (MO.getType() == MachineOperand::MO_ConstantPoolIndex) &&
"Expecting constant pool index");
"Expecting constant pool index");
// Hexagon_TODO: Do we need name mangling?
O << *GetCPISymbol(MO.getIndex());

View File

@ -13,13 +13,26 @@
// *** Must match HexagonBaseInfo.h ***
//===----------------------------------------------------------------------===//
class Type<bits<5> t> {
bits<5> Value = t;
}
def TypePSEUDO : Type<0>;
def TypeALU32 : Type<1>;
def TypeCR : Type<2>;
def TypeJR : Type<3>;
def TypeJ : Type<4>;
def TypeLD : Type<5>;
def TypeST : Type<6>;
def TypeSYSTEM : Type<7>;
def TypeXTYPE : Type<8>;
def TypeMARKER : Type<31>;
//===----------------------------------------------------------------------===//
// Intruction Class Declaration +
//===----------------------------------------------------------------------===//
class InstHexagon<dag outs, dag ins, string asmstr, list<dag> pattern,
string cstr, InstrItinClass itin> : Instruction {
string cstr, InstrItinClass itin, Type type> : Instruction {
field bits<32> Inst;
let Namespace = "Hexagon";
@ -31,11 +44,15 @@ class InstHexagon<dag outs, dag ins, string asmstr, list<dag> pattern,
let Constraints = cstr;
let Itinerary = itin;
// *** The code below must match HexagonBaseInfo.h ***
// *** Must match HexagonBaseInfo.h ***
Type HexagonType = type;
let TSFlags{4-0} = HexagonType.Value;
bits<1> isHexagonSolo = 0;
let TSFlags{5} = isHexagonSolo;
// Predicated instructions.
bits<1> isPredicated = 0;
let TSFlags{1} = isPredicated;
let TSFlags{6} = isPredicated;
// *** The code above must match HexagonBaseInfo.h ***
}
@ -47,17 +64,25 @@ class InstHexagon<dag outs, dag ins, string asmstr, list<dag> pattern,
// LD Instruction Class in V2/V3/V4.
// Definition of the instruction class NOT CHANGED.
class LDInst<dag outs, dag ins, string asmstr, list<dag> pattern>
: InstHexagon<outs, ins, asmstr, pattern, "", LD> {
: InstHexagon<outs, ins, asmstr, pattern, "", LD, TypeLD> {
bits<5> rd;
bits<5> rs;
bits<13> imm13;
}
class LDInst2<dag outs, dag ins, string asmstr, list<dag> pattern>
: InstHexagon<outs, ins, asmstr, pattern, "", LD, TypeLD> {
bits<5> rd;
bits<5> rs;
bits<13> imm13;
let mayLoad = 1;
}
// LD Instruction Class in V2/V3/V4.
// Definition of the instruction class NOT CHANGED.
class LDInstPost<dag outs, dag ins, string asmstr, list<dag> pattern,
string cstr>
: InstHexagon<outs, ins, asmstr, pattern, cstr, LD> {
: InstHexagon<outs, ins, asmstr, pattern, cstr, LD, TypeLD> {
bits<5> rd;
bits<5> rs;
bits<5> rt;
@ -68,7 +93,24 @@ class LDInstPost<dag outs, dag ins, string asmstr, list<dag> pattern,
// ST Instruction Class in V4 can take SLOT0 & SLOT1.
// Definition of the instruction class CHANGED from V2/V3 to V4.
class STInst<dag outs, dag ins, string asmstr, list<dag> pattern>
: InstHexagon<outs, ins, asmstr, pattern, "", ST> {
: InstHexagon<outs, ins, asmstr, pattern, "", ST, TypeST> {
bits<5> rd;
bits<5> rs;
bits<13> imm13;
}
class STInst2<dag outs, dag ins, string asmstr, list<dag> pattern>
: InstHexagon<outs, ins, asmstr, pattern, "", ST, TypeST> {
bits<5> rd;
bits<5> rs;
bits<13> imm13;
let mayStore = 1;
}
// SYSTEM Instruction Class in V4 can take SLOT0 only
// In V2/V3 we used ST for this but in v4 ST can take SLOT0 or SLOT1.
class SYSInst<dag outs, dag ins, string asmstr, list<dag> pattern>
: InstHexagon<outs, ins, asmstr, pattern, "", SYS, TypeSYSTEM> {
bits<5> rd;
bits<5> rs;
bits<13> imm13;
@ -79,7 +121,7 @@ class STInst<dag outs, dag ins, string asmstr, list<dag> pattern>
// Definition of the instruction class CHANGED from V2/V3 to V4.
class STInstPost<dag outs, dag ins, string asmstr, list<dag> pattern,
string cstr>
: InstHexagon<outs, ins, asmstr, pattern, cstr, ST> {
: InstHexagon<outs, ins, asmstr, pattern, cstr, ST, TypeST> {
bits<5> rd;
bits<5> rs;
bits<5> rt;
@ -89,7 +131,7 @@ class STInstPost<dag outs, dag ins, string asmstr, list<dag> pattern,
// ALU32 Instruction Class in V2/V3/V4.
// Definition of the instruction class NOT CHANGED.
class ALU32Type<dag outs, dag ins, string asmstr, list<dag> pattern>
: InstHexagon<outs, ins, asmstr, pattern, "", ALU32> {
: InstHexagon<outs, ins, asmstr, pattern, "", ALU32, TypeALU32> {
bits<5> rd;
bits<5> rs;
bits<5> rt;
@ -102,7 +144,17 @@ class ALU32Type<dag outs, dag ins, string asmstr, list<dag> pattern>
// Definition of the instruction class NOT CHANGED.
// Name of the Instruction Class changed from ALU64 to XTYPE from V2/V3 to V4.
class ALU64Type<dag outs, dag ins, string asmstr, list<dag> pattern>
: InstHexagon<outs, ins, asmstr, pattern, "", ALU64> {
: InstHexagon<outs, ins, asmstr, pattern, "", ALU64, TypeXTYPE> {
bits<5> rd;
bits<5> rs;
bits<5> rt;
bits<16> imm16;
bits<16> imm16_2;
}
class ALU64_acc<dag outs, dag ins, string asmstr, list<dag> pattern,
string cstr>
: InstHexagon<outs, ins, asmstr, pattern, cstr, ALU64, TypeXTYPE> {
bits<5> rd;
bits<5> rs;
bits<5> rt;
@ -115,7 +167,7 @@ class ALU64Type<dag outs, dag ins, string asmstr, list<dag> pattern>
// Definition of the instruction class NOT CHANGED.
// Name of the Instruction Class changed from M to XTYPE from V2/V3 to V4.
class MInst<dag outs, dag ins, string asmstr, list<dag> pattern>
: InstHexagon<outs, ins, asmstr, pattern, "", M> {
: InstHexagon<outs, ins, asmstr, pattern, "", M, TypeXTYPE> {
bits<5> rd;
bits<5> rs;
bits<5> rt;
@ -126,8 +178,8 @@ class MInst<dag outs, dag ins, string asmstr, list<dag> pattern>
// Definition of the instruction class NOT CHANGED.
// Name of the Instruction Class changed from M to XTYPE from V2/V3 to V4.
class MInst_acc<dag outs, dag ins, string asmstr, list<dag> pattern,
string cstr>
: InstHexagon<outs, ins, asmstr, pattern, cstr, M> {
string cstr>
: InstHexagon<outs, ins, asmstr, pattern, cstr, M, TypeXTYPE> {
bits<5> rd;
bits<5> rs;
bits<5> rt;
@ -138,9 +190,7 @@ class MInst_acc<dag outs, dag ins, string asmstr, list<dag> pattern,
// Definition of the instruction class NOT CHANGED.
// Name of the Instruction Class changed from S to XTYPE from V2/V3 to V4.
class SInst<dag outs, dag ins, string asmstr, list<dag> pattern>
//: InstHexagon<outs, ins, asmstr, pattern, cstr, !if(V4T, XTYPE_V4, M)> {
: InstHexagon<outs, ins, asmstr, pattern, "", S> {
// : InstHexagon<outs, ins, asmstr, pattern, "", S> {
: InstHexagon<outs, ins, asmstr, pattern, "", S, TypeXTYPE> {
bits<5> rd;
bits<5> rs;
bits<5> rt;
@ -151,8 +201,8 @@ class SInst<dag outs, dag ins, string asmstr, list<dag> pattern>
// Definition of the instruction class NOT CHANGED.
// Name of the Instruction Class changed from S to XTYPE from V2/V3 to V4.
class SInst_acc<dag outs, dag ins, string asmstr, list<dag> pattern,
string cstr>
: InstHexagon<outs, ins, asmstr, pattern, cstr, S> {
string cstr>
: InstHexagon<outs, ins, asmstr, pattern, cstr, S, TypeXTYPE> {
// : InstHexagon<outs, ins, asmstr, pattern, cstr, S> {
// : InstHexagon<outs, ins, asmstr, pattern, cstr, !if(V4T, XTYPE_V4, S)> {
bits<5> rd;
@ -163,14 +213,14 @@ class SInst_acc<dag outs, dag ins, string asmstr, list<dag> pattern,
// J Instruction Class in V2/V3/V4.
// Definition of the instruction class NOT CHANGED.
class JType<dag outs, dag ins, string asmstr, list<dag> pattern>
: InstHexagon<outs, ins, asmstr, pattern, "", J> {
: InstHexagon<outs, ins, asmstr, pattern, "", J, TypeJ> {
bits<16> imm16;
}
// JR Instruction Class in V2/V3/V4.
// Definition of the instruction class NOT CHANGED.
class JRType<dag outs, dag ins, string asmstr, list<dag> pattern>
: InstHexagon<outs, ins, asmstr, pattern, "", JR> {
: InstHexagon<outs, ins, asmstr, pattern, "", JR, TypeJR> {
bits<5> rs;
bits<5> pu; // Predicate register
}
@ -178,15 +228,22 @@ class JRType<dag outs, dag ins, string asmstr, list<dag> pattern>
// CR Instruction Class in V2/V3/V4.
// Definition of the instruction class NOT CHANGED.
class CRInst<dag outs, dag ins, string asmstr, list<dag> pattern>
: InstHexagon<outs, ins, asmstr, pattern, "", CR> {
: InstHexagon<outs, ins, asmstr, pattern, "", CR, TypeCR> {
bits<5> rs;
bits<10> imm10;
}
class Marker<dag outs, dag ins, string asmstr, list<dag> pattern>
: InstHexagon<outs, ins, asmstr, pattern, "", MARKER, TypeMARKER> {
let isCodeGenOnly = 1;
let isPseudo = 1;
}
class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
: InstHexagon<outs, ins, asmstr, pattern, "", PSEUDO>;
: InstHexagon<outs, ins, asmstr, pattern, "", PSEUDO, TypePSEUDO> {
let isCodeGenOnly = 1;
let isPseudo = 1;
}
//===----------------------------------------------------------------------===//
// Intruction Classes Definitions -
@ -222,6 +279,11 @@ class ALU64_rr<dag outs, dag ins, string asmstr, list<dag> pattern>
: ALU64Type<outs, ins, asmstr, pattern> {
}
class ALU64_ri<dag outs, dag ins, string asmstr, list<dag> pattern>
: ALU64Type<outs, ins, asmstr, pattern> {
let rt{0-4} = 0;
}
// J Type Instructions.
class JInst<dag outs, dag ins, string asmstr, list<dag> pattern>
: JType<outs, ins, asmstr, pattern> {
@ -239,12 +301,27 @@ class STInstPI<dag outs, dag ins, string asmstr, list<dag> pattern, string cstr>
let rt{0-4} = 0;
}
class STInst2PI<dag outs, dag ins, string asmstr, list<dag> pattern, string cstr>
: STInstPost<outs, ins, asmstr, pattern, cstr> {
let rt{0-4} = 0;
let mayStore = 1;
}
// Post increment LD Instruction.
class LDInstPI<dag outs, dag ins, string asmstr, list<dag> pattern, string cstr>
: LDInstPost<outs, ins, asmstr, pattern, cstr> {
let rt{0-4} = 0;
}
class LDInst2PI<dag outs, dag ins, string asmstr, list<dag> pattern, string cstr>
: LDInstPost<outs, ins, asmstr, pattern, cstr> {
let rt{0-4} = 0;
let mayLoad = 1;
}
//===----------------------------------------------------------------------===//
// V4 Instruction Format Definitions +
//===----------------------------------------------------------------------===//

View File

@ -11,11 +11,25 @@
//
//===----------------------------------------------------------------------===//
//----------------------------------------------------------------------------//
// Hexagon Intruction Flags +
//
// *** Must match BaseInfo.h ***
//----------------------------------------------------------------------------//
def TypeMEMOP : Type<9>;
def TypeNV : Type<10>;
def TypePREFIX : Type<30>;
//----------------------------------------------------------------------------//
// Intruction Classes Definitions +
//----------------------------------------------------------------------------//
//
// NV type instructions.
//
class NVInst_V4<dag outs, dag ins, string asmstr, list<dag> pattern>
: InstHexagon<outs, ins, asmstr, pattern, "", NV_V4> {
: InstHexagon<outs, ins, asmstr, pattern, "", NV_V4, TypeNV> {
bits<5> rd;
bits<5> rs;
bits<13> imm13;
@ -24,7 +38,7 @@ class NVInst_V4<dag outs, dag ins, string asmstr, list<dag> pattern>
// Definition of Post increment new value store.
class NVInstPost_V4<dag outs, dag ins, string asmstr, list<dag> pattern,
string cstr>
: InstHexagon<outs, ins, asmstr, pattern, cstr, NV_V4> {
: InstHexagon<outs, ins, asmstr, pattern, cstr, NV_V4, TypeNV> {
bits<5> rd;
bits<5> rs;
bits<5> rt;
@ -39,8 +53,15 @@ class NVInstPI_V4<dag outs, dag ins, string asmstr, list<dag> pattern,
}
class MEMInst_V4<dag outs, dag ins, string asmstr, list<dag> pattern>
: InstHexagon<outs, ins, asmstr, pattern, "", MEM_V4> {
: InstHexagon<outs, ins, asmstr, pattern, "", MEM_V4, TypeMEMOP> {
bits<5> rd;
bits<5> rs;
bits<6> imm6;
}
class Immext<dag outs, dag ins, string asmstr, list<dag> pattern>
: InstHexagon<outs, ins, asmstr, pattern, "", PREFIX, TypePREFIX> {
let isCodeGenOnly = 1;
bits<26> imm26;
}

File diff suppressed because it is too large Load Diff

View File

@ -160,10 +160,20 @@ public:
bool isS8_Immediate(const int value) const;
bool isS6_Immediate(const int value) const;
bool isSaveCalleeSavedRegsCall(const MachineInstr* MI) const;
bool isConditionalTransfer(const MachineInstr* MI) const;
bool isConditionalALU32 (const MachineInstr* MI) const;
bool isConditionalLoad (const MachineInstr* MI) const;
bool isConditionalStore(const MachineInstr* MI) const;
bool isDeallocRet(const MachineInstr *MI) const;
unsigned getInvertedPredicatedOpcode(const int Opc) const;
bool isExtendable(const MachineInstr* MI) const;
bool isExtended(const MachineInstr* MI) const;
bool isPostIncrement(const MachineInstr* MI) const;
bool isNewValueStore(const MachineInstr* MI) const;
bool isNewValueJump(const MachineInstr* MI) const;
unsigned getImmExtForm(const MachineInstr* MI) const;
unsigned getNormalBranchForm(const MachineInstr* MI) const;
private:
int getMatchingCondBranchOpcode(int Opc, bool sense) const;

View File

@ -875,19 +875,19 @@ def LDrid_indexed : LDInst<(outs DoubleRegs:$dst),
s11_3ImmPred:$offset)))]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDrid_GP : LDInst<(outs DoubleRegs:$dst),
def LDrid_GP : LDInst2<(outs DoubleRegs:$dst),
(ins globaladdress:$global, u16Imm:$offset),
"$dst=memd(#$global+$offset)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDd_GP : LDInst<(outs DoubleRegs:$dst),
def LDd_GP : LDInst2<(outs DoubleRegs:$dst),
(ins globaladdress:$global),
"$dst=memd(#$global)",
[]>;
let isPredicable = 1, mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in
def POST_LDrid : LDInstPI<(outs DoubleRegs:$dst, IntRegs:$dst2),
def POST_LDrid : LDInst2PI<(outs DoubleRegs:$dst, IntRegs:$dst2),
(ins IntRegs:$src1, s4Imm:$offset),
"$dst = memd($src1++#$offset)",
[],
@ -895,64 +895,64 @@ def POST_LDrid : LDInstPI<(outs DoubleRegs:$dst, IntRegs:$dst2),
// Load doubleword conditionally.
let mayLoad = 1, neverHasSideEffects = 1 in
def LDrid_cPt : LDInst<(outs DoubleRegs:$dst),
def LDrid_cPt : LDInst2<(outs DoubleRegs:$dst),
(ins PredRegs:$src1, MEMri:$addr),
"if ($src1) $dst = memd($addr)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDrid_cNotPt : LDInst<(outs DoubleRegs:$dst),
def LDrid_cNotPt : LDInst2<(outs DoubleRegs:$dst),
(ins PredRegs:$src1, MEMri:$addr),
"if (!$src1) $dst = memd($addr)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDrid_indexed_cPt : LDInst<(outs DoubleRegs:$dst),
def LDrid_indexed_cPt : LDInst2<(outs DoubleRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, u6_3Imm:$src3),
"if ($src1) $dst=memd($src2+#$src3)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDrid_indexed_cNotPt : LDInst<(outs DoubleRegs:$dst),
def LDrid_indexed_cNotPt : LDInst2<(outs DoubleRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, u6_3Imm:$src3),
"if (!$src1) $dst=memd($src2+#$src3)",
[]>;
let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in
def POST_LDrid_cPt : LDInstPI<(outs DoubleRegs:$dst1, IntRegs:$dst2),
def POST_LDrid_cPt : LDInst2PI<(outs DoubleRegs:$dst1, IntRegs:$dst2),
(ins PredRegs:$src1, IntRegs:$src2, s4_3Imm:$src3),
"if ($src1) $dst1 = memd($src2++#$src3)",
[],
"$src2 = $dst2">;
let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in
def POST_LDrid_cNotPt : LDInstPI<(outs DoubleRegs:$dst1, IntRegs:$dst2),
def POST_LDrid_cNotPt : LDInst2PI<(outs DoubleRegs:$dst1, IntRegs:$dst2),
(ins PredRegs:$src1, IntRegs:$src2, s4_3Imm:$src3),
"if (!$src1) $dst1 = memd($src2++#$src3)",
[],
"$src2 = $dst2">;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDrid_cdnPt : LDInst<(outs DoubleRegs:$dst),
def LDrid_cdnPt : LDInst2<(outs DoubleRegs:$dst),
(ins PredRegs:$src1, MEMri:$addr),
"if ($src1.new) $dst = memd($addr)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDrid_cdnNotPt : LDInst<(outs DoubleRegs:$dst),
def LDrid_cdnNotPt : LDInst2<(outs DoubleRegs:$dst),
(ins PredRegs:$src1, MEMri:$addr),
"if (!$src1.new) $dst = memd($addr)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDrid_indexed_cdnPt : LDInst<(outs DoubleRegs:$dst),
def LDrid_indexed_cdnPt : LDInst2<(outs DoubleRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, u6_3Imm:$src3),
"if ($src1.new) $dst=memd($src2+#$src3)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDrid_indexed_cdnNotPt : LDInst<(outs DoubleRegs:$dst),
def LDrid_indexed_cdnNotPt : LDInst2<(outs DoubleRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, u6_3Imm:$src3),
"if (!$src1.new) $dst=memd($src2+#$src3)",
[]>;
@ -988,25 +988,25 @@ def LDrib_ae_indexed : LDInst<(outs IntRegs:$dst),
s11_0ImmPred:$offset)))]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDrib_GP : LDInst<(outs IntRegs:$dst),
def LDrib_GP : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global, u16Imm:$offset),
"$dst=memb(#$global+$offset)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDb_GP : LDInst<(outs IntRegs:$dst),
def LDb_GP : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global),
"$dst=memb(#$global)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDub_GP : LDInst<(outs IntRegs:$dst),
def LDub_GP : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global),
"$dst=memub(#$global)",
[]>;
let isPredicable = 1, mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in
def POST_LDrib : LDInstPI<(outs IntRegs:$dst, IntRegs:$dst2),
def POST_LDrib : LDInst2PI<(outs IntRegs:$dst, IntRegs:$dst2),
(ins IntRegs:$src1, s4Imm:$offset),
"$dst = memb($src1++#$offset)",
[],
@ -1014,63 +1014,63 @@ def POST_LDrib : LDInstPI<(outs IntRegs:$dst, IntRegs:$dst2),
// Load byte conditionally.
let mayLoad = 1, neverHasSideEffects = 1 in
def LDrib_cPt : LDInst<(outs IntRegs:$dst),
def LDrib_cPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, MEMri:$addr),
"if ($src1) $dst = memb($addr)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDrib_cNotPt : LDInst<(outs IntRegs:$dst),
def LDrib_cNotPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, MEMri:$addr),
"if (!$src1) $dst = memb($addr)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDrib_indexed_cPt : LDInst<(outs IntRegs:$dst),
def LDrib_indexed_cPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3),
"if ($src1) $dst = memb($src2+#$src3)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDrib_indexed_cNotPt : LDInst<(outs IntRegs:$dst),
def LDrib_indexed_cNotPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3),
"if (!$src1) $dst = memb($src2+#$src3)",
[]>;
let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in
def POST_LDrib_cPt : LDInstPI<(outs IntRegs:$dst1, IntRegs:$dst2),
def POST_LDrib_cPt : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
(ins PredRegs:$src1, IntRegs:$src2, s4_0Imm:$src3),
"if ($src1) $dst1 = memb($src2++#$src3)",
[],
"$src2 = $dst2">;
let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in
def POST_LDrib_cNotPt : LDInstPI<(outs IntRegs:$dst1, IntRegs:$dst2),
def POST_LDrib_cNotPt : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
(ins PredRegs:$src1, IntRegs:$src2, s4_0Imm:$src3),
"if (!$src1) $dst1 = memb($src2++#$src3)",
[],
"$src2 = $dst2">;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDrib_cdnPt : LDInst<(outs IntRegs:$dst),
def LDrib_cdnPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, MEMri:$addr),
"if ($src1.new) $dst = memb($addr)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDrib_cdnNotPt : LDInst<(outs IntRegs:$dst),
def LDrib_cdnNotPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, MEMri:$addr),
"if (!$src1.new) $dst = memb($addr)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDrib_indexed_cdnPt : LDInst<(outs IntRegs:$dst),
def LDrib_indexed_cdnPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3),
"if ($src1.new) $dst = memb($src2+#$src3)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDrib_indexed_cdnNotPt : LDInst<(outs IntRegs:$dst),
def LDrib_indexed_cdnNotPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3),
"if (!$src1.new) $dst = memb($src2+#$src3)",
[]>;
@ -1103,26 +1103,26 @@ def LDrih_ae_indexed : LDInst<(outs IntRegs:$dst),
s11_1ImmPred:$offset)))] >;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDrih_GP : LDInst<(outs IntRegs:$dst),
def LDrih_GP : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global, u16Imm:$offset),
"$dst=memh(#$global+$offset)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDh_GP : LDInst<(outs IntRegs:$dst),
def LDh_GP : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global),
"$dst=memh(#$global)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDuh_GP : LDInst<(outs IntRegs:$dst),
def LDuh_GP : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global),
"$dst=memuh(#$global)",
[]>;
let isPredicable = 1, mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in
def POST_LDrih : LDInstPI<(outs IntRegs:$dst, IntRegs:$dst2),
def POST_LDrih : LDInst2PI<(outs IntRegs:$dst, IntRegs:$dst2),
(ins IntRegs:$src1, s4Imm:$offset),
"$dst = memh($src1++#$offset)",
[],
@ -1130,63 +1130,63 @@ def POST_LDrih : LDInstPI<(outs IntRegs:$dst, IntRegs:$dst2),
// Load halfword conditionally.
let mayLoad = 1, neverHasSideEffects = 1 in
def LDrih_cPt : LDInst<(outs IntRegs:$dst),
def LDrih_cPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, MEMri:$addr),
"if ($src1) $dst = memh($addr)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDrih_cNotPt : LDInst<(outs IntRegs:$dst),
def LDrih_cNotPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, MEMri:$addr),
"if (!$src1) $dst = memh($addr)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDrih_indexed_cPt : LDInst<(outs IntRegs:$dst),
def LDrih_indexed_cPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3),
"if ($src1) $dst = memh($src2+#$src3)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDrih_indexed_cNotPt : LDInst<(outs IntRegs:$dst),
def LDrih_indexed_cNotPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3),
"if (!$src1) $dst = memh($src2+#$src3)",
[]>;
let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in
def POST_LDrih_cPt : LDInstPI<(outs IntRegs:$dst1, IntRegs:$dst2),
def POST_LDrih_cPt : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
(ins PredRegs:$src1, IntRegs:$src2, s4_1Imm:$src3),
"if ($src1) $dst1 = memh($src2++#$src3)",
[],
"$src2 = $dst2">;
let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in
def POST_LDrih_cNotPt : LDInstPI<(outs IntRegs:$dst1, IntRegs:$dst2),
def POST_LDrih_cNotPt : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
(ins PredRegs:$src1, IntRegs:$src2, s4_1Imm:$src3),
"if (!$src1) $dst1 = memh($src2++#$src3)",
[],
"$src2 = $dst2">;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDrih_cdnPt : LDInst<(outs IntRegs:$dst),
def LDrih_cdnPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, MEMri:$addr),
"if ($src1.new) $dst = memh($addr)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDrih_cdnNotPt : LDInst<(outs IntRegs:$dst),
def LDrih_cdnNotPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, MEMri:$addr),
"if (!$src1.new) $dst = memh($addr)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDrih_indexed_cdnPt : LDInst<(outs IntRegs:$dst),
def LDrih_indexed_cdnPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3),
"if ($src1.new) $dst = memh($src2+#$src3)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDrih_indexed_cdnNotPt : LDInst<(outs IntRegs:$dst),
def LDrih_indexed_cdnNotPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3),
"if (!$src1.new) $dst = memh($src2+#$src3)",
[]>;
@ -1232,13 +1232,13 @@ def LDriub_ae_indexed : LDInst<(outs IntRegs:$dst),
s11_0ImmPred:$offset)))]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDriub_GP : LDInst<(outs IntRegs:$dst),
def LDriub_GP : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global, u16Imm:$offset),
"$dst=memub(#$global+$offset)",
[]>;
let isPredicable = 1, mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in
def POST_LDriub : LDInstPI<(outs IntRegs:$dst, IntRegs:$dst2),
def POST_LDriub : LDInst2PI<(outs IntRegs:$dst, IntRegs:$dst2),
(ins IntRegs:$src1, s4Imm:$offset),
"$dst = memub($src1++#$offset)",
[],
@ -1246,63 +1246,63 @@ def POST_LDriub : LDInstPI<(outs IntRegs:$dst, IntRegs:$dst2),
// Load unsigned byte conditionally.
let mayLoad = 1, neverHasSideEffects = 1 in
def LDriub_cPt : LDInst<(outs IntRegs:$dst),
def LDriub_cPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, MEMri:$addr),
"if ($src1) $dst = memub($addr)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDriub_cNotPt : LDInst<(outs IntRegs:$dst),
def LDriub_cNotPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, MEMri:$addr),
"if (!$src1) $dst = memub($addr)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDriub_indexed_cPt : LDInst<(outs IntRegs:$dst),
def LDriub_indexed_cPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3),
"if ($src1) $dst = memub($src2+#$src3)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDriub_indexed_cNotPt : LDInst<(outs IntRegs:$dst),
def LDriub_indexed_cNotPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3),
"if (!$src1) $dst = memub($src2+#$src3)",
[]>;
let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in
def POST_LDriub_cPt : LDInstPI<(outs IntRegs:$dst1, IntRegs:$dst2),
def POST_LDriub_cPt : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
(ins PredRegs:$src1, IntRegs:$src2, s4_0Imm:$src3),
"if ($src1) $dst1 = memub($src2++#$src3)",
[],
"$src2 = $dst2">;
let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in
def POST_LDriub_cNotPt : LDInstPI<(outs IntRegs:$dst1, IntRegs:$dst2),
def POST_LDriub_cNotPt : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
(ins PredRegs:$src1, IntRegs:$src2, s4_0Imm:$src3),
"if (!$src1) $dst1 = memub($src2++#$src3)",
[],
"$src2 = $dst2">;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDriub_cdnPt : LDInst<(outs IntRegs:$dst),
def LDriub_cdnPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, MEMri:$addr),
"if ($src1.new) $dst = memub($addr)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDriub_cdnNotPt : LDInst<(outs IntRegs:$dst),
def LDriub_cdnNotPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, MEMri:$addr),
"if (!$src1.new) $dst = memub($addr)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDriub_indexed_cdnPt : LDInst<(outs IntRegs:$dst),
def LDriub_indexed_cdnPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3),
"if ($src1.new) $dst = memub($src2+#$src3)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDriub_indexed_cdnNotPt : LDInst<(outs IntRegs:$dst),
def LDriub_indexed_cdnNotPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3),
"if (!$src1.new) $dst = memub($src2+#$src3)",
[]>;
@ -1337,13 +1337,13 @@ def LDriuh_ae_indexed : LDInst<(outs IntRegs:$dst),
s11_1ImmPred:$offset)))] >;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDriuh_GP : LDInst<(outs IntRegs:$dst),
def LDriuh_GP : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global, u16Imm:$offset),
"$dst=memuh(#$global+$offset)",
[]>;
let isPredicable = 1, mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in
def POST_LDriuh : LDInstPI<(outs IntRegs:$dst, IntRegs:$dst2),
def POST_LDriuh : LDInst2PI<(outs IntRegs:$dst, IntRegs:$dst2),
(ins IntRegs:$src1, s4Imm:$offset),
"$dst = memuh($src1++#$offset)",
[],
@ -1351,63 +1351,63 @@ def POST_LDriuh : LDInstPI<(outs IntRegs:$dst, IntRegs:$dst2),
// Load unsigned halfword conditionally.
let mayLoad = 1, neverHasSideEffects = 1 in
def LDriuh_cPt : LDInst<(outs IntRegs:$dst),
def LDriuh_cPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, MEMri:$addr),
"if ($src1) $dst = memuh($addr)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDriuh_cNotPt : LDInst<(outs IntRegs:$dst),
def LDriuh_cNotPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, MEMri:$addr),
"if (!$src1) $dst = memuh($addr)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDriuh_indexed_cPt : LDInst<(outs IntRegs:$dst),
def LDriuh_indexed_cPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3),
"if ($src1) $dst = memuh($src2+#$src3)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDriuh_indexed_cNotPt : LDInst<(outs IntRegs:$dst),
def LDriuh_indexed_cNotPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3),
"if (!$src1) $dst = memuh($src2+#$src3)",
[]>;
let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in
def POST_LDriuh_cPt : LDInstPI<(outs IntRegs:$dst1, IntRegs:$dst2),
def POST_LDriuh_cPt : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
(ins PredRegs:$src1, IntRegs:$src2, s4_1Imm:$src3),
"if ($src1) $dst1 = memuh($src2++#$src3)",
[],
"$src2 = $dst2">;
let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in
def POST_LDriuh_cNotPt : LDInstPI<(outs IntRegs:$dst1, IntRegs:$dst2),
def POST_LDriuh_cNotPt : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
(ins PredRegs:$src1, IntRegs:$src2, s4_1Imm:$src3),
"if (!$src1) $dst1 = memuh($src2++#$src3)",
[],
"$src2 = $dst2">;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDriuh_cdnPt : LDInst<(outs IntRegs:$dst),
def LDriuh_cdnPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, MEMri:$addr),
"if ($src1.new) $dst = memuh($addr)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDriuh_cdnNotPt : LDInst<(outs IntRegs:$dst),
def LDriuh_cdnNotPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, MEMri:$addr),
"if (!$src1.new) $dst = memuh($addr)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDriuh_indexed_cdnPt : LDInst<(outs IntRegs:$dst),
def LDriuh_indexed_cdnPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3),
"if ($src1.new) $dst = memuh($src2+#$src3)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDriuh_indexed_cdnNotPt : LDInst<(outs IntRegs:$dst),
def LDriuh_indexed_cdnNotPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3),
"if (!$src1.new) $dst = memuh($src2+#$src3)",
[]>;
@ -1421,7 +1421,7 @@ def LDriw : LDInst<(outs IntRegs:$dst),
// Load predicate.
let mayLoad = 1, Defs = [R10,R11] in
def LDriw_pred : LDInst<(outs PredRegs:$dst),
def LDriw_pred : LDInst2<(outs PredRegs:$dst),
(ins MEMri:$addr),
"Error; should not emit",
[]>;
@ -1435,19 +1435,19 @@ def LDriw_indexed : LDInst<(outs IntRegs:$dst),
s11_2ImmPred:$offset)))]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDriw_GP : LDInst<(outs IntRegs:$dst),
def LDriw_GP : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global, u16Imm:$offset),
"$dst=memw(#$global+$offset)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDw_GP : LDInst<(outs IntRegs:$dst),
def LDw_GP : LDInst2<(outs IntRegs:$dst),
(ins globaladdress:$global),
"$dst=memw(#$global)",
[]>;
let isPredicable = 1, mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in
def POST_LDriw : LDInstPI<(outs IntRegs:$dst, IntRegs:$dst2),
def POST_LDriw : LDInst2PI<(outs IntRegs:$dst, IntRegs:$dst2),
(ins IntRegs:$src1, s4Imm:$offset),
"$dst = memw($src1++#$offset)",
[],
@ -1456,70 +1456,70 @@ def POST_LDriw : LDInstPI<(outs IntRegs:$dst, IntRegs:$dst2),
// Load word conditionally.
let mayLoad = 1, neverHasSideEffects = 1 in
def LDriw_cPt : LDInst<(outs IntRegs:$dst),
def LDriw_cPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, MEMri:$addr),
"if ($src1) $dst = memw($addr)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDriw_cNotPt : LDInst<(outs IntRegs:$dst),
def LDriw_cNotPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, MEMri:$addr),
"if (!$src1) $dst = memw($addr)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDriw_indexed_cPt : LDInst<(outs IntRegs:$dst),
def LDriw_indexed_cPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, u6_2Imm:$src3),
"if ($src1) $dst=memw($src2+#$src3)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDriw_indexed_cNotPt : LDInst<(outs IntRegs:$dst),
def LDriw_indexed_cNotPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, u6_2Imm:$src3),
"if (!$src1) $dst=memw($src2+#$src3)",
[]>;
let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in
def POST_LDriw_cPt : LDInstPI<(outs IntRegs:$dst1, IntRegs:$dst2),
def POST_LDriw_cPt : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
(ins PredRegs:$src1, IntRegs:$src2, s4_2Imm:$src3),
"if ($src1) $dst1 = memw($src2++#$src3)",
[],
"$src2 = $dst2">;
let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in
def POST_LDriw_cNotPt : LDInstPI<(outs IntRegs:$dst1, IntRegs:$dst2),
def POST_LDriw_cNotPt : LDInst2PI<(outs IntRegs:$dst1, IntRegs:$dst2),
(ins PredRegs:$src1, IntRegs:$src2, s4_2Imm:$src3),
"if (!$src1) $dst1 = memw($src2++#$src3)",
[],
"$src2 = $dst2">;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDriw_cdnPt : LDInst<(outs IntRegs:$dst),
def LDriw_cdnPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, MEMri:$addr),
"if ($src1.new) $dst = memw($addr)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDriw_cdnNotPt : LDInst<(outs IntRegs:$dst),
def LDriw_cdnNotPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, MEMri:$addr),
"if (!$src1.new) $dst = memw($addr)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDriw_indexed_cdnPt : LDInst<(outs IntRegs:$dst),
def LDriw_indexed_cdnPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, u6_2Imm:$src3),
"if ($src1.new) $dst=memw($src2+#$src3)",
[]>;
let mayLoad = 1, neverHasSideEffects = 1 in
def LDriw_indexed_cdnNotPt : LDInst<(outs IntRegs:$dst),
def LDriw_indexed_cdnNotPt : LDInst2<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, u6_2Imm:$src3),
"if (!$src1.new) $dst=memw($src2+#$src3)",
[]>;
// Deallocate stack frame.
let Defs = [R29, R30, R31], Uses = [R29], neverHasSideEffects = 1 in {
def DEALLOCFRAME : LDInst<(outs), (ins i32imm:$amt1),
def DEALLOCFRAME : LDInst2<(outs), (ins i32imm:$amt1),
"deallocframe",
[]>;
}
@ -1741,8 +1741,8 @@ def STrid_indexed : STInst<(outs),
[(store DoubleRegs:$src3,
(add IntRegs:$src1, s11_3ImmPred:$src2))]>;
let mayStore = 1, neverHasSideEffects = 1 in
def STrid_GP : STInst<(outs),
let neverHasSideEffects = 1 in
def STrid_GP : STInst2<(outs),
(ins globaladdress:$global, u16Imm:$offset, DoubleRegs:$src),
"memd(#$global+$offset) = $src",
[]>;
@ -1758,30 +1758,30 @@ def POST_STdri : STInstPI<(outs IntRegs:$dst),
// Store doubleword conditionally.
// if ([!]Pv) memd(Rs+#u6:3)=Rtt
// if (Pv) memd(Rs+#u6:3)=Rtt
let AddedComplexity = 10, mayStore = 1, neverHasSideEffects = 1 in
def STrid_cPt : STInst<(outs),
let AddedComplexity = 10, neverHasSideEffects = 1 in
def STrid_cPt : STInst2<(outs),
(ins PredRegs:$src1, MEMri:$addr, DoubleRegs:$src2),
"if ($src1) memd($addr) = $src2",
[]>;
// if (!Pv) memd(Rs+#u6:3)=Rtt
let AddedComplexity = 10, mayStore = 1, neverHasSideEffects = 1 in
def STrid_cNotPt : STInst<(outs),
let AddedComplexity = 10, neverHasSideEffects = 1 in
def STrid_cNotPt : STInst2<(outs),
(ins PredRegs:$src1, MEMri:$addr, DoubleRegs:$src2),
"if (!$src1) memd($addr) = $src2",
[]>;
// if (Pv) memd(Rs+#u6:3)=Rtt
let AddedComplexity = 10, mayStore = 1, neverHasSideEffects = 1 in
def STrid_indexed_cPt : STInst<(outs),
let AddedComplexity = 10, neverHasSideEffects = 1 in
def STrid_indexed_cPt : STInst2<(outs),
(ins PredRegs:$src1, IntRegs:$src2, u6_3Imm:$src3,
DoubleRegs:$src4),
"if ($src1) memd($src2+#$src3) = $src4",
[]>;
// if (!Pv) memd(Rs+#u6:3)=Rtt
let AddedComplexity = 10, mayStore = 1, neverHasSideEffects = 1 in
def STrid_indexed_cNotPt : STInst<(outs),
let AddedComplexity = 10, neverHasSideEffects = 1 in
def STrid_indexed_cNotPt : STInst2<(outs),
(ins PredRegs:$src1, IntRegs:$src2, u6_3Imm:$src3,
DoubleRegs:$src4),
"if (!$src1) memd($src2+#$src3) = $src4",
@ -1789,8 +1789,8 @@ def STrid_indexed_cNotPt : STInst<(outs),
// if ([!]Pv) memd(Rx++#s4:3)=Rtt
// if (Pv) memd(Rx++#s4:3)=Rtt
let AddedComplexity = 10, mayStore = 1, neverHasSideEffects = 1 in
def POST_STdri_cPt : STInstPI<(outs IntRegs:$dst),
let AddedComplexity = 10, neverHasSideEffects = 1 in
def POST_STdri_cPt : STInst2PI<(outs IntRegs:$dst),
(ins PredRegs:$src1, DoubleRegs:$src2, IntRegs:$src3,
s4_3Imm:$offset),
"if ($src1) memd($src3++#$offset) = $src2",
@ -1798,9 +1798,9 @@ def POST_STdri_cPt : STInstPI<(outs IntRegs:$dst),
"$src3 = $dst">;
// if (!Pv) memd(Rx++#s4:3)=Rtt
let AddedComplexity = 10, mayStore = 1, neverHasSideEffects = 1,
let AddedComplexity = 10, neverHasSideEffects = 1,
isPredicated = 1 in
def POST_STdri_cNotPt : STInstPI<(outs IntRegs:$dst),
def POST_STdri_cNotPt : STInst2PI<(outs IntRegs:$dst),
(ins PredRegs:$src1, DoubleRegs:$src2, IntRegs:$src3,
s4_3Imm:$offset),
"if (!$src1) memd($src3++#$offset) = $src2",
@ -1824,14 +1824,14 @@ def STrib_indexed : STInst<(outs),
s11_0ImmPred:$src2))]>;
// memb(gp+#u16:0)=Rt
let mayStore = 1, neverHasSideEffects = 1 in
def STrib_GP : STInst<(outs),
let neverHasSideEffects = 1 in
def STrib_GP : STInst2<(outs),
(ins globaladdress:$global, u16Imm:$offset, IntRegs:$src),
"memb(#$global+$offset) = $src",
[]>;
let mayStore = 1, neverHasSideEffects = 1 in
def STb_GP : STInst<(outs),
let neverHasSideEffects = 1 in
def STb_GP : STInst2<(outs),
(ins globaladdress:$global, IntRegs:$src),
"memb(#$global) = $src",
[]>;
@ -1850,44 +1850,44 @@ def POST_STbri : STInstPI<(outs IntRegs:$dst), (ins IntRegs:$src1,
// Store byte conditionally.
// if ([!]Pv) memb(Rs+#u6:0)=Rt
// if (Pv) memb(Rs+#u6:0)=Rt
let mayStore = 1, neverHasSideEffects = 1 in
def STrib_cPt : STInst<(outs),
let neverHasSideEffects = 1 in
def STrib_cPt : STInst2<(outs),
(ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2),
"if ($src1) memb($addr) = $src2",
[]>;
// if (!Pv) memb(Rs+#u6:0)=Rt
let mayStore = 1, neverHasSideEffects = 1 in
def STrib_cNotPt : STInst<(outs),
let neverHasSideEffects = 1 in
def STrib_cNotPt : STInst2<(outs),
(ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2),
"if (!$src1) memb($addr) = $src2",
[]>;
// if (Pv) memb(Rs+#u6:0)=Rt
let mayStore = 1, neverHasSideEffects = 1 in
def STrib_indexed_cPt : STInst<(outs),
let neverHasSideEffects = 1 in
def STrib_indexed_cPt : STInst2<(outs),
(ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3, IntRegs:$src4),
"if ($src1) memb($src2+#$src3) = $src4",
[]>;
// if (!Pv) memb(Rs+#u6:0)=Rt
let mayStore = 1, neverHasSideEffects = 1 in
def STrib_indexed_cNotPt : STInst<(outs),
let neverHasSideEffects = 1 in
def STrib_indexed_cNotPt : STInst2<(outs),
(ins PredRegs:$src1, IntRegs:$src2, u6_0Imm:$src3, IntRegs:$src4),
"if (!$src1) memb($src2+#$src3) = $src4",
[]>;
// if ([!]Pv) memb(Rx++#s4:0)=Rt
// if (Pv) memb(Rx++#s4:0)=Rt
let mayStore = 1, hasCtrlDep = 1, isPredicated = 1 in
def POST_STbri_cPt : STInstPI<(outs IntRegs:$dst),
let hasCtrlDep = 1, isPredicated = 1 in
def POST_STbri_cPt : STInst2PI<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, s4_0Imm:$offset),
"if ($src1) memb($src3++#$offset) = $src2",
[],"$src3 = $dst">;
// if (!Pv) memb(Rx++#s4:0)=Rt
let mayStore = 1, hasCtrlDep = 1, isPredicated = 1 in
def POST_STbri_cNotPt : STInstPI<(outs IntRegs:$dst),
let hasCtrlDep = 1, isPredicated = 1 in
def POST_STbri_cNotPt : STInst2PI<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, s4_0Imm:$offset),
"if (!$src1) memb($src3++#$offset) = $src2",
[],"$src3 = $dst">;
@ -1909,14 +1909,14 @@ def STrih_indexed : STInst<(outs),
[(truncstorei16 IntRegs:$src3, (add IntRegs:$src1,
s11_1ImmPred:$src2))]>;
let mayStore = 1, neverHasSideEffects = 1 in
def STrih_GP : STInst<(outs),
let neverHasSideEffects = 1 in
def STrih_GP : STInst2<(outs),
(ins globaladdress:$global, u16Imm:$offset, IntRegs:$src),
"memh(#$global+$offset) = $src",
[]>;
let mayStore = 1, neverHasSideEffects = 1 in
def STh_GP : STInst<(outs),
let neverHasSideEffects = 1 in
def STh_GP : STInst2<(outs),
(ins globaladdress:$global, IntRegs:$src),
"memh(#$global) = $src",
[]>;
@ -1935,44 +1935,44 @@ def POST_SThri : STInstPI<(outs IntRegs:$dst),
// Store halfword conditionally.
// if ([!]Pv) memh(Rs+#u6:1)=Rt
// if (Pv) memh(Rs+#u6:1)=Rt
let mayStore = 1, neverHasSideEffects = 1 in
def STrih_cPt : STInst<(outs),
let neverHasSideEffects = 1 in
def STrih_cPt : STInst2<(outs),
(ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2),
"if ($src1) memh($addr) = $src2",
[]>;
// if (!Pv) memh(Rs+#u6:1)=Rt
let mayStore = 1, neverHasSideEffects = 1 in
def STrih_cNotPt : STInst<(outs),
let neverHasSideEffects = 1 in
def STrih_cNotPt : STInst2<(outs),
(ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2),
"if (!$src1) memh($addr) = $src2",
[]>;
// if (Pv) memh(Rs+#u6:1)=Rt
let mayStore = 1, neverHasSideEffects = 1 in
def STrih_indexed_cPt : STInst<(outs),
let neverHasSideEffects = 1 in
def STrih_indexed_cPt : STInst2<(outs),
(ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3, IntRegs:$src4),
"if ($src1) memh($src2+#$src3) = $src4",
[]>;
// if (!Pv) memh(Rs+#u6:1)=Rt
let mayStore = 1, neverHasSideEffects = 1 in
def STrih_indexed_cNotPt : STInst<(outs),
let neverHasSideEffects = 1 in
def STrih_indexed_cNotPt : STInst2<(outs),
(ins PredRegs:$src1, IntRegs:$src2, u6_1Imm:$src3, IntRegs:$src4),
"if (!$src1) memh($src2+#$src3) = $src4",
[]>;
// if ([!]Pv) memh(Rx++#s4:1)=Rt
// if (Pv) memh(Rx++#s4:1)=Rt
let mayStore = 1, hasCtrlDep = 1, isPredicated = 1 in
def POST_SThri_cPt : STInstPI<(outs IntRegs:$dst),
let hasCtrlDep = 1, isPredicated = 1 in
def POST_SThri_cPt : STInst2PI<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, s4_1Imm:$offset),
"if ($src1) memh($src3++#$offset) = $src2",
[],"$src3 = $dst">;
// if (!Pv) memh(Rx++#s4:1)=Rt
let mayStore = 1, hasCtrlDep = 1, isPredicated = 1 in
def POST_SThri_cNotPt : STInstPI<(outs IntRegs:$dst),
let hasCtrlDep = 1, isPredicated = 1 in
def POST_SThri_cNotPt : STInst2PI<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, s4_1Imm:$offset),
"if (!$src1) memh($src3++#$offset) = $src2",
[],"$src3 = $dst">;
@ -1981,7 +1981,7 @@ def POST_SThri_cNotPt : STInstPI<(outs IntRegs:$dst),
// Store word.
// Store predicate.
let Defs = [R10,R11] in
def STriw_pred : STInst<(outs),
def STriw_pred : STInst2<(outs),
(ins MEMri:$addr, PredRegs:$src1),
"Error; should not emit",
[]>;
@ -1999,8 +1999,8 @@ def STriw_indexed : STInst<(outs),
"memw($src1+#$src2) = $src3",
[(store IntRegs:$src3, (add IntRegs:$src1, s11_2ImmPred:$src2))]>;
let mayStore = 1, neverHasSideEffects = 1 in
def STriw_GP : STInst<(outs),
let neverHasSideEffects = 1 in
def STriw_GP : STInst2<(outs),
(ins globaladdress:$global, u16Imm:$offset, IntRegs:$src),
"memw(#$global+$offset) = $src",
[]>;
@ -2016,44 +2016,44 @@ def POST_STwri : STInstPI<(outs IntRegs:$dst),
// Store word conditionally.
// if ([!]Pv) memw(Rs+#u6:2)=Rt
// if (Pv) memw(Rs+#u6:2)=Rt
let mayStore = 1, neverHasSideEffects = 1 in
def STriw_cPt : STInst<(outs),
let neverHasSideEffects = 1 in
def STriw_cPt : STInst2<(outs),
(ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2),
"if ($src1) memw($addr) = $src2",
[]>;
// if (!Pv) memw(Rs+#u6:2)=Rt
let mayStore = 1, neverHasSideEffects = 1 in
def STriw_cNotPt : STInst<(outs),
let neverHasSideEffects = 1 in
def STriw_cNotPt : STInst2<(outs),
(ins PredRegs:$src1, MEMri:$addr, IntRegs:$src2),
"if (!$src1) memw($addr) = $src2",
[]>;
// if (Pv) memw(Rs+#u6:2)=Rt
let mayStore = 1, neverHasSideEffects = 1 in
def STriw_indexed_cPt : STInst<(outs),
let neverHasSideEffects = 1 in
def STriw_indexed_cPt : STInst2<(outs),
(ins PredRegs:$src1, IntRegs:$src2, u6_2Imm:$src3, IntRegs:$src4),
"if ($src1) memw($src2+#$src3) = $src4",
[]>;
// if (!Pv) memw(Rs+#u6:2)=Rt
let mayStore = 1, neverHasSideEffects = 1 in
def STriw_indexed_cNotPt : STInst<(outs),
let neverHasSideEffects = 1 in
def STriw_indexed_cNotPt : STInst2<(outs),
(ins PredRegs:$src1, IntRegs:$src2, u6_2Imm:$src3, IntRegs:$src4),
"if (!$src1) memw($src2+#$src3) = $src4",
[]>;
// if ([!]Pv) memw(Rx++#s4:2)=Rt
// if (Pv) memw(Rx++#s4:2)=Rt
let mayStore = 1, hasCtrlDep = 1, isPredicated = 1 in
def POST_STwri_cPt : STInstPI<(outs IntRegs:$dst),
let hasCtrlDep = 1, isPredicated = 1 in
def POST_STwri_cPt : STInst2PI<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, s4_2Imm:$offset),
"if ($src1) memw($src3++#$offset) = $src2",
[],"$src3 = $dst">;
// if (!Pv) memw(Rx++#s4:2)=Rt
let mayStore = 1, hasCtrlDep = 1, isPredicated = 1 in
def POST_STwri_cNotPt : STInstPI<(outs IntRegs:$dst),
let hasCtrlDep = 1, isPredicated = 1 in
def POST_STwri_cNotPt : STInst2PI<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, s4_2Imm:$offset),
"if (!$src1) memw($src3++#$offset) = $src2",
[],"$src3 = $dst">;
@ -2062,7 +2062,7 @@ def POST_STwri_cNotPt : STInstPI<(outs IntRegs:$dst),
// Allocate stack frame.
let Defs = [R29, R30], Uses = [R31, R30], neverHasSideEffects = 1 in {
def ALLOCFRAME : STInst<(outs),
def ALLOCFRAME : STInst2<(outs),
(ins i32imm:$amt),
"allocframe(#$amt)",
[]>;
@ -2232,7 +2232,7 @@ def HexagonBARRIER: SDNode<"HexagonISD::BARRIER", SDHexagonBARRIER,
[SDNPHasChain]>;
let hasSideEffects = 1 in
def BARRIER : STInst<(outs), (ins),
def BARRIER : STInst2<(outs), (ins),
"barrier",
[(HexagonBARRIER)]>;
@ -2324,35 +2324,35 @@ def CONST32 : LDInst<(outs IntRegs:$dst), (ins globaladdress:$global),
(load (HexagonCONST32 tglobaltlsaddr:$global)))]>;
let isReMaterializable = 1, isMoveImm = 1 in
def CONST32_set : LDInst<(outs IntRegs:$dst), (ins globaladdress:$global),
def CONST32_set : LDInst2<(outs IntRegs:$dst), (ins globaladdress:$global),
"$dst = CONST32(#$global)",
[(set IntRegs:$dst,
(HexagonCONST32 tglobaladdr:$global))]>;
let isReMaterializable = 1, isMoveImm = 1 in
def CONST32_set_jt : LDInst<(outs IntRegs:$dst), (ins jumptablebase:$jt),
def CONST32_set_jt : LDInst2<(outs IntRegs:$dst), (ins jumptablebase:$jt),
"$dst = CONST32(#$jt)",
[(set IntRegs:$dst,
(HexagonCONST32 tjumptable:$jt))]>;
let isReMaterializable = 1, isMoveImm = 1 in
def CONST32GP_set : LDInst<(outs IntRegs:$dst), (ins globaladdress:$global),
def CONST32GP_set : LDInst2<(outs IntRegs:$dst), (ins globaladdress:$global),
"$dst = CONST32(#$global)",
[(set IntRegs:$dst,
(HexagonCONST32_GP tglobaladdr:$global))]>;
let isReMaterializable = 1, isMoveImm = 1 in
def CONST32_Int_Real : LDInst<(outs IntRegs:$dst), (ins i32imm:$global),
def CONST32_Int_Real : LDInst2<(outs IntRegs:$dst), (ins i32imm:$global),
"$dst = CONST32(#$global)",
[(set IntRegs:$dst, imm:$global) ]>;
let isReMaterializable = 1, isMoveImm = 1 in
def CONST32_Label : LDInst<(outs IntRegs:$dst), (ins bblabel:$label),
def CONST32_Label : LDInst2<(outs IntRegs:$dst), (ins bblabel:$label),
"$dst = CONST32($label)",
[(set IntRegs:$dst, (HexagonCONST32 bbl:$label))]>;
let isReMaterializable = 1, isMoveImm = 1 in
def CONST64_Int_Real : LDInst<(outs DoubleRegs:$dst), (ins i64imm:$global),
def CONST64_Int_Real : LDInst2<(outs DoubleRegs:$dst), (ins i64imm:$global),
"$dst = CONST64(#$global)",
[(set DoubleRegs:$dst, imm:$global) ]>;
@ -3046,3 +3046,7 @@ include "HexagonInstrInfoV3.td"
//===----------------------------------------------------------------------===//
include "HexagonInstrInfoV4.td"
//===----------------------------------------------------------------------===//
// V4 Instructions -
//===----------------------------------------------------------------------===//

View File

@ -41,10 +41,11 @@ let isCall = 1, neverHasSideEffects = 1,
}
// Jump to address from register
// if(p?.new) jumpr:t r?
let isReturn = 1, isTerminator = 1, isBarrier = 1,
Defs = [PC], Uses = [R31] in {
def JMPR_cPnewt: JRInst<(outs), (ins PredRegs:$src1, IntRegs:$src2),
def JMPR_cdnPt_V3: JRInst<(outs), (ins PredRegs:$src1, IntRegs:$src2),
"if ($src1.new) jumpr:t $src2",
[]>, Requires<[HasV3T]>;
}
@ -52,7 +53,7 @@ let isReturn = 1, isTerminator = 1, isBarrier = 1,
// if (!p?.new) jumpr:t r?
let isReturn = 1, isTerminator = 1, isBarrier = 1,
Defs = [PC], Uses = [R31] in {
def JMPR_cNotPnewt: JRInst<(outs), (ins PredRegs:$src1, IntRegs:$src2),
def JMPR_cdnNotPt_V3: JRInst<(outs), (ins PredRegs:$src1, IntRegs:$src2),
"if (!$src1.new) jumpr:t $src2",
[]>, Requires<[HasV3T]>;
}
@ -61,7 +62,7 @@ let isReturn = 1, isTerminator = 1, isBarrier = 1,
// if(p?.new) jumpr:nt r?
let isReturn = 1, isTerminator = 1, isBarrier = 1,
Defs = [PC], Uses = [R31] in {
def JMPR_cPnewNt: JRInst<(outs), (ins PredRegs:$src1, IntRegs:$src2),
def JMPR_cdnPnt: JRInst<(outs), (ins PredRegs:$src1, IntRegs:$src2),
"if ($src1.new) jumpr:nt $src2",
[]>, Requires<[HasV3T]>;
}
@ -69,7 +70,7 @@ let isReturn = 1, isTerminator = 1, isBarrier = 1,
// if (!p?.new) jumpr:nt r?
let isReturn = 1, isTerminator = 1, isBarrier = 1,
Defs = [PC], Uses = [R31] in {
def JMPR_cNotPnewNt: JRInst<(outs), (ins PredRegs:$src1, IntRegs:$src2),
def JMPR_cdnNotPnt: JRInst<(outs), (ins PredRegs:$src1, IntRegs:$src2),
"if (!$src1.new) jumpr:nt $src2",
[]>, Requires<[HasV3T]>;
}
@ -86,20 +87,22 @@ let AddedComplexity = 200 in
def MAXw_dd : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
DoubleRegs:$src2),
"$dst = max($src2, $src1)",
[(set DoubleRegs:$dst, (select (i1 (setlt DoubleRegs:$src2,
DoubleRegs:$src1)),
DoubleRegs:$src1,
DoubleRegs:$src2))]>,
[(set (i64 DoubleRegs:$dst),
(i64 (select (i1 (setlt (i64 DoubleRegs:$src2),
(i64 DoubleRegs:$src1))),
(i64 DoubleRegs:$src1),
(i64 DoubleRegs:$src2))))]>,
Requires<[HasV3T]>;
let AddedComplexity = 200 in
def MINw_dd : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
DoubleRegs:$src2),
"$dst = min($src2, $src1)",
[(set DoubleRegs:$dst, (select (i1 (setgt DoubleRegs:$src2,
DoubleRegs:$src1)),
DoubleRegs:$src1,
DoubleRegs:$src2))]>,
[(set (i64 DoubleRegs:$dst),
(i64 (select (i1 (setgt (i64 DoubleRegs:$src2),
(i64 DoubleRegs:$src1))),
(i64 DoubleRegs:$src1),
(i64 DoubleRegs:$src2))))]>,
Requires<[HasV3T]>;
//===----------------------------------------------------------------------===//
@ -109,25 +112,25 @@ Requires<[HasV3T]>;
//def : Pat <(brcond (i1 (seteq IntRegs:$src1, 0)), bb:$offset),
// (JMP_RegEzt IntRegs:$src1, bb:$offset)>, Requires<[HasV3T]>;
//def : Pat <(brcond (i1 (seteq (i32 IntRegs:$src1), 0)), bb:$offset),
// (JMP_RegEzt (i32 IntRegs:$src1), bb:$offset)>, Requires<[HasV3T]>;
//def : Pat <(brcond (i1 (setne IntRegs:$src1, 0)), bb:$offset),
// (JMP_RegNzt IntRegs:$src1, bb:$offset)>, Requires<[HasV3T]>;
//def : Pat <(brcond (i1 (setne (i32 IntRegs:$src1), 0)), bb:$offset),
// (JMP_RegNzt (i32 IntRegs:$src1), bb:$offset)>, Requires<[HasV3T]>;
//def : Pat <(brcond (i1 (setle IntRegs:$src1, 0)), bb:$offset),
// (JMP_RegLezt IntRegs:$src1, bb:$offset)>, Requires<[HasV3T]>;
//def : Pat <(brcond (i1 (setle (i32 IntRegs:$src1), 0)), bb:$offset),
// (JMP_RegLezt (i32 IntRegs:$src1), bb:$offset)>, Requires<[HasV3T]>;
//def : Pat <(brcond (i1 (setge IntRegs:$src1, 0)), bb:$offset),
// (JMP_RegGezt IntRegs:$src1, bb:$offset)>, Requires<[HasV3T]>;
//def : Pat <(brcond (i1 (setge (i32 IntRegs:$src1), 0)), bb:$offset),
// (JMP_RegGezt (i32 IntRegs:$src1), bb:$offset)>, Requires<[HasV3T]>;
//def : Pat <(brcond (i1 (setgt IntRegs:$src1, -1)), bb:$offset),
// (JMP_RegGezt IntRegs:$src1, bb:$offset)>, Requires<[HasV3T]>;
//def : Pat <(brcond (i1 (setgt (i32 IntRegs:$src1), -1)), bb:$offset),
// (JMP_RegGezt (i32 IntRegs:$src1), bb:$offset)>, Requires<[HasV3T]>;
// Map call instruction
def : Pat<(call IntRegs:$dst),
(CALLRv3 IntRegs:$dst)>, Requires<[HasV3T]>;
def : Pat<(call (i32 IntRegs:$dst)),
(CALLRv3 (i32 IntRegs:$dst))>, Requires<[HasV3T]>;
def : Pat<(call tglobaladdr:$dst),
(CALLv3 tglobaladdr:$dst)>, Requires<[HasV3T]>;
def : Pat<(call texternalsym:$dst),

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,41 @@
//===- 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 annotation.
//
//===----------------------------------------------------------------------===//
#ifndef HEXAGONMCINST_H
#define HEXAGONMCINST_H
#include "llvm/MC/MCInst.h"
#include "llvm/CodeGen/MachineInstr.h"
namespace llvm {
class HexagonMCInst: public MCInst {
// Packet start and end markers
unsigned startPacket: 1, endPacket: 1;
const MachineInstr *MachineI;
public:
explicit HexagonMCInst(): MCInst(),
startPacket(0), endPacket(0) {}
const MachineInstr* getMI() const { return MachineI; };
void setMI(const MachineInstr *MI) { MachineI = MI; };
bool isStartPacket() const { return (startPacket); };
bool isEndPacket() const { return (endPacket); };
void setStartPacket(bool yes) { startPacket = yes; };
void setEndPacket(bool yes) { endPacket = yes; };
};
}
#endif

View File

@ -49,7 +49,7 @@ void llvm::HexagonLowerToMC(const MachineInstr* MI, MCInst& MCI,
switch (MO.getType()) {
default:
MI->dump();
assert(0 && "unknown operand type");
llvm_unreachable("unknown operand type");
case MachineOperand::MO_Register:
// Ignore all implicit register operands.
if (MO.isImplicit()) continue;

View File

@ -13,7 +13,6 @@ def LSUNIT : FuncUnit;
def MUNIT : FuncUnit;
def SUNIT : FuncUnit;
// Itinerary classes
def ALU32 : InstrItinClass;
def ALU64 : InstrItinClass;
@ -24,23 +23,25 @@ def LD : InstrItinClass;
def M : InstrItinClass;
def ST : InstrItinClass;
def S : InstrItinClass;
def SYS : InstrItinClass;
def MARKER : InstrItinClass;
def PSEUDO : InstrItinClass;
def HexagonItineraries :
ProcessorItineraries<[LUNIT, LSUNIT, MUNIT, SUNIT], [], [
InstrItinData<ALU32 , [InstrStage<1, [LUNIT, LSUNIT, MUNIT, SUNIT]>]>,
InstrItinData<ALU64 , [InstrStage<1, [MUNIT, SUNIT]>]>,
InstrItinData<CR , [InstrStage<1, [SUNIT]>]>,
InstrItinData<J , [InstrStage<1, [SUNIT, MUNIT]>]>,
InstrItinData<JR , [InstrStage<1, [MUNIT]>]>,
InstrItinData<LD , [InstrStage<1, [LUNIT, LSUNIT]>]>,
InstrItinData<M , [InstrStage<1, [MUNIT, SUNIT]>]>,
InstrItinData<ST , [InstrStage<1, [LSUNIT]>]>,
InstrItinData<S , [InstrStage<1, [SUNIT, MUNIT]>]>,
InstrItinData<PSEUDO , [InstrStage<1, [LUNIT, LSUNIT, MUNIT, SUNIT]>]>
]>;
ProcessorItineraries<[LUNIT, LSUNIT, MUNIT, SUNIT], [], [
InstrItinData<ALU32 , [InstrStage<1, [LUNIT, LSUNIT, MUNIT, SUNIT]>]>,
InstrItinData<ALU64 , [InstrStage<1, [MUNIT, SUNIT]>]>,
InstrItinData<CR , [InstrStage<1, [SUNIT]>]>,
InstrItinData<J , [InstrStage<1, [SUNIT, MUNIT]>]>,
InstrItinData<JR , [InstrStage<1, [MUNIT]>]>,
InstrItinData<LD , [InstrStage<1, [LUNIT, LSUNIT]>]>,
InstrItinData<M , [InstrStage<1, [MUNIT, SUNIT]>]>,
InstrItinData<ST , [InstrStage<1, [LSUNIT]>]>,
InstrItinData<S , [InstrStage<1, [SUNIT, MUNIT]>]>,
InstrItinData<SYS , [InstrStage<1, [LSUNIT]>]>,
InstrItinData<MARKER , [InstrStage<1, [LUNIT, LSUNIT, MUNIT, SUNIT]>]>,
InstrItinData<PSEUDO , [InstrStage<1, [LUNIT, LSUNIT, MUNIT, SUNIT]>]>
]>;
//===----------------------------------------------------------------------===//
// V4 Machine Info +

View File

@ -23,7 +23,6 @@
// | SLOT3 | XTYPE ALU32 J CR |
// |===========|==================================================|
// Functional Units.
def SLOT0 : FuncUnit;
def SLOT1 : FuncUnit;
@ -34,22 +33,26 @@ def SLOT3 : FuncUnit;
def NV_V4 : InstrItinClass;
def MEM_V4 : InstrItinClass;
// ALU64/M/S Instruction classes of V2 are collectively knownn as XTYPE in V4.
def PREFIX : InstrItinClass;
def HexagonItinerariesV4 : ProcessorItineraries<
[SLOT0, SLOT1, SLOT2, SLOT3], [], [
InstrItinData<LD , [InstrStage<1, [SLOT0, SLOT1]>]>,
InstrItinData<ST , [InstrStage<1, [SLOT0, SLOT1]>]>,
InstrItinData<ALU32 , [InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>]>,
InstrItinData<NV_V4 , [InstrStage<1, [SLOT0]>]>,
InstrItinData<MEM_V4 , [InstrStage<1, [SLOT0]>]>,
InstrItinData<J , [InstrStage<1, [SLOT2, SLOT3]>]>,
InstrItinData<JR , [InstrStage<1, [SLOT2]>]>,
InstrItinData<CR , [InstrStage<1, [SLOT3]>]>,
InstrItinData<PSEUDO , [InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>]>,
InstrItinData<ALU64 , [InstrStage<1, [SLOT2, SLOT3]>]>,
InstrItinData<M , [InstrStage<1, [SLOT2, SLOT3]>]>,
InstrItinData<S , [InstrStage<1, [SLOT2, SLOT3]>]>
]>;
def HexagonItinerariesV4 :
ProcessorItineraries<[SLOT0, SLOT1, SLOT2, SLOT3], [], [
InstrItinData<ALU32 , [InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>]>,
InstrItinData<ALU64 , [InstrStage<1, [SLOT2, SLOT3]>]>,
InstrItinData<CR , [InstrStage<1, [SLOT3]>]>,
InstrItinData<J , [InstrStage<1, [SLOT2, SLOT3]>]>,
InstrItinData<JR , [InstrStage<1, [SLOT2]>]>,
InstrItinData<LD , [InstrStage<1, [SLOT0, SLOT1]>]>,
InstrItinData<M , [InstrStage<1, [SLOT2, SLOT3]>]>,
InstrItinData<ST , [InstrStage<1, [SLOT0, SLOT1]>]>,
InstrItinData<S , [InstrStage<1, [SLOT2, SLOT3]>]>,
InstrItinData<SYS , [InstrStage<1, [SLOT0]>]>,
InstrItinData<NV_V4 , [InstrStage<1, [SLOT0]>]>,
InstrItinData<MEM_V4 , [InstrStage<1, [SLOT0]>]>,
InstrItinData<MARKER , [InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>]>,
InstrItinData<PREFIX , [InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>]>,
InstrItinData<PSEUDO , [InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>]>
]>;
//===----------------------------------------------------------------------===//
// Hexagon V4 Resource Definitions -

View File

@ -138,5 +138,8 @@ bool HexagonPassConfig::addPreEmitPass() {
// Split up TFRcondsets into conditional transfers.
PM.add(createHexagonSplitTFRCondSets(getHexagonTargetMachine()));
// Create Packets.
PM.add(createHexagonPacketizer());
return false;
}

File diff suppressed because it is too large Load Diff

View File

@ -15,6 +15,7 @@
#include "Hexagon.h"
#include "HexagonAsmPrinter.h"
#include "HexagonInstPrinter.h"
#include "HexagonMCInst.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCExpr.h"
@ -37,20 +38,50 @@ StringRef HexagonInstPrinter::getRegName(unsigned RegNo) const {
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 packetPadding[] = " ";
const char startPacket = '{',
endPacket = '}';
// TODO: add outer HW loop when it's supported too.
if (MI->getOpcode() == Hexagon::ENDLOOP0) {
MCInst Nop;
// Ending a harware loop is different from ending an regular packet.
assert(MI->isEndPacket() && "Loop end must also end the packet");
O << packetPadding << startPacket << '\n';
Nop.setOpcode(Hexagon::NOP);
printInstruction(&Nop, O);
O << packetPadding << endPacket;
if (MI->isStartPacket()) {
// 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());
printInst (&Nop, O, NoAnnot);
}
// Close the packet.
if (MI->isEndPacket())
O << packetPadding << endPacket;
printInstruction(MI, O);
}
else {
// Prefix the insn opening the packet.
if (MI->isStartPacket())
O << packetPadding << startPacket << '\n';
printInstruction(MI, O);
// Suffix the insn closing the packet.
if (MI->isEndPacket())
// 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;
}
printInstruction(MI, O);
printAnnotation(O, Annot);
}
@ -65,22 +96,22 @@ void HexagonInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
} else if(MO.isImm()) {
printImmOperand(MI, OpNo, O);
} else {
assert(false && "Unknown operand");
llvm_unreachable("Unknown operand");
}
}
void HexagonInstPrinter::printImmOperand
(const MCInst *MI, unsigned OpNo, raw_ostream &O) const {
void HexagonInstPrinter::printImmOperand(const MCInst *MI, unsigned OpNo,
raw_ostream &O) const {
O << MI->getOperand(OpNo).getImm();
}
void HexagonInstPrinter::printExtOperand(const MCInst *MI, unsigned OpNo,
raw_ostream &O) const {
raw_ostream &O) const {
O << MI->getOperand(OpNo).getImm();
}
void HexagonInstPrinter::printUnsignedImmOperand
(const MCInst *MI, unsigned OpNo, raw_ostream &O) const {
void HexagonInstPrinter::printUnsignedImmOperand(const MCInst *MI, unsigned OpNo,
raw_ostream &O) const {
O << MI->getOperand(OpNo).getImm();
}
@ -89,13 +120,13 @@ void HexagonInstPrinter::printNegImmOperand(const MCInst *MI, unsigned OpNo,
O << -MI->getOperand(OpNo).getImm();
}
void HexagonInstPrinter::printNOneImmOperand
(const MCInst *MI, unsigned OpNo, raw_ostream &O) const {
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 {
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);
@ -103,8 +134,8 @@ void HexagonInstPrinter::printMEMriOperand
O << " + #" << MO1.getImm();
}
void HexagonInstPrinter::printFrameIndexOperand
(const MCInst *MI, unsigned OpNo, raw_ostream &O) const {
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);

View File

@ -14,6 +14,7 @@
#ifndef HEXAGONINSTPRINTER_H
#define HEXAGONINSTPRINTER_H
#include "HexagonMCInst.h"
#include "llvm/MC/MCInstPrinter.h"
namespace llvm {
@ -25,6 +26,7 @@ namespace llvm {
: MCInstPrinter(MAI, MII, MRI) {}
virtual void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot);
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;

View File

@ -23,14 +23,41 @@ namespace llvm {
/// instruction info tracks.
///
namespace HexagonII {
// *** The code below must match HexagonInstrFormat*.td *** //
// Insn types.
// *** Must match HexagonInstrFormat*.td ***
enum Type {
TypePSEUDO = 0,
TypeALU32 = 1,
TypeCR = 2,
TypeJR = 3,
TypeJ = 4,
TypeLD = 5,
TypeST = 6,
TypeSYSTEM = 7,
TypeXTYPE = 8,
TypeMEMOP = 9,
TypeNV = 10,
TypePREFIX = 30, // Such as extenders.
TypeMARKER = 31 // Such as end of a HW loop.
};
// MCInstrDesc TSFlags
// *** Must match HexagonInstrFormat*.td ***
enum {
// This 5-bit field describes the insn type.
TypePos = 0,
TypeMask = 0x1f,
// Solo instructions.
SoloPos = 5,
SoloMask = 0x1,
// Predicated instructions.
PredicatedPos = 1,
PredicatedPos = 6,
PredicatedMask = 0x1
};

View File

@ -0,0 +1,19 @@
; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s
; Check that we generate dual stores in one packet in V4
; CHECK: {
; CHECK-NEXT: memw(r{{[0-9]+}} + #{{[0-9]+}} = r{{[0-9]+}}
; CHECK-NEXT: memw(r{{[0-9]+}} + #{{[0-9]+}} = r{{[0-9]+}}
; CHECK-NEXT: }
@Reg = global i32 0, align 4
define i32 @main() nounwind {
entry:
%number= alloca i32, align 4
store i32 500000, i32* %number, align 4
%number1= alloca i32, align 4
store i32 100000, i32* %number1, align 4
ret i32 0
}

View File

@ -0,0 +1,16 @@
; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s
; Check that we generate fused logical and with shift instruction.
; CHECK: r{{[0-9]+}} = and(#15, lsr(r{{[0-9]+}}, #{{[0-9]+}})
define i32 @main(i16* %a, i16* %b) nounwind {
entry:
%0 = load i16* %a, align 2
%conv1 = sext i16 %0 to i32
%shr1 = ashr i32 %conv1, 3
%and1 = and i32 %shr1, 15
%conv2 = trunc i32 %and1 to i16
store i16 %conv2, i16* %b, align 2
ret i32 0
}

View File

@ -0,0 +1,22 @@
; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s
; Check that we generate new value store packet in V4
@i = global i32 0, align 4
@j = global i32 10, align 4
@k = global i32 100, align 4
define i32 @main() nounwind {
entry:
; CHECK: memw(r{{[0-9]+}} + #{{[0-9]+}}) = r{{[0-9]+}}.new
%number1 = alloca i32, align 4
%number2 = alloca i32, align 4
%number3 = alloca i32, align 4
%0 = load i32 * @i, align 4
store i32 %0, i32* %number1, align 4
%1 = load i32 * @j, align 4
store i32 %1, i32* %number2, align 4
%2 = load i32 * @k, align 4
store i32 %2, i32* %number3, align 4
ret i32 %0
}