//===----------------------------------------------------------------------===//
#include "HexagonInstrInfo.h"
+#include "Hexagon.h"
#include "HexagonRegisterInfo.h"
#include "HexagonSubtarget.h"
-#include "Hexagon.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/DFAPacketizer.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineMemOperand.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
+#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
-#define GET_INSTRINFO_CTOR
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "hexagon-instrinfo"
+
+#define GET_INSTRINFO_CTOR_DTOR
#define GET_INSTRMAP_INFO
#include "HexagonGenInstrInfo.inc"
#include "HexagonGenDFAPacketizer.inc"
-using namespace llvm;
-
///
/// Constants for Hexagon instructions.
///
const int Hexagon_MEMB_AUTOINC_MAX = 7;
const int Hexagon_MEMB_AUTOINC_MIN = -8;
+// Pin the vtable to this file.
+void HexagonInstrInfo::anchor() {}
HexagonInstrInfo::HexagonInstrInfo(HexagonSubtarget &ST)
: HexagonGenInstrInfo(Hexagon::ADJCALLSTACKDOWN, Hexagon::ADJCALLSTACKUP),
- RI(ST, *this), Subtarget(ST) {
+ RI(ST), Subtarget(ST) {
}
case Hexagon::LDriw:
case Hexagon::LDrid:
case Hexagon::LDrih:
- case Hexagon::LDrib:
- case Hexagon::LDriub:
+ case Hexagon::L2_loadrb_io:
+ case Hexagon::L2_loadrub_io:
if (MI->getOperand(2).isFI() &&
MI->getOperand(1).isImm() && (MI->getOperand(1).getImm() == 0)) {
FrameIndex = MI->getOperand(2).getIndex();
const SmallVectorImpl<MachineOperand> &Cond,
DebugLoc DL) const{
- int BOpc = Hexagon::JMP;
- int BccOpc = Hexagon::JMP_c;
+ int BOpc = Hexagon::J2_jump;
+ int BccOpc = Hexagon::J2_jumpt;
assert(TBB && "InsertBranch must not be told to insert a fallthrough");
int regPos = 0;
// Check if ReverseBranchCondition has asked to reverse this branch
// If we want to reverse the branch an odd number of times, we want
- // JMP_cNot.
+ // JMP_f.
if (!Cond.empty() && Cond[0].isImm() && Cond[0].getImm() == 0) {
- BccOpc = Hexagon::JMP_cNot;
+ BccOpc = Hexagon::J2_jumpf;
regPos = 1;
}
- if (FBB == 0) {
+ if (!FBB) {
if (Cond.empty()) {
// Due to a bug in TailMerging/CFG Optimization, we need to add a
// special case handling of a predicated jump followed by an
if (isPredicated(Term) && !AnalyzeBranch(MBB, NewTBB, NewFBB, Cond,
false)) {
MachineBasicBlock *NextBB =
- llvm::next(MachineFunction::iterator(&MBB));
+ std::next(MachineFunction::iterator(&MBB));
if (NewTBB == NextBB) {
ReverseBranchCondition(Cond);
RemoveBranch(MBB);
- return InsertBranch(MBB, TBB, 0, Cond, DL);
+ return InsertBranch(MBB, TBB, nullptr, Cond, DL);
}
}
BuildMI(&MBB, DL, get(BOpc)).addMBB(TBB);
MachineBasicBlock *&FBB,
SmallVectorImpl<MachineOperand> &Cond,
bool AllowModify) const {
- TBB = NULL;
- FBB = NULL;
+ TBB = nullptr;
+ FBB = nullptr;
// If the block has no terminators, it just falls into the block after it.
- MachineBasicBlock::iterator I = MBB.end();
- if (I == MBB.begin())
+ MachineBasicBlock::instr_iterator I = MBB.instr_end();
+ if (I == MBB.instr_begin())
return false;
// A basic block may looks like this:
--I;
if (I->isEHLabel())
return true;
- } while (I != MBB.begin());
+ } while (I != MBB.instr_begin());
- I = MBB.end();
+ I = MBB.instr_end();
--I;
while (I->isDebugValue()) {
- if (I == MBB.begin())
+ if (I == MBB.instr_begin())
+ return false;
+ --I;
+ }
+
+ // Delete the JMP if it's equivalent to a fall-through.
+ if (AllowModify && I->getOpcode() == Hexagon::J2_jump &&
+ MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
+ DEBUG(dbgs()<< "\nErasing the jump to successor block\n";);
+ I->eraseFromParent();
+ I = MBB.instr_end();
+ if (I == MBB.instr_begin())
return false;
--I;
}
// Get the last instruction in the block.
MachineInstr *LastInst = I;
+ MachineInstr *SecondLastInst = nullptr;
+ // Find one more terminator if present.
+ do {
+ if (&*I != LastInst && !I->isBundle() && isUnpredicatedTerminator(I)) {
+ if (!SecondLastInst)
+ SecondLastInst = I;
+ else
+ // This is a third branch.
+ return true;
+ }
+ if (I == MBB.instr_begin())
+ break;
+ --I;
+ } while(I);
+
+ int LastOpcode = LastInst->getOpcode();
+
+ bool LastOpcodeHasJMP_c = PredOpcodeHasJMP_c(LastOpcode);
+ bool LastOpcodeHasNot = PredOpcodeHasNot(LastOpcode);
// If there is only one terminator instruction, process it.
- if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
- if (LastInst->getOpcode() == Hexagon::JMP) {
+ if (LastInst && !SecondLastInst) {
+ if (LastOpcode == Hexagon::J2_jump) {
TBB = LastInst->getOperand(0).getMBB();
return false;
}
- if (LastInst->getOpcode() == Hexagon::JMP_c) {
- // Block ends with fall-through true condbranch.
- TBB = LastInst->getOperand(1).getMBB();
+ if (LastOpcode == Hexagon::ENDLOOP0) {
+ TBB = LastInst->getOperand(0).getMBB();
Cond.push_back(LastInst->getOperand(0));
return false;
}
- if (LastInst->getOpcode() == Hexagon::JMP_cNot) {
- // Block ends with fall-through false condbranch.
+ if (LastOpcodeHasJMP_c) {
TBB = LastInst->getOperand(1).getMBB();
- Cond.push_back(MachineOperand::CreateImm(0));
+ if (LastOpcodeHasNot) {
+ Cond.push_back(MachineOperand::CreateImm(0));
+ }
Cond.push_back(LastInst->getOperand(0));
return false;
}
return true;
}
- // Get the instruction before it if it's a terminator.
- MachineInstr *SecondLastInst = I;
+ int SecLastOpcode = SecondLastInst->getOpcode();
- // If there are three terminators, we don't know what sort of block this is.
- if (SecondLastInst && I != MBB.begin() &&
- isUnpredicatedTerminator(--I))
- return true;
-
- // If the block ends with Hexagon::BRCOND and Hexagon:JMP, handle it.
- if (((SecondLastInst->getOpcode() == Hexagon::BRCOND) ||
- (SecondLastInst->getOpcode() == Hexagon::JMP_c)) &&
- LastInst->getOpcode() == Hexagon::JMP) {
+ bool SecLastOpcodeHasJMP_c = PredOpcodeHasJMP_c(SecLastOpcode);
+ bool SecLastOpcodeHasNot = PredOpcodeHasNot(SecLastOpcode);
+ if (SecLastOpcodeHasJMP_c && (LastOpcode == Hexagon::J2_jump)) {
TBB = SecondLastInst->getOperand(1).getMBB();
- Cond.push_back(SecondLastInst->getOperand(0));
- FBB = LastInst->getOperand(0).getMBB();
- return false;
- }
-
- // If the block ends with Hexagon::JMP_cNot and Hexagon:JMP, handle it.
- if ((SecondLastInst->getOpcode() == Hexagon::JMP_cNot) &&
- LastInst->getOpcode() == Hexagon::JMP) {
- TBB = SecondLastInst->getOperand(1).getMBB();
- Cond.push_back(MachineOperand::CreateImm(0));
+ if (SecLastOpcodeHasNot)
+ Cond.push_back(MachineOperand::CreateImm(0));
Cond.push_back(SecondLastInst->getOperand(0));
FBB = LastInst->getOperand(0).getMBB();
return false;
// If the block ends with two Hexagon:JMPs, handle it. The second one is not
// executed, so remove it.
- if (SecondLastInst->getOpcode() == Hexagon::JMP &&
- LastInst->getOpcode() == Hexagon::JMP) {
+ if (SecLastOpcode == Hexagon::J2_jump && LastOpcode == Hexagon::J2_jump) {
TBB = SecondLastInst->getOperand(0).getMBB();
I = LastInst;
if (AllowModify)
return false;
}
+ // If the block ends with an ENDLOOP, and JMP, handle it.
+ if (SecLastOpcode == Hexagon::ENDLOOP0 &&
+ LastOpcode == Hexagon::J2_jump) {
+ TBB = SecondLastInst->getOperand(0).getMBB();
+ Cond.push_back(SecondLastInst->getOperand(0));
+ FBB = LastInst->getOperand(0).getMBB();
+ return false;
+ }
+
// Otherwise, can't handle this.
return true;
}
unsigned HexagonInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
- int BOpc = Hexagon::JMP;
- int BccOpc = Hexagon::JMP_c;
- int BccOpcNot = Hexagon::JMP_cNot;
+ int BOpc = Hexagon::J2_jump;
+ int BccOpc = Hexagon::J2_jumpt;
+ int BccOpcNot = Hexagon::J2_jumpf;
MachineBasicBlock::iterator I = MBB.end();
if (I == MBB.begin()) return 0;
}
+/// \brief For a comparison instruction, return the source registers in
+/// \p SrcReg and \p SrcReg2 if having two register operands, and the value it
+/// compares against in CmpValue. Return true if the comparison instruction
+/// can be analyzed.
+bool HexagonInstrInfo::analyzeCompare(const MachineInstr *MI,
+ unsigned &SrcReg, unsigned &SrcReg2,
+ int &Mask, int &Value) const {
+ unsigned Opc = MI->getOpcode();
+
+ // Set mask and the first source register.
+ switch (Opc) {
+ case Hexagon::C2_cmpeqp:
+ case Hexagon::C2_cmpeqi:
+ case Hexagon::C2_cmpeq:
+ case Hexagon::C2_cmpgtp:
+ case Hexagon::C2_cmpgtup:
+ case Hexagon::C2_cmpgtui:
+ case Hexagon::C2_cmpgtu:
+ case Hexagon::C2_cmpgti:
+ case Hexagon::C2_cmpgt:
+ SrcReg = MI->getOperand(1).getReg();
+ Mask = ~0;
+ break;
+ case Hexagon::CMPbEQri_V4:
+ case Hexagon::CMPbEQrr_sbsb_V4:
+ case Hexagon::CMPbEQrr_ubub_V4:
+ case Hexagon::CMPbGTUri_V4:
+ case Hexagon::CMPbGTUrr_V4:
+ case Hexagon::CMPbGTrr_V4:
+ SrcReg = MI->getOperand(1).getReg();
+ Mask = 0xFF;
+ break;
+ case Hexagon::CMPhEQri_V4:
+ case Hexagon::CMPhEQrr_shl_V4:
+ case Hexagon::CMPhEQrr_xor_V4:
+ case Hexagon::CMPhGTUri_V4:
+ case Hexagon::CMPhGTUrr_V4:
+ case Hexagon::CMPhGTrr_shl_V4:
+ SrcReg = MI->getOperand(1).getReg();
+ Mask = 0xFFFF;
+ break;
+ }
+
+ // Set the value/second source register.
+ switch (Opc) {
+ case Hexagon::C2_cmpeqp:
+ case Hexagon::C2_cmpeq:
+ case Hexagon::C2_cmpgtp:
+ case Hexagon::C2_cmpgtup:
+ case Hexagon::C2_cmpgtu:
+ case Hexagon::C2_cmpgt:
+ case Hexagon::CMPbEQrr_sbsb_V4:
+ case Hexagon::CMPbEQrr_ubub_V4:
+ case Hexagon::CMPbGTUrr_V4:
+ case Hexagon::CMPbGTrr_V4:
+ case Hexagon::CMPhEQrr_shl_V4:
+ case Hexagon::CMPhEQrr_xor_V4:
+ case Hexagon::CMPhGTUrr_V4:
+ case Hexagon::CMPhGTrr_shl_V4:
+ SrcReg2 = MI->getOperand(2).getReg();
+ return true;
+
+ case Hexagon::C2_cmpeqi:
+ case Hexagon::C2_cmpgtui:
+ case Hexagon::C2_cmpgti:
+ case Hexagon::CMPbEQri_V4:
+ case Hexagon::CMPbGTUri_V4:
+ case Hexagon::CMPhEQri_V4:
+ case Hexagon::CMPhGTUri_V4:
+ SrcReg2 = 0;
+ Value = MI->getOperand(2).getImm();
+ return true;
+ }
+
+ return false;
+}
+
+
void HexagonInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I, DebugLoc DL,
unsigned DestReg, unsigned SrcReg,
bool KillSrc) const {
if (Hexagon::IntRegsRegClass.contains(SrcReg, DestReg)) {
- BuildMI(MBB, I, DL, get(Hexagon::TFR), DestReg).addReg(SrcReg);
+ BuildMI(MBB, I, DL, get(Hexagon::A2_tfr), DestReg).addReg(SrcReg);
return;
}
if (Hexagon::DoubleRegsRegClass.contains(SrcReg, DestReg)) {
- BuildMI(MBB, I, DL, get(Hexagon::TFR_64), DestReg).addReg(SrcReg);
+ BuildMI(MBB, I, DL, get(Hexagon::A2_tfrp), DestReg).addReg(SrcReg);
return;
}
if (Hexagon::PredRegsRegClass.contains(SrcReg, DestReg)) {
// Map Pd = Ps to Pd = or(Ps, Ps).
- BuildMI(MBB, I, DL, get(Hexagon::OR_pp),
+ BuildMI(MBB, I, DL, get(Hexagon::C2_or),
DestReg).addReg(SrcReg).addReg(SrcReg);
return;
}
// We can have an overlap between single and double reg: r1:0 = r0.
if(SrcReg == RI.getSubReg(DestReg, Hexagon::subreg_loreg)) {
// r1:0 = r0
- BuildMI(MBB, I, DL, get(Hexagon::TFRI), (RI.getSubReg(DestReg,
+ BuildMI(MBB, I, DL, get(Hexagon::A2_tfrsi), (RI.getSubReg(DestReg,
Hexagon::subreg_hireg))).addImm(0);
} else {
// r1:0 = r1 or no overlap.
- BuildMI(MBB, I, DL, get(Hexagon::TFR), (RI.getSubReg(DestReg,
+ BuildMI(MBB, I, DL, get(Hexagon::A2_tfr), (RI.getSubReg(DestReg,
Hexagon::subreg_loreg))).addReg(SrcReg);
- BuildMI(MBB, I, DL, get(Hexagon::TFRI), (RI.getSubReg(DestReg,
+ BuildMI(MBB, I, DL, get(Hexagon::A2_tfrsi), (RI.getSubReg(DestReg,
Hexagon::subreg_hireg))).addImm(0);
}
return;
}
- if (Hexagon::CRRegsRegClass.contains(DestReg) &&
+ if (Hexagon::CtrRegsRegClass.contains(DestReg) &&
Hexagon::IntRegsRegClass.contains(SrcReg)) {
- BuildMI(MBB, I, DL, get(Hexagon::TFCR), DestReg).addReg(SrcReg);
+ BuildMI(MBB, I, DL, get(Hexagon::A2_tfrrcr), DestReg).addReg(SrcReg);
+ return;
+ }
+ if (Hexagon::PredRegsRegClass.contains(SrcReg) &&
+ Hexagon::IntRegsRegClass.contains(DestReg)) {
+ BuildMI(MBB, I, DL, get(Hexagon::C2_tfrpr), DestReg).
+ addReg(SrcReg, getKillRegState(KillSrc));
+ return;
+ }
+ if (Hexagon::IntRegsRegClass.contains(SrcReg) &&
+ Hexagon::PredRegsRegClass.contains(DestReg)) {
+ BuildMI(MBB, I, DL, get(Hexagon::C2_tfrrp), DestReg).
+ addReg(SrcReg, getKillRegState(KillSrc));
return;
}
const SmallVectorImpl<unsigned> &Ops,
int FI) const {
// Hexagon_TODO: Implement.
- return(0);
+ return nullptr;
}
-
unsigned HexagonInstrInfo::createVR(MachineFunction* MF, MVT VT) const {
MachineRegisterInfo &RegInfo = MF->getRegInfo();
}
bool HexagonInstrInfo::isExtendable(const MachineInstr *MI) const {
+ // Constant extenders are allowed only for V4 and above.
+ if (!Subtarget.hasV4TOps())
+ return false;
+
+ const MCInstrDesc &MID = MI->getDesc();
+ const uint64_t F = MID.TSFlags;
+ if ((F >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask)
+ return true;
+
+ // TODO: This is largely obsolete now. Will need to be removed
+ // in consecutive patches.
switch(MI->getOpcode()) {
- default: return false;
- // JMP_EQri
- case Hexagon::JMP_EQriPt_nv_V4:
- case Hexagon::JMP_EQriPnt_nv_V4:
- case Hexagon::JMP_EQriNotPt_nv_V4:
- case Hexagon::JMP_EQriNotPnt_nv_V4:
-
- // JMP_EQri - with -1
- case Hexagon::JMP_EQriPtneg_nv_V4:
- case Hexagon::JMP_EQriPntneg_nv_V4:
- case Hexagon::JMP_EQriNotPtneg_nv_V4:
- case Hexagon::JMP_EQriNotPntneg_nv_V4:
-
- // JMP_EQrr
- case Hexagon::JMP_EQrrPt_nv_V4:
- case Hexagon::JMP_EQrrPnt_nv_V4:
- case Hexagon::JMP_EQrrNotPt_nv_V4:
- case Hexagon::JMP_EQrrNotPnt_nv_V4:
-
- // JMP_GTri
- case Hexagon::JMP_GTriPt_nv_V4:
- case Hexagon::JMP_GTriPnt_nv_V4:
- case Hexagon::JMP_GTriNotPt_nv_V4:
- case Hexagon::JMP_GTriNotPnt_nv_V4:
-
- // JMP_GTri - with -1
- case Hexagon::JMP_GTriPtneg_nv_V4:
- case Hexagon::JMP_GTriPntneg_nv_V4:
- case Hexagon::JMP_GTriNotPtneg_nv_V4:
- case Hexagon::JMP_GTriNotPntneg_nv_V4:
-
- // JMP_GTrr
- case Hexagon::JMP_GTrrPt_nv_V4:
- case Hexagon::JMP_GTrrPnt_nv_V4:
- case Hexagon::JMP_GTrrNotPt_nv_V4:
- case Hexagon::JMP_GTrrNotPnt_nv_V4:
-
- // JMP_GTrrdn
- case Hexagon::JMP_GTrrdnPt_nv_V4:
- case Hexagon::JMP_GTrrdnPnt_nv_V4:
- case Hexagon::JMP_GTrrdnNotPt_nv_V4:
- case Hexagon::JMP_GTrrdnNotPnt_nv_V4:
-
- // JMP_GTUri
- case Hexagon::JMP_GTUriPt_nv_V4:
- case Hexagon::JMP_GTUriPnt_nv_V4:
- case Hexagon::JMP_GTUriNotPt_nv_V4:
- case Hexagon::JMP_GTUriNotPnt_nv_V4:
-
- // JMP_GTUrr
- case Hexagon::JMP_GTUrrPt_nv_V4:
- case Hexagon::JMP_GTUrrPnt_nv_V4:
- case Hexagon::JMP_GTUrrNotPt_nv_V4:
- case Hexagon::JMP_GTUrrNotPnt_nv_V4:
-
- // JMP_GTUrrdn
- case Hexagon::JMP_GTUrrdnPt_nv_V4:
- case Hexagon::JMP_GTUrrdnPnt_nv_V4:
- case Hexagon::JMP_GTUrrdnNotPt_nv_V4:
- case Hexagon::JMP_GTUrrdnNotPnt_nv_V4:
-
- // TFR_FI
+ // TFR_FI Remains a special case.
case Hexagon::TFR_FI:
return true;
+ default:
+ return false;
}
+ return false;
}
+// This returns true in two cases:
+// - The OP code itself indicates that this is an extended instruction.
+// - One of MOs has been marked with HMOTF_ConstExtended flag.
bool HexagonInstrInfo::isExtended(const MachineInstr *MI) const {
- switch(MI->getOpcode()) {
- default: return false;
- // JMP_EQri
- case Hexagon::JMP_EQriPt_ie_nv_V4:
- case Hexagon::JMP_EQriPnt_ie_nv_V4:
- case Hexagon::JMP_EQriNotPt_ie_nv_V4:
- case Hexagon::JMP_EQriNotPnt_ie_nv_V4:
-
- // JMP_EQri - with -1
- case Hexagon::JMP_EQriPtneg_ie_nv_V4:
- case Hexagon::JMP_EQriPntneg_ie_nv_V4:
- case Hexagon::JMP_EQriNotPtneg_ie_nv_V4:
- case Hexagon::JMP_EQriNotPntneg_ie_nv_V4:
-
- // JMP_EQrr
- case Hexagon::JMP_EQrrPt_ie_nv_V4:
- case Hexagon::JMP_EQrrPnt_ie_nv_V4:
- case Hexagon::JMP_EQrrNotPt_ie_nv_V4:
- case Hexagon::JMP_EQrrNotPnt_ie_nv_V4:
-
- // JMP_GTri
- case Hexagon::JMP_GTriPt_ie_nv_V4:
- case Hexagon::JMP_GTriPnt_ie_nv_V4:
- case Hexagon::JMP_GTriNotPt_ie_nv_V4:
- case Hexagon::JMP_GTriNotPnt_ie_nv_V4:
-
- // JMP_GTri - with -1
- case Hexagon::JMP_GTriPtneg_ie_nv_V4:
- case Hexagon::JMP_GTriPntneg_ie_nv_V4:
- case Hexagon::JMP_GTriNotPtneg_ie_nv_V4:
- case Hexagon::JMP_GTriNotPntneg_ie_nv_V4:
-
- // JMP_GTrr
- case Hexagon::JMP_GTrrPt_ie_nv_V4:
- case Hexagon::JMP_GTrrPnt_ie_nv_V4:
- case Hexagon::JMP_GTrrNotPt_ie_nv_V4:
- case Hexagon::JMP_GTrrNotPnt_ie_nv_V4:
-
- // JMP_GTrrdn
- case Hexagon::JMP_GTrrdnPt_ie_nv_V4:
- case Hexagon::JMP_GTrrdnPnt_ie_nv_V4:
- case Hexagon::JMP_GTrrdnNotPt_ie_nv_V4:
- case Hexagon::JMP_GTrrdnNotPnt_ie_nv_V4:
-
- // JMP_GTUri
- case Hexagon::JMP_GTUriPt_ie_nv_V4:
- case Hexagon::JMP_GTUriPnt_ie_nv_V4:
- case Hexagon::JMP_GTUriNotPt_ie_nv_V4:
- case Hexagon::JMP_GTUriNotPnt_ie_nv_V4:
-
- // JMP_GTUrr
- case Hexagon::JMP_GTUrrPt_ie_nv_V4:
- case Hexagon::JMP_GTUrrPnt_ie_nv_V4:
- case Hexagon::JMP_GTUrrNotPt_ie_nv_V4:
- case Hexagon::JMP_GTUrrNotPnt_ie_nv_V4:
-
- // JMP_GTUrrdn
- case Hexagon::JMP_GTUrrdnPt_ie_nv_V4:
- case Hexagon::JMP_GTUrrdnPnt_ie_nv_V4:
- case Hexagon::JMP_GTUrrdnNotPt_ie_nv_V4:
- case Hexagon::JMP_GTUrrdnNotPnt_ie_nv_V4:
-
- // V4 absolute set addressing.
- case Hexagon::LDrid_abs_setimm_V4:
- case Hexagon::LDriw_abs_setimm_V4:
- case Hexagon::LDrih_abs_setimm_V4:
- case Hexagon::LDrib_abs_setimm_V4:
- case Hexagon::LDriuh_abs_setimm_V4:
- case Hexagon::LDriub_abs_setimm_V4:
-
- case Hexagon::STrid_abs_setimm_V4:
- case Hexagon::STrib_abs_setimm_V4:
- case Hexagon::STrih_abs_setimm_V4:
- case Hexagon::STriw_abs_setimm_V4:
-
- // V4 global address load.
- case Hexagon::LDrid_GP_cPt_V4 :
- case Hexagon::LDrid_GP_cNotPt_V4 :
- case Hexagon::LDrid_GP_cdnPt_V4 :
- case Hexagon::LDrid_GP_cdnNotPt_V4 :
- case Hexagon::LDrib_GP_cPt_V4 :
- case Hexagon::LDrib_GP_cNotPt_V4 :
- case Hexagon::LDrib_GP_cdnPt_V4 :
- case Hexagon::LDrib_GP_cdnNotPt_V4 :
- case Hexagon::LDriub_GP_cPt_V4 :
- case Hexagon::LDriub_GP_cNotPt_V4 :
- case Hexagon::LDriub_GP_cdnPt_V4 :
- case Hexagon::LDriub_GP_cdnNotPt_V4 :
- case Hexagon::LDrih_GP_cPt_V4 :
- case Hexagon::LDrih_GP_cNotPt_V4 :
- case Hexagon::LDrih_GP_cdnPt_V4 :
- case Hexagon::LDrih_GP_cdnNotPt_V4 :
- case Hexagon::LDriuh_GP_cPt_V4 :
- case Hexagon::LDriuh_GP_cNotPt_V4 :
- case Hexagon::LDriuh_GP_cdnPt_V4 :
- case Hexagon::LDriuh_GP_cdnNotPt_V4 :
- case Hexagon::LDriw_GP_cPt_V4 :
- case Hexagon::LDriw_GP_cNotPt_V4 :
- case Hexagon::LDriw_GP_cdnPt_V4 :
- case Hexagon::LDriw_GP_cdnNotPt_V4 :
- case Hexagon::LDd_GP_cPt_V4 :
- case Hexagon::LDd_GP_cNotPt_V4 :
- case Hexagon::LDd_GP_cdnPt_V4 :
- case Hexagon::LDd_GP_cdnNotPt_V4 :
- case Hexagon::LDb_GP_cPt_V4 :
- case Hexagon::LDb_GP_cNotPt_V4 :
- case Hexagon::LDb_GP_cdnPt_V4 :
- case Hexagon::LDb_GP_cdnNotPt_V4 :
- case Hexagon::LDub_GP_cPt_V4 :
- case Hexagon::LDub_GP_cNotPt_V4 :
- case Hexagon::LDub_GP_cdnPt_V4 :
- case Hexagon::LDub_GP_cdnNotPt_V4 :
- case Hexagon::LDh_GP_cPt_V4 :
- case Hexagon::LDh_GP_cNotPt_V4 :
- case Hexagon::LDh_GP_cdnPt_V4 :
- case Hexagon::LDh_GP_cdnNotPt_V4 :
- case Hexagon::LDuh_GP_cPt_V4 :
- case Hexagon::LDuh_GP_cNotPt_V4 :
- case Hexagon::LDuh_GP_cdnPt_V4 :
- case Hexagon::LDuh_GP_cdnNotPt_V4 :
- case Hexagon::LDw_GP_cPt_V4 :
- case Hexagon::LDw_GP_cNotPt_V4 :
- case Hexagon::LDw_GP_cdnPt_V4 :
- case Hexagon::LDw_GP_cdnNotPt_V4 :
-
- // V4 global address store.
- case Hexagon::STrid_GP_cPt_V4 :
- case Hexagon::STrid_GP_cNotPt_V4 :
- case Hexagon::STrid_GP_cdnPt_V4 :
- case Hexagon::STrid_GP_cdnNotPt_V4 :
- case Hexagon::STrib_GP_cPt_V4 :
- case Hexagon::STrib_GP_cNotPt_V4 :
- case Hexagon::STrib_GP_cdnPt_V4 :
- case Hexagon::STrib_GP_cdnNotPt_V4 :
- case Hexagon::STrih_GP_cPt_V4 :
- case Hexagon::STrih_GP_cNotPt_V4 :
- case Hexagon::STrih_GP_cdnPt_V4 :
- case Hexagon::STrih_GP_cdnNotPt_V4 :
- case Hexagon::STriw_GP_cPt_V4 :
- case Hexagon::STriw_GP_cNotPt_V4 :
- case Hexagon::STriw_GP_cdnPt_V4 :
- case Hexagon::STriw_GP_cdnNotPt_V4 :
- case Hexagon::STd_GP_cPt_V4 :
- case Hexagon::STd_GP_cNotPt_V4 :
- case Hexagon::STd_GP_cdnPt_V4 :
- case Hexagon::STd_GP_cdnNotPt_V4 :
- case Hexagon::STb_GP_cPt_V4 :
- case Hexagon::STb_GP_cNotPt_V4 :
- case Hexagon::STb_GP_cdnPt_V4 :
- case Hexagon::STb_GP_cdnNotPt_V4 :
- case Hexagon::STh_GP_cPt_V4 :
- case Hexagon::STh_GP_cNotPt_V4 :
- case Hexagon::STh_GP_cdnPt_V4 :
- case Hexagon::STh_GP_cdnNotPt_V4 :
- case Hexagon::STw_GP_cPt_V4 :
- case Hexagon::STw_GP_cNotPt_V4 :
- case Hexagon::STw_GP_cdnPt_V4 :
- case Hexagon::STw_GP_cdnNotPt_V4 :
-
- // V4 predicated global address new value store.
- case Hexagon::STrib_GP_cPt_nv_V4 :
- case Hexagon::STrib_GP_cNotPt_nv_V4 :
- case Hexagon::STrib_GP_cdnPt_nv_V4 :
- case Hexagon::STrib_GP_cdnNotPt_nv_V4 :
- case Hexagon::STrih_GP_cPt_nv_V4 :
- case Hexagon::STrih_GP_cNotPt_nv_V4 :
- case Hexagon::STrih_GP_cdnPt_nv_V4 :
- case Hexagon::STrih_GP_cdnNotPt_nv_V4 :
- case Hexagon::STriw_GP_cPt_nv_V4 :
- case Hexagon::STriw_GP_cNotPt_nv_V4 :
- case Hexagon::STriw_GP_cdnPt_nv_V4 :
- case Hexagon::STriw_GP_cdnNotPt_nv_V4 :
- case Hexagon::STb_GP_cPt_nv_V4 :
- case Hexagon::STb_GP_cNotPt_nv_V4 :
- case Hexagon::STb_GP_cdnPt_nv_V4 :
- case Hexagon::STb_GP_cdnNotPt_nv_V4 :
- case Hexagon::STh_GP_cPt_nv_V4 :
- case Hexagon::STh_GP_cNotPt_nv_V4 :
- case Hexagon::STh_GP_cdnPt_nv_V4 :
- case Hexagon::STh_GP_cdnNotPt_nv_V4 :
- case Hexagon::STw_GP_cPt_nv_V4 :
- case Hexagon::STw_GP_cNotPt_nv_V4 :
- case Hexagon::STw_GP_cdnPt_nv_V4 :
- case Hexagon::STw_GP_cdnNotPt_nv_V4 :
-
- // TFR_FI
- case Hexagon::TFR_FI_immext_V4:
-
- // TFRI_F
- case Hexagon::TFRI_f:
- case Hexagon::TFRI_cPt_f:
- case Hexagon::TFRI_cNotPt_f:
- case Hexagon::CONST64_Float_Real:
- return true;
- }
-}
-
-bool HexagonInstrInfo::isNewValueJump(const MachineInstr *MI) const {
- switch (MI->getOpcode()) {
- default: return false;
- // JMP_EQri
- case Hexagon::JMP_EQriPt_nv_V4:
- case Hexagon::JMP_EQriPnt_nv_V4:
- case Hexagon::JMP_EQriNotPt_nv_V4:
- case Hexagon::JMP_EQriNotPnt_nv_V4:
- case Hexagon::JMP_EQriPt_ie_nv_V4:
- case Hexagon::JMP_EQriPnt_ie_nv_V4:
- case Hexagon::JMP_EQriNotPt_ie_nv_V4:
- case Hexagon::JMP_EQriNotPnt_ie_nv_V4:
-
- // JMP_EQri - with -1
- case Hexagon::JMP_EQriPtneg_nv_V4:
- case Hexagon::JMP_EQriPntneg_nv_V4:
- case Hexagon::JMP_EQriNotPtneg_nv_V4:
- case Hexagon::JMP_EQriNotPntneg_nv_V4:
- case Hexagon::JMP_EQriPtneg_ie_nv_V4:
- case Hexagon::JMP_EQriPntneg_ie_nv_V4:
- case Hexagon::JMP_EQriNotPtneg_ie_nv_V4:
- case Hexagon::JMP_EQriNotPntneg_ie_nv_V4:
-
- // JMP_EQrr
- case Hexagon::JMP_EQrrPt_nv_V4:
- case Hexagon::JMP_EQrrPnt_nv_V4:
- case Hexagon::JMP_EQrrNotPt_nv_V4:
- case Hexagon::JMP_EQrrNotPnt_nv_V4:
- case Hexagon::JMP_EQrrPt_ie_nv_V4:
- case Hexagon::JMP_EQrrPnt_ie_nv_V4:
- case Hexagon::JMP_EQrrNotPt_ie_nv_V4:
- case Hexagon::JMP_EQrrNotPnt_ie_nv_V4:
-
- // JMP_GTri
- case Hexagon::JMP_GTriPt_nv_V4:
- case Hexagon::JMP_GTriPnt_nv_V4:
- case Hexagon::JMP_GTriNotPt_nv_V4:
- case Hexagon::JMP_GTriNotPnt_nv_V4:
- case Hexagon::JMP_GTriPt_ie_nv_V4:
- case Hexagon::JMP_GTriPnt_ie_nv_V4:
- case Hexagon::JMP_GTriNotPt_ie_nv_V4:
- case Hexagon::JMP_GTriNotPnt_ie_nv_V4:
-
- // JMP_GTri - with -1
- case Hexagon::JMP_GTriPtneg_nv_V4:
- case Hexagon::JMP_GTriPntneg_nv_V4:
- case Hexagon::JMP_GTriNotPtneg_nv_V4:
- case Hexagon::JMP_GTriNotPntneg_nv_V4:
- case Hexagon::JMP_GTriPtneg_ie_nv_V4:
- case Hexagon::JMP_GTriPntneg_ie_nv_V4:
- case Hexagon::JMP_GTriNotPtneg_ie_nv_V4:
- case Hexagon::JMP_GTriNotPntneg_ie_nv_V4:
-
- // JMP_GTrr
- case Hexagon::JMP_GTrrPt_nv_V4:
- case Hexagon::JMP_GTrrPnt_nv_V4:
- case Hexagon::JMP_GTrrNotPt_nv_V4:
- case Hexagon::JMP_GTrrNotPnt_nv_V4:
- case Hexagon::JMP_GTrrPt_ie_nv_V4:
- case Hexagon::JMP_GTrrPnt_ie_nv_V4:
- case Hexagon::JMP_GTrrNotPt_ie_nv_V4:
- case Hexagon::JMP_GTrrNotPnt_ie_nv_V4:
-
- // JMP_GTrrdn
- case Hexagon::JMP_GTrrdnPt_nv_V4:
- case Hexagon::JMP_GTrrdnPnt_nv_V4:
- case Hexagon::JMP_GTrrdnNotPt_nv_V4:
- case Hexagon::JMP_GTrrdnNotPnt_nv_V4:
- case Hexagon::JMP_GTrrdnPt_ie_nv_V4:
- case Hexagon::JMP_GTrrdnPnt_ie_nv_V4:
- case Hexagon::JMP_GTrrdnNotPt_ie_nv_V4:
- case Hexagon::JMP_GTrrdnNotPnt_ie_nv_V4:
-
- // JMP_GTUri
- case Hexagon::JMP_GTUriPt_nv_V4:
- case Hexagon::JMP_GTUriPnt_nv_V4:
- case Hexagon::JMP_GTUriNotPt_nv_V4:
- case Hexagon::JMP_GTUriNotPnt_nv_V4:
- case Hexagon::JMP_GTUriPt_ie_nv_V4:
- case Hexagon::JMP_GTUriPnt_ie_nv_V4:
- case Hexagon::JMP_GTUriNotPt_ie_nv_V4:
- case Hexagon::JMP_GTUriNotPnt_ie_nv_V4:
-
- // JMP_GTUrr
- case Hexagon::JMP_GTUrrPt_nv_V4:
- case Hexagon::JMP_GTUrrPnt_nv_V4:
- case Hexagon::JMP_GTUrrNotPt_nv_V4:
- case Hexagon::JMP_GTUrrNotPnt_nv_V4:
- case Hexagon::JMP_GTUrrPt_ie_nv_V4:
- case Hexagon::JMP_GTUrrPnt_ie_nv_V4:
- case Hexagon::JMP_GTUrrNotPt_ie_nv_V4:
- case Hexagon::JMP_GTUrrNotPnt_ie_nv_V4:
-
- // JMP_GTUrrdn
- case Hexagon::JMP_GTUrrdnPt_nv_V4:
- case Hexagon::JMP_GTUrrdnPnt_nv_V4:
- case Hexagon::JMP_GTUrrdnNotPt_nv_V4:
- case Hexagon::JMP_GTUrrdnNotPnt_nv_V4:
- case Hexagon::JMP_GTUrrdnPt_ie_nv_V4:
- case Hexagon::JMP_GTUrrdnPnt_ie_nv_V4:
- case Hexagon::JMP_GTUrrdnNotPt_ie_nv_V4:
- case Hexagon::JMP_GTUrrdnNotPnt_ie_nv_V4:
+ // First check if this is permanently extended op code.
+ const uint64_t F = MI->getDesc().TSFlags;
+ if ((F >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask)
+ return true;
+ // Use MO operand flags to determine if one of MI's operands
+ // has HMOTF_ConstExtended flag set.
+ for (MachineInstr::const_mop_iterator I = MI->operands_begin(),
+ E = MI->operands_end(); I != E; ++I) {
+ if (I->getTargetFlags() && HexagonII::HMOTF_ConstExtended)
return true;
}
+ return false;
}
-unsigned HexagonInstrInfo::getImmExtForm(const MachineInstr* MI) const {
- switch(MI->getOpcode()) {
- default: llvm_unreachable("Unknown type of instruction.");
- // JMP_EQri
- case Hexagon::JMP_EQriPt_nv_V4:
- return Hexagon::JMP_EQriPt_ie_nv_V4;
- case Hexagon::JMP_EQriNotPt_nv_V4:
- return Hexagon::JMP_EQriNotPt_ie_nv_V4;
- case Hexagon::JMP_EQriPnt_nv_V4:
- return Hexagon::JMP_EQriPnt_ie_nv_V4;
- case Hexagon::JMP_EQriNotPnt_nv_V4:
- return Hexagon::JMP_EQriNotPnt_ie_nv_V4;
-
- // JMP_EQri -- with -1
- case Hexagon::JMP_EQriPtneg_nv_V4:
- return Hexagon::JMP_EQriPtneg_ie_nv_V4;
- case Hexagon::JMP_EQriNotPtneg_nv_V4:
- return Hexagon::JMP_EQriNotPtneg_ie_nv_V4;
- case Hexagon::JMP_EQriPntneg_nv_V4:
- return Hexagon::JMP_EQriPntneg_ie_nv_V4;
- case Hexagon::JMP_EQriNotPntneg_nv_V4:
- return Hexagon::JMP_EQriNotPntneg_ie_nv_V4;
-
- // JMP_EQrr
- case Hexagon::JMP_EQrrPt_nv_V4:
- return Hexagon::JMP_EQrrPt_ie_nv_V4;
- case Hexagon::JMP_EQrrNotPt_nv_V4:
- return Hexagon::JMP_EQrrNotPt_ie_nv_V4;
- case Hexagon::JMP_EQrrPnt_nv_V4:
- return Hexagon::JMP_EQrrPnt_ie_nv_V4;
- case Hexagon::JMP_EQrrNotPnt_nv_V4:
- return Hexagon::JMP_EQrrNotPnt_ie_nv_V4;
-
- // JMP_GTri
- case Hexagon::JMP_GTriPt_nv_V4:
- return Hexagon::JMP_GTriPt_ie_nv_V4;
- case Hexagon::JMP_GTriNotPt_nv_V4:
- return Hexagon::JMP_GTriNotPt_ie_nv_V4;
- case Hexagon::JMP_GTriPnt_nv_V4:
- return Hexagon::JMP_GTriPnt_ie_nv_V4;
- case Hexagon::JMP_GTriNotPnt_nv_V4:
- return Hexagon::JMP_GTriNotPnt_ie_nv_V4;
-
- // JMP_GTri -- with -1
- case Hexagon::JMP_GTriPtneg_nv_V4:
- return Hexagon::JMP_GTriPtneg_ie_nv_V4;
- case Hexagon::JMP_GTriNotPtneg_nv_V4:
- return Hexagon::JMP_GTriNotPtneg_ie_nv_V4;
- case Hexagon::JMP_GTriPntneg_nv_V4:
- return Hexagon::JMP_GTriPntneg_ie_nv_V4;
- case Hexagon::JMP_GTriNotPntneg_nv_V4:
- return Hexagon::JMP_GTriNotPntneg_ie_nv_V4;
-
- // JMP_GTrr
- case Hexagon::JMP_GTrrPt_nv_V4:
- return Hexagon::JMP_GTrrPt_ie_nv_V4;
- case Hexagon::JMP_GTrrNotPt_nv_V4:
- return Hexagon::JMP_GTrrNotPt_ie_nv_V4;
- case Hexagon::JMP_GTrrPnt_nv_V4:
- return Hexagon::JMP_GTrrPnt_ie_nv_V4;
- case Hexagon::JMP_GTrrNotPnt_nv_V4:
- return Hexagon::JMP_GTrrNotPnt_ie_nv_V4;
-
- // JMP_GTrrdn
- case Hexagon::JMP_GTrrdnPt_nv_V4:
- return Hexagon::JMP_GTrrdnPt_ie_nv_V4;
- case Hexagon::JMP_GTrrdnNotPt_nv_V4:
- return Hexagon::JMP_GTrrdnNotPt_ie_nv_V4;
- case Hexagon::JMP_GTrrdnPnt_nv_V4:
- return Hexagon::JMP_GTrrdnPnt_ie_nv_V4;
- case Hexagon::JMP_GTrrdnNotPnt_nv_V4:
- return Hexagon::JMP_GTrrdnNotPnt_ie_nv_V4;
-
- // JMP_GTUri
- case Hexagon::JMP_GTUriPt_nv_V4:
- return Hexagon::JMP_GTUriPt_ie_nv_V4;
- case Hexagon::JMP_GTUriNotPt_nv_V4:
- return Hexagon::JMP_GTUriNotPt_ie_nv_V4;
- case Hexagon::JMP_GTUriPnt_nv_V4:
- return Hexagon::JMP_GTUriPnt_ie_nv_V4;
- case Hexagon::JMP_GTUriNotPnt_nv_V4:
- return Hexagon::JMP_GTUriNotPnt_ie_nv_V4;
-
- // JMP_GTUrr
- case Hexagon::JMP_GTUrrPt_nv_V4:
- return Hexagon::JMP_GTUrrPt_ie_nv_V4;
- case Hexagon::JMP_GTUrrNotPt_nv_V4:
- return Hexagon::JMP_GTUrrNotPt_ie_nv_V4;
- case Hexagon::JMP_GTUrrPnt_nv_V4:
- return Hexagon::JMP_GTUrrPnt_ie_nv_V4;
- case Hexagon::JMP_GTUrrNotPnt_nv_V4:
- return Hexagon::JMP_GTUrrNotPnt_ie_nv_V4;
-
- // JMP_GTUrrdn
- case Hexagon::JMP_GTUrrdnPt_nv_V4:
- return Hexagon::JMP_GTUrrdnPt_ie_nv_V4;
- case Hexagon::JMP_GTUrrdnNotPt_nv_V4:
- return Hexagon::JMP_GTUrrdnNotPt_ie_nv_V4;
- case Hexagon::JMP_GTUrrdnPnt_nv_V4:
- return Hexagon::JMP_GTUrrdnPnt_ie_nv_V4;
- case Hexagon::JMP_GTUrrdnNotPnt_nv_V4:
- return Hexagon::JMP_GTUrrdnNotPnt_ie_nv_V4;
-
- case Hexagon::TFR_FI:
- return Hexagon::TFR_FI_immext_V4;
-
- case Hexagon::MEMw_ADDi_indexed_MEM_V4 :
- case Hexagon::MEMw_SUBi_indexed_MEM_V4 :
- case Hexagon::MEMw_ADDr_indexed_MEM_V4 :
- case Hexagon::MEMw_SUBr_indexed_MEM_V4 :
- case Hexagon::MEMw_ANDr_indexed_MEM_V4 :
- case Hexagon::MEMw_ORr_indexed_MEM_V4 :
- case Hexagon::MEMw_ADDi_MEM_V4 :
- case Hexagon::MEMw_SUBi_MEM_V4 :
- case Hexagon::MEMw_ADDr_MEM_V4 :
- case Hexagon::MEMw_SUBr_MEM_V4 :
- case Hexagon::MEMw_ANDr_MEM_V4 :
- case Hexagon::MEMw_ORr_MEM_V4 :
- case Hexagon::MEMh_ADDi_indexed_MEM_V4 :
- case Hexagon::MEMh_SUBi_indexed_MEM_V4 :
- case Hexagon::MEMh_ADDr_indexed_MEM_V4 :
- case Hexagon::MEMh_SUBr_indexed_MEM_V4 :
- case Hexagon::MEMh_ANDr_indexed_MEM_V4 :
- case Hexagon::MEMh_ORr_indexed_MEM_V4 :
- case Hexagon::MEMh_ADDi_MEM_V4 :
- case Hexagon::MEMh_SUBi_MEM_V4 :
- case Hexagon::MEMh_ADDr_MEM_V4 :
- case Hexagon::MEMh_SUBr_MEM_V4 :
- case Hexagon::MEMh_ANDr_MEM_V4 :
- case Hexagon::MEMh_ORr_MEM_V4 :
- case Hexagon::MEMb_ADDi_indexed_MEM_V4 :
- case Hexagon::MEMb_SUBi_indexed_MEM_V4 :
- case Hexagon::MEMb_ADDr_indexed_MEM_V4 :
- case Hexagon::MEMb_SUBr_indexed_MEM_V4 :
- case Hexagon::MEMb_ANDr_indexed_MEM_V4 :
- case Hexagon::MEMb_ORr_indexed_MEM_V4 :
- case Hexagon::MEMb_ADDi_MEM_V4 :
- case Hexagon::MEMb_SUBi_MEM_V4 :
- case Hexagon::MEMb_ADDr_MEM_V4 :
- case Hexagon::MEMb_SUBr_MEM_V4 :
- case Hexagon::MEMb_ANDr_MEM_V4 :
- case Hexagon::MEMb_ORr_MEM_V4 :
- llvm_unreachable("Needs implementing.");
- }
-}
-
-unsigned HexagonInstrInfo::getNormalBranchForm(const MachineInstr* MI) const {
- switch(MI->getOpcode()) {
- default: llvm_unreachable("Unknown type of jump instruction.");
- // JMP_EQri
- case Hexagon::JMP_EQriPt_ie_nv_V4:
- return Hexagon::JMP_EQriPt_nv_V4;
- case Hexagon::JMP_EQriNotPt_ie_nv_V4:
- return Hexagon::JMP_EQriNotPt_nv_V4;
- case Hexagon::JMP_EQriPnt_ie_nv_V4:
- return Hexagon::JMP_EQriPnt_nv_V4;
- case Hexagon::JMP_EQriNotPnt_ie_nv_V4:
- return Hexagon::JMP_EQriNotPnt_nv_V4;
-
- // JMP_EQri -- with -1
- case Hexagon::JMP_EQriPtneg_ie_nv_V4:
- return Hexagon::JMP_EQriPtneg_nv_V4;
- case Hexagon::JMP_EQriNotPtneg_ie_nv_V4:
- return Hexagon::JMP_EQriNotPtneg_nv_V4;
- case Hexagon::JMP_EQriPntneg_ie_nv_V4:
- return Hexagon::JMP_EQriPntneg_nv_V4;
- case Hexagon::JMP_EQriNotPntneg_ie_nv_V4:
- return Hexagon::JMP_EQriNotPntneg_nv_V4;
-
- // JMP_EQrr
- case Hexagon::JMP_EQrrPt_ie_nv_V4:
- return Hexagon::JMP_EQrrPt_nv_V4;
- case Hexagon::JMP_EQrrNotPt_ie_nv_V4:
- return Hexagon::JMP_EQrrNotPt_nv_V4;
- case Hexagon::JMP_EQrrPnt_ie_nv_V4:
- return Hexagon::JMP_EQrrPnt_nv_V4;
- case Hexagon::JMP_EQrrNotPnt_ie_nv_V4:
- return Hexagon::JMP_EQrrNotPnt_nv_V4;
-
- // JMP_GTri
- case Hexagon::JMP_GTriPt_ie_nv_V4:
- return Hexagon::JMP_GTriPt_nv_V4;
- case Hexagon::JMP_GTriNotPt_ie_nv_V4:
- return Hexagon::JMP_GTriNotPt_nv_V4;
- case Hexagon::JMP_GTriPnt_ie_nv_V4:
- return Hexagon::JMP_GTriPnt_nv_V4;
- case Hexagon::JMP_GTriNotPnt_ie_nv_V4:
- return Hexagon::JMP_GTriNotPnt_nv_V4;
-
- // JMP_GTri -- with -1
- case Hexagon::JMP_GTriPtneg_ie_nv_V4:
- return Hexagon::JMP_GTriPtneg_nv_V4;
- case Hexagon::JMP_GTriNotPtneg_ie_nv_V4:
- return Hexagon::JMP_GTriNotPtneg_nv_V4;
- case Hexagon::JMP_GTriPntneg_ie_nv_V4:
- return Hexagon::JMP_GTriPntneg_nv_V4;
- case Hexagon::JMP_GTriNotPntneg_ie_nv_V4:
- return Hexagon::JMP_GTriNotPntneg_nv_V4;
-
- // JMP_GTrr
- case Hexagon::JMP_GTrrPt_ie_nv_V4:
- return Hexagon::JMP_GTrrPt_nv_V4;
- case Hexagon::JMP_GTrrNotPt_ie_nv_V4:
- return Hexagon::JMP_GTrrNotPt_nv_V4;
- case Hexagon::JMP_GTrrPnt_ie_nv_V4:
- return Hexagon::JMP_GTrrPnt_nv_V4;
- case Hexagon::JMP_GTrrNotPnt_ie_nv_V4:
- return Hexagon::JMP_GTrrNotPnt_nv_V4;
-
- // JMP_GTrrdn
- case Hexagon::JMP_GTrrdnPt_ie_nv_V4:
- return Hexagon::JMP_GTrrdnPt_nv_V4;
- case Hexagon::JMP_GTrrdnNotPt_ie_nv_V4:
- return Hexagon::JMP_GTrrdnNotPt_nv_V4;
- case Hexagon::JMP_GTrrdnPnt_ie_nv_V4:
- return Hexagon::JMP_GTrrdnPnt_nv_V4;
- case Hexagon::JMP_GTrrdnNotPnt_ie_nv_V4:
- return Hexagon::JMP_GTrrdnNotPnt_nv_V4;
-
- // JMP_GTUri
- case Hexagon::JMP_GTUriPt_ie_nv_V4:
- return Hexagon::JMP_GTUriPt_nv_V4;
- case Hexagon::JMP_GTUriNotPt_ie_nv_V4:
- return Hexagon::JMP_GTUriNotPt_nv_V4;
- case Hexagon::JMP_GTUriPnt_ie_nv_V4:
- return Hexagon::JMP_GTUriPnt_nv_V4;
- case Hexagon::JMP_GTUriNotPnt_ie_nv_V4:
- return Hexagon::JMP_GTUriNotPnt_nv_V4;
-
- // JMP_GTUrr
- case Hexagon::JMP_GTUrrPt_ie_nv_V4:
- return Hexagon::JMP_GTUrrPt_nv_V4;
- case Hexagon::JMP_GTUrrNotPt_ie_nv_V4:
- return Hexagon::JMP_GTUrrNotPt_nv_V4;
- case Hexagon::JMP_GTUrrPnt_ie_nv_V4:
- return Hexagon::JMP_GTUrrPnt_nv_V4;
- case Hexagon::JMP_GTUrrNotPnt_ie_nv_V4:
- return Hexagon::JMP_GTUrrNotPnt_nv_V4;
-
- // JMP_GTUrrdn
- case Hexagon::JMP_GTUrrdnPt_ie_nv_V4:
- return Hexagon::JMP_GTUrrdnPt_nv_V4;
- case Hexagon::JMP_GTUrrdnNotPt_ie_nv_V4:
- return Hexagon::JMP_GTUrrdnNotPt_nv_V4;
- case Hexagon::JMP_GTUrrdnPnt_ie_nv_V4:
- return Hexagon::JMP_GTUrrdnPnt_nv_V4;
- case Hexagon::JMP_GTUrrdnNotPnt_ie_nv_V4:
- return Hexagon::JMP_GTUrrdnNotPnt_nv_V4;
- }
+bool HexagonInstrInfo::isBranch (const MachineInstr *MI) const {
+ return MI->getDesc().isBranch();
}
+bool HexagonInstrInfo::isNewValueInst(const MachineInstr *MI) const {
+ if (isNewValueJump(MI))
+ return true;
-bool HexagonInstrInfo::isNewValueStore(const MachineInstr *MI) const {
- switch (MI->getOpcode()) {
- default: return false;
- // Store Byte
- case Hexagon::STrib_nv_V4:
- case Hexagon::STrib_indexed_nv_V4:
- case Hexagon::STrib_indexed_shl_nv_V4:
- case Hexagon::STrib_shl_nv_V4:
- case Hexagon::STrib_GP_nv_V4:
- case Hexagon::STb_GP_nv_V4:
- case Hexagon::POST_STbri_nv_V4:
- case Hexagon::STrib_cPt_nv_V4:
- case Hexagon::STrib_cdnPt_nv_V4:
- case Hexagon::STrib_cNotPt_nv_V4:
- case Hexagon::STrib_cdnNotPt_nv_V4:
- case Hexagon::STrib_indexed_cPt_nv_V4:
- case Hexagon::STrib_indexed_cdnPt_nv_V4:
- case Hexagon::STrib_indexed_cNotPt_nv_V4:
- case Hexagon::STrib_indexed_cdnNotPt_nv_V4:
- case Hexagon::STrib_indexed_shl_cPt_nv_V4:
- case Hexagon::STrib_indexed_shl_cdnPt_nv_V4:
- case Hexagon::STrib_indexed_shl_cNotPt_nv_V4:
- case Hexagon::STrib_indexed_shl_cdnNotPt_nv_V4:
- case Hexagon::POST_STbri_cPt_nv_V4:
- case Hexagon::POST_STbri_cdnPt_nv_V4:
- case Hexagon::POST_STbri_cNotPt_nv_V4:
- case Hexagon::POST_STbri_cdnNotPt_nv_V4:
- case Hexagon::STb_GP_cPt_nv_V4:
- case Hexagon::STb_GP_cNotPt_nv_V4:
- case Hexagon::STb_GP_cdnPt_nv_V4:
- case Hexagon::STb_GP_cdnNotPt_nv_V4:
- case Hexagon::STrib_GP_cPt_nv_V4:
- case Hexagon::STrib_GP_cNotPt_nv_V4:
- case Hexagon::STrib_GP_cdnPt_nv_V4:
- case Hexagon::STrib_GP_cdnNotPt_nv_V4:
- case Hexagon::STrib_abs_nv_V4:
- case Hexagon::STrib_abs_cPt_nv_V4:
- case Hexagon::STrib_abs_cdnPt_nv_V4:
- case Hexagon::STrib_abs_cNotPt_nv_V4:
- case Hexagon::STrib_abs_cdnNotPt_nv_V4:
- case Hexagon::STrib_imm_abs_nv_V4:
- case Hexagon::STrib_imm_abs_cPt_nv_V4:
- case Hexagon::STrib_imm_abs_cdnPt_nv_V4:
- case Hexagon::STrib_imm_abs_cNotPt_nv_V4:
- case Hexagon::STrib_imm_abs_cdnNotPt_nv_V4:
-
- // Store Halfword
- case Hexagon::STrih_nv_V4:
- case Hexagon::STrih_indexed_nv_V4:
- case Hexagon::STrih_indexed_shl_nv_V4:
- case Hexagon::STrih_shl_nv_V4:
- case Hexagon::STrih_GP_nv_V4:
- case Hexagon::STh_GP_nv_V4:
- case Hexagon::POST_SThri_nv_V4:
- case Hexagon::STrih_cPt_nv_V4:
- case Hexagon::STrih_cdnPt_nv_V4:
- case Hexagon::STrih_cNotPt_nv_V4:
- case Hexagon::STrih_cdnNotPt_nv_V4:
- case Hexagon::STrih_indexed_cPt_nv_V4:
- case Hexagon::STrih_indexed_cdnPt_nv_V4:
- case Hexagon::STrih_indexed_cNotPt_nv_V4:
- case Hexagon::STrih_indexed_cdnNotPt_nv_V4:
- case Hexagon::STrih_indexed_shl_cPt_nv_V4:
- case Hexagon::STrih_indexed_shl_cdnPt_nv_V4:
- case Hexagon::STrih_indexed_shl_cNotPt_nv_V4:
- case Hexagon::STrih_indexed_shl_cdnNotPt_nv_V4:
- case Hexagon::POST_SThri_cPt_nv_V4:
- case Hexagon::POST_SThri_cdnPt_nv_V4:
- case Hexagon::POST_SThri_cNotPt_nv_V4:
- case Hexagon::POST_SThri_cdnNotPt_nv_V4:
- case Hexagon::STh_GP_cPt_nv_V4:
- case Hexagon::STh_GP_cNotPt_nv_V4:
- case Hexagon::STh_GP_cdnPt_nv_V4:
- case Hexagon::STh_GP_cdnNotPt_nv_V4:
- case Hexagon::STrih_GP_cPt_nv_V4:
- case Hexagon::STrih_GP_cNotPt_nv_V4:
- case Hexagon::STrih_GP_cdnPt_nv_V4:
- case Hexagon::STrih_GP_cdnNotPt_nv_V4:
- case Hexagon::STrih_abs_nv_V4:
- case Hexagon::STrih_abs_cPt_nv_V4:
- case Hexagon::STrih_abs_cdnPt_nv_V4:
- case Hexagon::STrih_abs_cNotPt_nv_V4:
- case Hexagon::STrih_abs_cdnNotPt_nv_V4:
- case Hexagon::STrih_imm_abs_nv_V4:
- case Hexagon::STrih_imm_abs_cPt_nv_V4:
- case Hexagon::STrih_imm_abs_cdnPt_nv_V4:
- case Hexagon::STrih_imm_abs_cNotPt_nv_V4:
- case Hexagon::STrih_imm_abs_cdnNotPt_nv_V4:
-
- // Store Word
- case Hexagon::STriw_nv_V4:
- case Hexagon::STriw_indexed_nv_V4:
- case Hexagon::STriw_indexed_shl_nv_V4:
- case Hexagon::STriw_shl_nv_V4:
- case Hexagon::STriw_GP_nv_V4:
- case Hexagon::STw_GP_nv_V4:
- case Hexagon::POST_STwri_nv_V4:
- case Hexagon::STriw_cPt_nv_V4:
- case Hexagon::STriw_cdnPt_nv_V4:
- case Hexagon::STriw_cNotPt_nv_V4:
- case Hexagon::STriw_cdnNotPt_nv_V4:
- case Hexagon::STriw_indexed_cPt_nv_V4:
- case Hexagon::STriw_indexed_cdnPt_nv_V4:
- case Hexagon::STriw_indexed_cNotPt_nv_V4:
- case Hexagon::STriw_indexed_cdnNotPt_nv_V4:
- case Hexagon::STriw_indexed_shl_cPt_nv_V4:
- case Hexagon::STriw_indexed_shl_cdnPt_nv_V4:
- case Hexagon::STriw_indexed_shl_cNotPt_nv_V4:
- case Hexagon::STriw_indexed_shl_cdnNotPt_nv_V4:
- case Hexagon::POST_STwri_cPt_nv_V4:
- case Hexagon::POST_STwri_cdnPt_nv_V4:
- case Hexagon::POST_STwri_cNotPt_nv_V4:
- case Hexagon::POST_STwri_cdnNotPt_nv_V4:
- case Hexagon::STw_GP_cPt_nv_V4:
- case Hexagon::STw_GP_cNotPt_nv_V4:
- case Hexagon::STw_GP_cdnPt_nv_V4:
- case Hexagon::STw_GP_cdnNotPt_nv_V4:
- case Hexagon::STriw_GP_cPt_nv_V4:
- case Hexagon::STriw_GP_cNotPt_nv_V4:
- case Hexagon::STriw_GP_cdnPt_nv_V4:
- case Hexagon::STriw_GP_cdnNotPt_nv_V4:
- case Hexagon::STriw_abs_nv_V4:
- case Hexagon::STriw_abs_cPt_nv_V4:
- case Hexagon::STriw_abs_cdnPt_nv_V4:
- case Hexagon::STriw_abs_cNotPt_nv_V4:
- case Hexagon::STriw_abs_cdnNotPt_nv_V4:
- case Hexagon::STriw_imm_abs_nv_V4:
- case Hexagon::STriw_imm_abs_cPt_nv_V4:
- case Hexagon::STriw_imm_abs_cdnPt_nv_V4:
- case Hexagon::STriw_imm_abs_cNotPt_nv_V4:
- case Hexagon::STriw_imm_abs_cdnNotPt_nv_V4:
- return true;
- }
-}
+ if (isNewValueStore(MI))
+ return true;
-bool HexagonInstrInfo::isPostIncrement (const MachineInstr* MI) const {
- switch (MI->getOpcode())
- {
- default: return false;
- // Load Byte
- case Hexagon::POST_LDrib:
- case Hexagon::POST_LDrib_cPt:
- case Hexagon::POST_LDrib_cNotPt:
- case Hexagon::POST_LDrib_cdnPt_V4:
- case Hexagon::POST_LDrib_cdnNotPt_V4:
-
- // Load unsigned byte
- case Hexagon::POST_LDriub:
- case Hexagon::POST_LDriub_cPt:
- case Hexagon::POST_LDriub_cNotPt:
- case Hexagon::POST_LDriub_cdnPt_V4:
- case Hexagon::POST_LDriub_cdnNotPt_V4:
-
- // Load halfword
- case Hexagon::POST_LDrih:
- case Hexagon::POST_LDrih_cPt:
- case Hexagon::POST_LDrih_cNotPt:
- case Hexagon::POST_LDrih_cdnPt_V4:
- case Hexagon::POST_LDrih_cdnNotPt_V4:
-
- // Load unsigned halfword
- case Hexagon::POST_LDriuh:
- case Hexagon::POST_LDriuh_cPt:
- case Hexagon::POST_LDriuh_cNotPt:
- case Hexagon::POST_LDriuh_cdnPt_V4:
- case Hexagon::POST_LDriuh_cdnNotPt_V4:
-
- // Load word
- case Hexagon::POST_LDriw:
- case Hexagon::POST_LDriw_cPt:
- case Hexagon::POST_LDriw_cNotPt:
- case Hexagon::POST_LDriw_cdnPt_V4:
- case Hexagon::POST_LDriw_cdnNotPt_V4:
-
- // Load double word
- case Hexagon::POST_LDrid:
- case Hexagon::POST_LDrid_cPt:
- case Hexagon::POST_LDrid_cNotPt:
- case Hexagon::POST_LDrid_cdnPt_V4:
- case Hexagon::POST_LDrid_cdnNotPt_V4:
-
- // Store byte
- case Hexagon::POST_STbri:
- case Hexagon::POST_STbri_cPt:
- case Hexagon::POST_STbri_cNotPt:
- case Hexagon::POST_STbri_cdnPt_V4:
- case Hexagon::POST_STbri_cdnNotPt_V4:
-
- // Store halfword
- case Hexagon::POST_SThri:
- case Hexagon::POST_SThri_cPt:
- case Hexagon::POST_SThri_cNotPt:
- case Hexagon::POST_SThri_cdnPt_V4:
- case Hexagon::POST_SThri_cdnNotPt_V4:
-
- // Store word
- case Hexagon::POST_STwri:
- case Hexagon::POST_STwri_cPt:
- case Hexagon::POST_STwri_cNotPt:
- case Hexagon::POST_STwri_cdnPt_V4:
- case Hexagon::POST_STwri_cdnNotPt_V4:
-
- // Store double word
- case Hexagon::POST_STdri:
- case Hexagon::POST_STdri_cPt:
- case Hexagon::POST_STdri_cNotPt:
- case Hexagon::POST_STdri_cdnPt_V4:
- case Hexagon::POST_STdri_cdnNotPt_V4:
- return true;
- }
+ return false;
}
bool HexagonInstrInfo::isSaveCalleeSavedRegsCall(const MachineInstr *MI) const {
const int Opc = MI->getOpcode();
switch(Opc) {
- case Hexagon::TFRI:
+ case Hexagon::A2_tfrsi:
return isInt<12>(MI->getOperand(1).getImm());
case Hexagon::STrid:
case Hexagon::LDriuh_indexed:
return isShiftedUInt<6,1>(MI->getOperand(2).getImm());
- case Hexagon::LDrib:
- case Hexagon::LDriub:
- case Hexagon::LDrib_indexed:
- case Hexagon::LDriub_indexed:
+ case Hexagon::L2_loadrb_io:
+ case Hexagon::L2_loadrub_io:
return isUInt<6>(MI->getOperand(2).getImm());
case Hexagon::POST_LDrid:
case Hexagon::ADD_ri:
return isInt<8>(MI->getOperand(2).getImm());
- case Hexagon::ASLH:
- case Hexagon::ASRH:
- case Hexagon::SXTB:
- case Hexagon::SXTH:
- case Hexagon::ZXTB:
- case Hexagon::ZXTH:
+ case Hexagon::A2_aslh:
+ case Hexagon::A2_asrh:
+ case Hexagon::A2_sxtb:
+ case Hexagon::A2_sxth:
+ case Hexagon::A2_zxtb:
+ case Hexagon::A2_zxth:
return Subtarget.hasV4TOps();
-
- case Hexagon::JMPR:
- return false;
}
return true;
// cPt ---> cNotPt
// cNotPt ---> cPt
//
-// however, these inversiones are NOT included:
-//
-// cdnPt -X-> cdnNotPt
-// cdnNotPt -X-> cdnPt
-// cPt_nv -X-> cNotPt_nv (new value stores)
-// cNotPt_nv -X-> cPt_nv (new value stores)
-//
-// because only the following transformations are allowed:
-//
-// cNotPt ---> cdnNotPt
-// cPt ---> cdnPt
-// cNotPt ---> cNotPt_nv
-// cPt ---> cPt_nv
unsigned HexagonInstrInfo::getInvertedPredicatedOpcode(const int Opc) const {
+ int InvPredOpcode;
+ InvPredOpcode = isPredicatedTrue(Opc) ? Hexagon::getFalsePredOpcode(Opc)
+ : Hexagon::getTruePredOpcode(Opc);
+ if (InvPredOpcode >= 0) // Valid instruction with the inverted predicate.
+ return InvPredOpcode;
+
switch(Opc) {
default: llvm_unreachable("Unexpected predicated instruction");
- case Hexagon::TFR_cPt:
- return Hexagon::TFR_cNotPt;
- case Hexagon::TFR_cNotPt:
- return Hexagon::TFR_cPt;
-
- case Hexagon::TFRI_cPt:
- return Hexagon::TFRI_cNotPt;
- case Hexagon::TFRI_cNotPt:
- return Hexagon::TFRI_cPt;
-
- case Hexagon::JMP_c:
- return Hexagon::JMP_cNot;
- case Hexagon::JMP_cNot:
- return Hexagon::JMP_c;
+ case Hexagon::C2_ccombinewt:
+ return Hexagon::C2_ccombinewf;
+ case Hexagon::C2_ccombinewf:
+ return Hexagon::C2_ccombinewt;
- case Hexagon::ADD_ri_cPt:
- return Hexagon::ADD_ri_cNotPt;
- case Hexagon::ADD_ri_cNotPt:
- return Hexagon::ADD_ri_cPt;
-
- case Hexagon::ADD_rr_cPt:
- return Hexagon::ADD_rr_cNotPt;
- case Hexagon::ADD_rr_cNotPt:
- return Hexagon::ADD_rr_cPt;
-
- case Hexagon::XOR_rr_cPt:
- return Hexagon::XOR_rr_cNotPt;
- case Hexagon::XOR_rr_cNotPt:
- return Hexagon::XOR_rr_cPt;
-
- case Hexagon::AND_rr_cPt:
- return Hexagon::AND_rr_cNotPt;
- case Hexagon::AND_rr_cNotPt:
- return Hexagon::AND_rr_cPt;
-
- case Hexagon::OR_rr_cPt:
- return Hexagon::OR_rr_cNotPt;
- case Hexagon::OR_rr_cNotPt:
- return Hexagon::OR_rr_cPt;
-
- case Hexagon::SUB_rr_cPt:
- return Hexagon::SUB_rr_cNotPt;
- case Hexagon::SUB_rr_cNotPt:
- return Hexagon::SUB_rr_cPt;
-
- case Hexagon::COMBINE_rr_cPt:
- return Hexagon::COMBINE_rr_cNotPt;
- case Hexagon::COMBINE_rr_cNotPt:
- return Hexagon::COMBINE_rr_cPt;
-
- case Hexagon::ASLH_cPt_V4:
- return Hexagon::ASLH_cNotPt_V4;
- case Hexagon::ASLH_cNotPt_V4:
- return Hexagon::ASLH_cPt_V4;
-
- case Hexagon::ASRH_cPt_V4:
- return Hexagon::ASRH_cNotPt_V4;
- case Hexagon::ASRH_cNotPt_V4:
- return Hexagon::ASRH_cPt_V4;
-
- case Hexagon::SXTB_cPt_V4:
- return Hexagon::SXTB_cNotPt_V4;
- case Hexagon::SXTB_cNotPt_V4:
- return Hexagon::SXTB_cPt_V4;
-
- case Hexagon::SXTH_cPt_V4:
- return Hexagon::SXTH_cNotPt_V4;
- case Hexagon::SXTH_cNotPt_V4:
- return Hexagon::SXTH_cPt_V4;
-
- case Hexagon::ZXTB_cPt_V4:
- return Hexagon::ZXTB_cNotPt_V4;
- case Hexagon::ZXTB_cNotPt_V4:
- return Hexagon::ZXTB_cPt_V4;
-
- case Hexagon::ZXTH_cPt_V4:
- return Hexagon::ZXTH_cNotPt_V4;
- case Hexagon::ZXTH_cNotPt_V4:
- return Hexagon::ZXTH_cPt_V4;
-
-
- case Hexagon::JMPR_cPt:
- return Hexagon::JMPR_cNotPt;
- case Hexagon::JMPR_cNotPt:
- return Hexagon::JMPR_cPt;
-
- // V4 indexed+scaled load.
- case Hexagon::LDrid_indexed_cPt_V4:
- return Hexagon::LDrid_indexed_cNotPt_V4;
- case Hexagon::LDrid_indexed_cNotPt_V4:
- return Hexagon::LDrid_indexed_cPt_V4;
-
- case Hexagon::LDrid_indexed_shl_cPt_V4:
- return Hexagon::LDrid_indexed_shl_cNotPt_V4;
- case Hexagon::LDrid_indexed_shl_cNotPt_V4:
- return Hexagon::LDrid_indexed_shl_cPt_V4;
-
- case Hexagon::LDrib_indexed_cPt_V4:
- return Hexagon::LDrib_indexed_cNotPt_V4;
- case Hexagon::LDrib_indexed_cNotPt_V4:
- return Hexagon::LDrib_indexed_cPt_V4;
-
- case Hexagon::LDriub_indexed_cPt_V4:
- return Hexagon::LDriub_indexed_cNotPt_V4;
- case Hexagon::LDriub_indexed_cNotPt_V4:
- return Hexagon::LDriub_indexed_cPt_V4;
-
- case Hexagon::LDrib_indexed_shl_cPt_V4:
- return Hexagon::LDrib_indexed_shl_cNotPt_V4;
- case Hexagon::LDrib_indexed_shl_cNotPt_V4:
- return Hexagon::LDrib_indexed_shl_cPt_V4;
-
- case Hexagon::LDriub_indexed_shl_cPt_V4:
- return Hexagon::LDriub_indexed_shl_cNotPt_V4;
- case Hexagon::LDriub_indexed_shl_cNotPt_V4:
- return Hexagon::LDriub_indexed_shl_cPt_V4;
-
- case Hexagon::LDrih_indexed_cPt_V4:
- return Hexagon::LDrih_indexed_cNotPt_V4;
- case Hexagon::LDrih_indexed_cNotPt_V4:
- return Hexagon::LDrih_indexed_cPt_V4;
-
- case Hexagon::LDriuh_indexed_cPt_V4:
- return Hexagon::LDriuh_indexed_cNotPt_V4;
- case Hexagon::LDriuh_indexed_cNotPt_V4:
- return Hexagon::LDriuh_indexed_cPt_V4;
-
- case Hexagon::LDrih_indexed_shl_cPt_V4:
- return Hexagon::LDrih_indexed_shl_cNotPt_V4;
- case Hexagon::LDrih_indexed_shl_cNotPt_V4:
- return Hexagon::LDrih_indexed_shl_cPt_V4;
-
- case Hexagon::LDriuh_indexed_shl_cPt_V4:
- return Hexagon::LDriuh_indexed_shl_cNotPt_V4;
- case Hexagon::LDriuh_indexed_shl_cNotPt_V4:
- return Hexagon::LDriuh_indexed_shl_cPt_V4;
-
- case Hexagon::LDriw_indexed_cPt_V4:
- return Hexagon::LDriw_indexed_cNotPt_V4;
- case Hexagon::LDriw_indexed_cNotPt_V4:
- return Hexagon::LDriw_indexed_cPt_V4;
-
- case Hexagon::LDriw_indexed_shl_cPt_V4:
- return Hexagon::LDriw_indexed_shl_cNotPt_V4;
- case Hexagon::LDriw_indexed_shl_cNotPt_V4:
- return Hexagon::LDriw_indexed_shl_cPt_V4;
-
- // Byte.
- case Hexagon::POST_STbri_cPt:
- return Hexagon::POST_STbri_cNotPt;
- case Hexagon::POST_STbri_cNotPt:
- return Hexagon::POST_STbri_cPt;
-
- case Hexagon::STrib_cPt:
- return Hexagon::STrib_cNotPt;
- case Hexagon::STrib_cNotPt:
- return Hexagon::STrib_cPt;
-
- case Hexagon::STrib_indexed_cPt:
- return Hexagon::STrib_indexed_cNotPt;
- case Hexagon::STrib_indexed_cNotPt:
- return Hexagon::STrib_indexed_cPt;
-
- case Hexagon::STrib_imm_cPt_V4:
- return Hexagon::STrib_imm_cNotPt_V4;
- case Hexagon::STrib_imm_cNotPt_V4:
- return Hexagon::STrib_imm_cPt_V4;
-
- case Hexagon::STrib_indexed_shl_cPt_V4:
- return Hexagon::STrib_indexed_shl_cNotPt_V4;
- case Hexagon::STrib_indexed_shl_cNotPt_V4:
- return Hexagon::STrib_indexed_shl_cPt_V4;
-
- // Halfword.
- case Hexagon::POST_SThri_cPt:
- return Hexagon::POST_SThri_cNotPt;
- case Hexagon::POST_SThri_cNotPt:
- return Hexagon::POST_SThri_cPt;
-
- case Hexagon::STrih_cPt:
- return Hexagon::STrih_cNotPt;
- case Hexagon::STrih_cNotPt:
- return Hexagon::STrih_cPt;
-
- case Hexagon::STrih_indexed_cPt:
- return Hexagon::STrih_indexed_cNotPt;
- case Hexagon::STrih_indexed_cNotPt:
- return Hexagon::STrih_indexed_cPt;
-
- case Hexagon::STrih_imm_cPt_V4:
- return Hexagon::STrih_imm_cNotPt_V4;
- case Hexagon::STrih_imm_cNotPt_V4:
- return Hexagon::STrih_imm_cPt_V4;
-
- case Hexagon::STrih_indexed_shl_cPt_V4:
- return Hexagon::STrih_indexed_shl_cNotPt_V4;
- case Hexagon::STrih_indexed_shl_cNotPt_V4:
- return Hexagon::STrih_indexed_shl_cPt_V4;
-
- // Word.
- case Hexagon::POST_STwri_cPt:
- return Hexagon::POST_STwri_cNotPt;
- case Hexagon::POST_STwri_cNotPt:
- return Hexagon::POST_STwri_cPt;
-
- case Hexagon::STriw_cPt:
- return Hexagon::STriw_cNotPt;
- case Hexagon::STriw_cNotPt:
- return Hexagon::STriw_cPt;
-
- case Hexagon::STriw_indexed_cPt:
- return Hexagon::STriw_indexed_cNotPt;
- case Hexagon::STriw_indexed_cNotPt:
- return Hexagon::STriw_indexed_cPt;
-
- case Hexagon::STriw_indexed_shl_cPt_V4:
- return Hexagon::STriw_indexed_shl_cNotPt_V4;
- case Hexagon::STriw_indexed_shl_cNotPt_V4:
- return Hexagon::STriw_indexed_shl_cPt_V4;
-
- case Hexagon::STriw_imm_cPt_V4:
- return Hexagon::STriw_imm_cNotPt_V4;
- case Hexagon::STriw_imm_cNotPt_V4:
- return Hexagon::STriw_imm_cPt_V4;
-
- // Double word.
- case Hexagon::POST_STdri_cPt:
- return Hexagon::POST_STdri_cNotPt;
- case Hexagon::POST_STdri_cNotPt:
- return Hexagon::POST_STdri_cPt;
-
- case Hexagon::STrid_cPt:
- return Hexagon::STrid_cNotPt;
- case Hexagon::STrid_cNotPt:
- return Hexagon::STrid_cPt;
-
- case Hexagon::STrid_indexed_cPt:
- return Hexagon::STrid_indexed_cNotPt;
- case Hexagon::STrid_indexed_cNotPt:
- return Hexagon::STrid_indexed_cPt;
-
- case Hexagon::STrid_indexed_shl_cPt_V4:
- return Hexagon::STrid_indexed_shl_cNotPt_V4;
- case Hexagon::STrid_indexed_shl_cNotPt_V4:
- return Hexagon::STrid_indexed_shl_cPt_V4;
-
- // V4 Store to global address.
- case Hexagon::STd_GP_cPt_V4:
- return Hexagon::STd_GP_cNotPt_V4;
- case Hexagon::STd_GP_cNotPt_V4:
- return Hexagon::STd_GP_cPt_V4;
-
- case Hexagon::STb_GP_cPt_V4:
- return Hexagon::STb_GP_cNotPt_V4;
- case Hexagon::STb_GP_cNotPt_V4:
- return Hexagon::STb_GP_cPt_V4;
-
- case Hexagon::STh_GP_cPt_V4:
- return Hexagon::STh_GP_cNotPt_V4;
- case Hexagon::STh_GP_cNotPt_V4:
- return Hexagon::STh_GP_cPt_V4;
-
- case Hexagon::STw_GP_cPt_V4:
- return Hexagon::STw_GP_cNotPt_V4;
- case Hexagon::STw_GP_cNotPt_V4:
- return Hexagon::STw_GP_cPt_V4;
-
- case Hexagon::STrid_GP_cPt_V4:
- return Hexagon::STrid_GP_cNotPt_V4;
- case Hexagon::STrid_GP_cNotPt_V4:
- return Hexagon::STrid_GP_cPt_V4;
-
- case Hexagon::STrib_GP_cPt_V4:
- return Hexagon::STrib_GP_cNotPt_V4;
- case Hexagon::STrib_GP_cNotPt_V4:
- return Hexagon::STrib_GP_cPt_V4;
-
- case Hexagon::STrih_GP_cPt_V4:
- return Hexagon::STrih_GP_cNotPt_V4;
- case Hexagon::STrih_GP_cNotPt_V4:
- return Hexagon::STrih_GP_cPt_V4;
-
- case Hexagon::STriw_GP_cPt_V4:
- return Hexagon::STriw_GP_cNotPt_V4;
- case Hexagon::STriw_GP_cNotPt_V4:
- return Hexagon::STriw_GP_cPt_V4;
-
- // Load.
- case Hexagon::LDrid_cPt:
- return Hexagon::LDrid_cNotPt;
- case Hexagon::LDrid_cNotPt:
- return Hexagon::LDrid_cPt;
-
- case Hexagon::LDriw_cPt:
- return Hexagon::LDriw_cNotPt;
- case Hexagon::LDriw_cNotPt:
- return Hexagon::LDriw_cPt;
-
- case Hexagon::LDrih_cPt:
- return Hexagon::LDrih_cNotPt;
- case Hexagon::LDrih_cNotPt:
- return Hexagon::LDrih_cPt;
-
- case Hexagon::LDriuh_cPt:
- return Hexagon::LDriuh_cNotPt;
- case Hexagon::LDriuh_cNotPt:
- return Hexagon::LDriuh_cPt;
-
- case Hexagon::LDrib_cPt:
- return Hexagon::LDrib_cNotPt;
- case Hexagon::LDrib_cNotPt:
- return Hexagon::LDrib_cPt;
-
- case Hexagon::LDriub_cPt:
- return Hexagon::LDriub_cNotPt;
- case Hexagon::LDriub_cNotPt:
- return Hexagon::LDriub_cPt;
-
- // Load Indexed.
- case Hexagon::LDrid_indexed_cPt:
- return Hexagon::LDrid_indexed_cNotPt;
- case Hexagon::LDrid_indexed_cNotPt:
- return Hexagon::LDrid_indexed_cPt;
-
- case Hexagon::LDriw_indexed_cPt:
- return Hexagon::LDriw_indexed_cNotPt;
- case Hexagon::LDriw_indexed_cNotPt:
- return Hexagon::LDriw_indexed_cPt;
-
- case Hexagon::LDrih_indexed_cPt:
- return Hexagon::LDrih_indexed_cNotPt;
- case Hexagon::LDrih_indexed_cNotPt:
- return Hexagon::LDrih_indexed_cPt;
-
- case Hexagon::LDriuh_indexed_cPt:
- return Hexagon::LDriuh_indexed_cNotPt;
- case Hexagon::LDriuh_indexed_cNotPt:
- return Hexagon::LDriuh_indexed_cPt;
-
- case Hexagon::LDrib_indexed_cPt:
- return Hexagon::LDrib_indexed_cNotPt;
- case Hexagon::LDrib_indexed_cNotPt:
- return Hexagon::LDrib_indexed_cPt;
-
- case Hexagon::LDriub_indexed_cPt:
- return Hexagon::LDriub_indexed_cNotPt;
- case Hexagon::LDriub_indexed_cNotPt:
- return Hexagon::LDriub_indexed_cPt;
-
- // Post Inc Load.
- case Hexagon::POST_LDrid_cPt:
- return Hexagon::POST_LDrid_cNotPt;
- case Hexagon::POST_LDriw_cNotPt:
- return Hexagon::POST_LDriw_cPt;
-
- case Hexagon::POST_LDrih_cPt:
- return Hexagon::POST_LDrih_cNotPt;
- case Hexagon::POST_LDrih_cNotPt:
- return Hexagon::POST_LDrih_cPt;
-
- case Hexagon::POST_LDriuh_cPt:
- return Hexagon::POST_LDriuh_cNotPt;
- case Hexagon::POST_LDriuh_cNotPt:
- return Hexagon::POST_LDriuh_cPt;
-
- case Hexagon::POST_LDrib_cPt:
- return Hexagon::POST_LDrib_cNotPt;
- case Hexagon::POST_LDrib_cNotPt:
- return Hexagon::POST_LDrib_cPt;
-
- case Hexagon::POST_LDriub_cPt:
- return Hexagon::POST_LDriub_cNotPt;
- case Hexagon::POST_LDriub_cNotPt:
- return Hexagon::POST_LDriub_cPt;
-
- // Dealloc_return.
+ // Dealloc_return.
case Hexagon::DEALLOC_RET_cPt_V4:
return Hexagon::DEALLOC_RET_cNotPt_V4;
case Hexagon::DEALLOC_RET_cNotPt_V4:
return Hexagon::DEALLOC_RET_cPt_V4;
-
- // New Value Jump.
- // JMPEQ_ri - with -1.
- case Hexagon::JMP_EQriPtneg_nv_V4:
- return Hexagon::JMP_EQriNotPtneg_nv_V4;
- case Hexagon::JMP_EQriNotPtneg_nv_V4:
- return Hexagon::JMP_EQriPtneg_nv_V4;
-
- case Hexagon::JMP_EQriPntneg_nv_V4:
- return Hexagon::JMP_EQriNotPntneg_nv_V4;
- case Hexagon::JMP_EQriNotPntneg_nv_V4:
- return Hexagon::JMP_EQriPntneg_nv_V4;
-
- // JMPEQ_ri.
- case Hexagon::JMP_EQriPt_nv_V4:
- return Hexagon::JMP_EQriNotPt_nv_V4;
- case Hexagon::JMP_EQriNotPt_nv_V4:
- return Hexagon::JMP_EQriPt_nv_V4;
-
- case Hexagon::JMP_EQriPnt_nv_V4:
- return Hexagon::JMP_EQriNotPnt_nv_V4;
- case Hexagon::JMP_EQriNotPnt_nv_V4:
- return Hexagon::JMP_EQriPnt_nv_V4;
-
- // JMPEQ_rr.
- case Hexagon::JMP_EQrrPt_nv_V4:
- return Hexagon::JMP_EQrrNotPt_nv_V4;
- case Hexagon::JMP_EQrrNotPt_nv_V4:
- return Hexagon::JMP_EQrrPt_nv_V4;
-
- case Hexagon::JMP_EQrrPnt_nv_V4:
- return Hexagon::JMP_EQrrNotPnt_nv_V4;
- case Hexagon::JMP_EQrrNotPnt_nv_V4:
- return Hexagon::JMP_EQrrPnt_nv_V4;
-
- // JMPGT_ri - with -1.
- case Hexagon::JMP_GTriPtneg_nv_V4:
- return Hexagon::JMP_GTriNotPtneg_nv_V4;
- case Hexagon::JMP_GTriNotPtneg_nv_V4:
- return Hexagon::JMP_GTriPtneg_nv_V4;
-
- case Hexagon::JMP_GTriPntneg_nv_V4:
- return Hexagon::JMP_GTriNotPntneg_nv_V4;
- case Hexagon::JMP_GTriNotPntneg_nv_V4:
- return Hexagon::JMP_GTriPntneg_nv_V4;
-
- // JMPGT_ri.
- case Hexagon::JMP_GTriPt_nv_V4:
- return Hexagon::JMP_GTriNotPt_nv_V4;
- case Hexagon::JMP_GTriNotPt_nv_V4:
- return Hexagon::JMP_GTriPt_nv_V4;
-
- case Hexagon::JMP_GTriPnt_nv_V4:
- return Hexagon::JMP_GTriNotPnt_nv_V4;
- case Hexagon::JMP_GTriNotPnt_nv_V4:
- return Hexagon::JMP_GTriPnt_nv_V4;
-
- // JMPGT_rr.
- case Hexagon::JMP_GTrrPt_nv_V4:
- return Hexagon::JMP_GTrrNotPt_nv_V4;
- case Hexagon::JMP_GTrrNotPt_nv_V4:
- return Hexagon::JMP_GTrrPt_nv_V4;
-
- case Hexagon::JMP_GTrrPnt_nv_V4:
- return Hexagon::JMP_GTrrNotPnt_nv_V4;
- case Hexagon::JMP_GTrrNotPnt_nv_V4:
- return Hexagon::JMP_GTrrPnt_nv_V4;
-
- // JMPGT_rrdn.
- case Hexagon::JMP_GTrrdnPt_nv_V4:
- return Hexagon::JMP_GTrrdnNotPt_nv_V4;
- case Hexagon::JMP_GTrrdnNotPt_nv_V4:
- return Hexagon::JMP_GTrrdnPt_nv_V4;
-
- case Hexagon::JMP_GTrrdnPnt_nv_V4:
- return Hexagon::JMP_GTrrdnNotPnt_nv_V4;
- case Hexagon::JMP_GTrrdnNotPnt_nv_V4:
- return Hexagon::JMP_GTrrdnPnt_nv_V4;
-
- // JMPGTU_ri.
- case Hexagon::JMP_GTUriPt_nv_V4:
- return Hexagon::JMP_GTUriNotPt_nv_V4;
- case Hexagon::JMP_GTUriNotPt_nv_V4:
- return Hexagon::JMP_GTUriPt_nv_V4;
-
- case Hexagon::JMP_GTUriPnt_nv_V4:
- return Hexagon::JMP_GTUriNotPnt_nv_V4;
- case Hexagon::JMP_GTUriNotPnt_nv_V4:
- return Hexagon::JMP_GTUriPnt_nv_V4;
-
- // JMPGTU_rr.
- case Hexagon::JMP_GTUrrPt_nv_V4:
- return Hexagon::JMP_GTUrrNotPt_nv_V4;
- case Hexagon::JMP_GTUrrNotPt_nv_V4:
- return Hexagon::JMP_GTUrrPt_nv_V4;
-
- case Hexagon::JMP_GTUrrPnt_nv_V4:
- return Hexagon::JMP_GTUrrNotPnt_nv_V4;
- case Hexagon::JMP_GTUrrNotPnt_nv_V4:
- return Hexagon::JMP_GTUrrPnt_nv_V4;
-
- // JMPGTU_rrdn.
- case Hexagon::JMP_GTUrrdnPt_nv_V4:
- return Hexagon::JMP_GTUrrdnNotPt_nv_V4;
- case Hexagon::JMP_GTUrrdnNotPt_nv_V4:
- return Hexagon::JMP_GTUrrdnPt_nv_V4;
-
- case Hexagon::JMP_GTUrrdnPnt_nv_V4:
- return Hexagon::JMP_GTUrrdnNotPnt_nv_V4;
- case Hexagon::JMP_GTUrrdnNotPnt_nv_V4:
- return Hexagon::JMP_GTUrrdnPnt_nv_V4;
}
}
+// New Value Store instructions.
+bool HexagonInstrInfo::isNewValueStore(const MachineInstr *MI) const {
+ const uint64_t F = MI->getDesc().TSFlags;
+
+ return ((F >> HexagonII::NVStorePos) & HexagonII::NVStoreMask);
+}
+
+bool HexagonInstrInfo::isNewValueStore(unsigned Opcode) const {
+ const uint64_t F = get(Opcode).TSFlags;
+
+ return ((F >> HexagonII::NVStorePos) & HexagonII::NVStoreMask);
+}
int HexagonInstrInfo::
getMatchingCondBranchOpcode(int Opc, bool invertPredicate) const {
// This switch case will be removed once all the instructions have been
// modified to use relation maps.
switch(Opc) {
- case Hexagon::TFR:
- return !invertPredicate ? Hexagon::TFR_cPt :
- Hexagon::TFR_cNotPt;
case Hexagon::TFRI_f:
return !invertPredicate ? Hexagon::TFRI_cPt_f :
Hexagon::TFRI_cNotPt_f;
- case Hexagon::TFRI:
- return !invertPredicate ? Hexagon::TFRI_cPt :
- Hexagon::TFRI_cNotPt;
- case Hexagon::JMP:
- return !invertPredicate ? Hexagon::JMP_c :
- Hexagon::JMP_cNot;
- case Hexagon::JMP_EQrrPt_nv_V4:
- return !invertPredicate ? Hexagon::JMP_EQrrPt_nv_V4 :
- Hexagon::JMP_EQrrNotPt_nv_V4;
- case Hexagon::JMP_EQriPt_nv_V4:
- return !invertPredicate ? Hexagon::JMP_EQriPt_nv_V4 :
- Hexagon::JMP_EQriNotPt_nv_V4;
- case Hexagon::COMBINE_rr:
- return !invertPredicate ? Hexagon::COMBINE_rr_cPt :
- Hexagon::COMBINE_rr_cNotPt;
- case Hexagon::ASLH:
- return !invertPredicate ? Hexagon::ASLH_cPt_V4 :
- Hexagon::ASLH_cNotPt_V4;
- case Hexagon::ASRH:
- return !invertPredicate ? Hexagon::ASRH_cPt_V4 :
- Hexagon::ASRH_cNotPt_V4;
- case Hexagon::SXTB:
- return !invertPredicate ? Hexagon::SXTB_cPt_V4 :
- Hexagon::SXTB_cNotPt_V4;
- case Hexagon::SXTH:
- return !invertPredicate ? Hexagon::SXTH_cPt_V4 :
- Hexagon::SXTH_cNotPt_V4;
- case Hexagon::ZXTB:
- return !invertPredicate ? Hexagon::ZXTB_cPt_V4 :
- Hexagon::ZXTB_cNotPt_V4;
- case Hexagon::ZXTH:
- return !invertPredicate ? Hexagon::ZXTH_cPt_V4 :
- Hexagon::ZXTH_cNotPt_V4;
-
- case Hexagon::JMPR:
- return !invertPredicate ? Hexagon::JMPR_cPt :
- Hexagon::JMPR_cNotPt;
-
- // V4 indexed+scaled load.
- case Hexagon::LDrid_indexed_V4:
- return !invertPredicate ? Hexagon::LDrid_indexed_cPt_V4 :
- Hexagon::LDrid_indexed_cNotPt_V4;
- case Hexagon::LDrid_indexed_shl_V4:
- return !invertPredicate ? Hexagon::LDrid_indexed_shl_cPt_V4 :
- Hexagon::LDrid_indexed_shl_cNotPt_V4;
- case Hexagon::LDrib_indexed_V4:
- return !invertPredicate ? Hexagon::LDrib_indexed_cPt_V4 :
- Hexagon::LDrib_indexed_cNotPt_V4;
- case Hexagon::LDriub_indexed_V4:
- return !invertPredicate ? Hexagon::LDriub_indexed_cPt_V4 :
- Hexagon::LDriub_indexed_cNotPt_V4;
- case Hexagon::LDriub_ae_indexed_V4:
- return !invertPredicate ? Hexagon::LDriub_indexed_cPt_V4 :
- Hexagon::LDriub_indexed_cNotPt_V4;
- case Hexagon::LDrib_indexed_shl_V4:
- return !invertPredicate ? Hexagon::LDrib_indexed_shl_cPt_V4 :
- Hexagon::LDrib_indexed_shl_cNotPt_V4;
- case Hexagon::LDriub_indexed_shl_V4:
- return !invertPredicate ? Hexagon::LDriub_indexed_shl_cPt_V4 :
- Hexagon::LDriub_indexed_shl_cNotPt_V4;
- case Hexagon::LDriub_ae_indexed_shl_V4:
- return !invertPredicate ? Hexagon::LDriub_indexed_shl_cPt_V4 :
- Hexagon::LDriub_indexed_shl_cNotPt_V4;
- case Hexagon::LDrih_indexed_V4:
- return !invertPredicate ? Hexagon::LDrih_indexed_cPt_V4 :
- Hexagon::LDrih_indexed_cNotPt_V4;
- case Hexagon::LDriuh_indexed_V4:
- return !invertPredicate ? Hexagon::LDriuh_indexed_cPt_V4 :
- Hexagon::LDriuh_indexed_cNotPt_V4;
- case Hexagon::LDriuh_ae_indexed_V4:
- return !invertPredicate ? Hexagon::LDriuh_indexed_cPt_V4 :
- Hexagon::LDriuh_indexed_cNotPt_V4;
- case Hexagon::LDrih_indexed_shl_V4:
- return !invertPredicate ? Hexagon::LDrih_indexed_shl_cPt_V4 :
- Hexagon::LDrih_indexed_shl_cNotPt_V4;
- case Hexagon::LDriuh_indexed_shl_V4:
- return !invertPredicate ? Hexagon::LDriuh_indexed_shl_cPt_V4 :
- Hexagon::LDriuh_indexed_shl_cNotPt_V4;
- case Hexagon::LDriuh_ae_indexed_shl_V4:
- return !invertPredicate ? Hexagon::LDriuh_indexed_shl_cPt_V4 :
- Hexagon::LDriuh_indexed_shl_cNotPt_V4;
- case Hexagon::LDriw_indexed_V4:
- return !invertPredicate ? Hexagon::LDriw_indexed_cPt_V4 :
- Hexagon::LDriw_indexed_cNotPt_V4;
- case Hexagon::LDriw_indexed_shl_V4:
- return !invertPredicate ? Hexagon::LDriw_indexed_shl_cPt_V4 :
- Hexagon::LDriw_indexed_shl_cNotPt_V4;
-
- // V4 Load from global address
- case Hexagon::LDrid_GP_V4:
- return !invertPredicate ? Hexagon::LDrid_GP_cPt_V4 :
- Hexagon::LDrid_GP_cNotPt_V4;
- case Hexagon::LDrib_GP_V4:
- return !invertPredicate ? Hexagon::LDrib_GP_cPt_V4 :
- Hexagon::LDrib_GP_cNotPt_V4;
- case Hexagon::LDriub_GP_V4:
- return !invertPredicate ? Hexagon::LDriub_GP_cPt_V4 :
- Hexagon::LDriub_GP_cNotPt_V4;
- case Hexagon::LDrih_GP_V4:
- return !invertPredicate ? Hexagon::LDrih_GP_cPt_V4 :
- Hexagon::LDrih_GP_cNotPt_V4;
- case Hexagon::LDriuh_GP_V4:
- return !invertPredicate ? Hexagon::LDriuh_GP_cPt_V4 :
- Hexagon::LDriuh_GP_cNotPt_V4;
- case Hexagon::LDriw_GP_V4:
- return !invertPredicate ? Hexagon::LDriw_GP_cPt_V4 :
- Hexagon::LDriw_GP_cNotPt_V4;
-
- case Hexagon::LDd_GP_V4:
- return !invertPredicate ? Hexagon::LDd_GP_cPt_V4 :
- Hexagon::LDd_GP_cNotPt_V4;
- case Hexagon::LDb_GP_V4:
- return !invertPredicate ? Hexagon::LDb_GP_cPt_V4 :
- Hexagon::LDb_GP_cNotPt_V4;
- case Hexagon::LDub_GP_V4:
- return !invertPredicate ? Hexagon::LDub_GP_cPt_V4 :
- Hexagon::LDub_GP_cNotPt_V4;
- case Hexagon::LDh_GP_V4:
- return !invertPredicate ? Hexagon::LDh_GP_cPt_V4 :
- Hexagon::LDh_GP_cNotPt_V4;
- case Hexagon::LDuh_GP_V4:
- return !invertPredicate ? Hexagon::LDuh_GP_cPt_V4 :
- Hexagon::LDuh_GP_cNotPt_V4;
- case Hexagon::LDw_GP_V4:
- return !invertPredicate ? Hexagon::LDw_GP_cPt_V4 :
- Hexagon::LDw_GP_cNotPt_V4;
-
- // Byte.
- case Hexagon::POST_STbri:
- return !invertPredicate ? Hexagon::POST_STbri_cPt :
- Hexagon::POST_STbri_cNotPt;
- case Hexagon::STrib:
- return !invertPredicate ? Hexagon::STrib_cPt :
- Hexagon::STrib_cNotPt;
- case Hexagon::STrib_indexed:
- return !invertPredicate ? Hexagon::STrib_indexed_cPt :
- Hexagon::STrib_indexed_cNotPt;
- case Hexagon::STrib_imm_V4:
- return !invertPredicate ? Hexagon::STrib_imm_cPt_V4 :
- Hexagon::STrib_imm_cNotPt_V4;
- case Hexagon::STrib_indexed_shl_V4:
- return !invertPredicate ? Hexagon::STrib_indexed_shl_cPt_V4 :
- Hexagon::STrib_indexed_shl_cNotPt_V4;
- // Halfword.
- case Hexagon::POST_SThri:
- return !invertPredicate ? Hexagon::POST_SThri_cPt :
- Hexagon::POST_SThri_cNotPt;
- case Hexagon::STrih:
- return !invertPredicate ? Hexagon::STrih_cPt :
- Hexagon::STrih_cNotPt;
- case Hexagon::STrih_indexed:
- return !invertPredicate ? Hexagon::STrih_indexed_cPt :
- Hexagon::STrih_indexed_cNotPt;
- case Hexagon::STrih_imm_V4:
- return !invertPredicate ? Hexagon::STrih_imm_cPt_V4 :
- Hexagon::STrih_imm_cNotPt_V4;
- case Hexagon::STrih_indexed_shl_V4:
- return !invertPredicate ? Hexagon::STrih_indexed_shl_cPt_V4 :
- Hexagon::STrih_indexed_shl_cNotPt_V4;
+ case Hexagon::A2_combinew:
+ return !invertPredicate ? Hexagon::C2_ccombinewt :
+ Hexagon::C2_ccombinewf;
+
// Word.
- case Hexagon::POST_STwri:
- return !invertPredicate ? Hexagon::POST_STwri_cPt :
- Hexagon::POST_STwri_cNotPt;
- case Hexagon::STriw:
+ case Hexagon::STriw_f:
return !invertPredicate ? Hexagon::STriw_cPt :
Hexagon::STriw_cNotPt;
- case Hexagon::STriw_indexed:
+ case Hexagon::STriw_indexed_f:
return !invertPredicate ? Hexagon::STriw_indexed_cPt :
Hexagon::STriw_indexed_cNotPt;
- case Hexagon::STriw_indexed_shl_V4:
- return !invertPredicate ? Hexagon::STriw_indexed_shl_cPt_V4 :
- Hexagon::STriw_indexed_shl_cNotPt_V4;
- case Hexagon::STriw_imm_V4:
- return !invertPredicate ? Hexagon::STriw_imm_cPt_V4 :
- Hexagon::STriw_imm_cNotPt_V4;
- // Double word.
- case Hexagon::POST_STdri:
- return !invertPredicate ? Hexagon::POST_STdri_cPt :
- Hexagon::POST_STdri_cNotPt;
- case Hexagon::STrid:
- return !invertPredicate ? Hexagon::STrid_cPt :
- Hexagon::STrid_cNotPt;
- case Hexagon::STrid_indexed:
- return !invertPredicate ? Hexagon::STrid_indexed_cPt :
- Hexagon::STrid_indexed_cNotPt;
- case Hexagon::STrid_indexed_shl_V4:
- return !invertPredicate ? Hexagon::STrid_indexed_shl_cPt_V4 :
- Hexagon::STrid_indexed_shl_cNotPt_V4;
-
- // V4 Store to global address
- case Hexagon::STrid_GP_V4:
- return !invertPredicate ? Hexagon::STrid_GP_cPt_V4 :
- Hexagon::STrid_GP_cNotPt_V4;
- case Hexagon::STrib_GP_V4:
- return !invertPredicate ? Hexagon::STrib_GP_cPt_V4 :
- Hexagon::STrib_GP_cNotPt_V4;
- case Hexagon::STrih_GP_V4:
- return !invertPredicate ? Hexagon::STrih_GP_cPt_V4 :
- Hexagon::STrih_GP_cNotPt_V4;
- case Hexagon::STriw_GP_V4:
- return !invertPredicate ? Hexagon::STriw_GP_cPt_V4 :
- Hexagon::STriw_GP_cNotPt_V4;
-
- case Hexagon::STd_GP_V4:
- return !invertPredicate ? Hexagon::STd_GP_cPt_V4 :
- Hexagon::STd_GP_cNotPt_V4;
- case Hexagon::STb_GP_V4:
- return !invertPredicate ? Hexagon::STb_GP_cPt_V4 :
- Hexagon::STb_GP_cNotPt_V4;
- case Hexagon::STh_GP_V4:
- return !invertPredicate ? Hexagon::STh_GP_cPt_V4 :
- Hexagon::STh_GP_cNotPt_V4;
- case Hexagon::STw_GP_V4:
- return !invertPredicate ? Hexagon::STw_GP_cPt_V4 :
- Hexagon::STw_GP_cNotPt_V4;
-
- // Load.
- case Hexagon::LDrid:
- return !invertPredicate ? Hexagon::LDrid_cPt :
- Hexagon::LDrid_cNotPt;
- case Hexagon::LDriw:
- return !invertPredicate ? Hexagon::LDriw_cPt :
- Hexagon::LDriw_cNotPt;
- case Hexagon::LDrih:
- return !invertPredicate ? Hexagon::LDrih_cPt :
- Hexagon::LDrih_cNotPt;
- case Hexagon::LDriuh:
- return !invertPredicate ? Hexagon::LDriuh_cPt :
- Hexagon::LDriuh_cNotPt;
- case Hexagon::LDrib:
- return !invertPredicate ? Hexagon::LDrib_cPt :
- Hexagon::LDrib_cNotPt;
- case Hexagon::LDriub:
- return !invertPredicate ? Hexagon::LDriub_cPt :
- Hexagon::LDriub_cNotPt;
- // Load Indexed.
- case Hexagon::LDrid_indexed:
- return !invertPredicate ? Hexagon::LDrid_indexed_cPt :
- Hexagon::LDrid_indexed_cNotPt;
- case Hexagon::LDriw_indexed:
- return !invertPredicate ? Hexagon::LDriw_indexed_cPt :
- Hexagon::LDriw_indexed_cNotPt;
- case Hexagon::LDrih_indexed:
- return !invertPredicate ? Hexagon::LDrih_indexed_cPt :
- Hexagon::LDrih_indexed_cNotPt;
- case Hexagon::LDriuh_indexed:
- return !invertPredicate ? Hexagon::LDriuh_indexed_cPt :
- Hexagon::LDriuh_indexed_cNotPt;
- case Hexagon::LDrib_indexed:
- return !invertPredicate ? Hexagon::LDrib_indexed_cPt :
- Hexagon::LDrib_indexed_cNotPt;
- case Hexagon::LDriub_indexed:
- return !invertPredicate ? Hexagon::LDriub_indexed_cPt :
- Hexagon::LDriub_indexed_cNotPt;
- // Post Increment Load.
- case Hexagon::POST_LDrid:
- return !invertPredicate ? Hexagon::POST_LDrid_cPt :
- Hexagon::POST_LDrid_cNotPt;
- case Hexagon::POST_LDriw:
- return !invertPredicate ? Hexagon::POST_LDriw_cPt :
- Hexagon::POST_LDriw_cNotPt;
- case Hexagon::POST_LDrih:
- return !invertPredicate ? Hexagon::POST_LDrih_cPt :
- Hexagon::POST_LDrih_cNotPt;
- case Hexagon::POST_LDriuh:
- return !invertPredicate ? Hexagon::POST_LDriuh_cPt :
- Hexagon::POST_LDriuh_cNotPt;
- case Hexagon::POST_LDrib:
- return !invertPredicate ? Hexagon::POST_LDrib_cPt :
- Hexagon::POST_LDrib_cNotPt;
- case Hexagon::POST_LDriub:
- return !invertPredicate ? Hexagon::POST_LDriub_cPt :
- Hexagon::POST_LDriub_cNotPt;
+
// DEALLOC_RETURN.
case Hexagon::DEALLOC_RET_V4:
return !invertPredicate ? Hexagon::DEALLOC_RET_cPt_V4 :
assert (isPredicable(MI) && "Expected predicable instruction");
bool invertJump = (!Cond.empty() && Cond[0].isImm() &&
(Cond[0].getImm() == 0));
+
+ // This will change MI's opcode to its predicate version.
+ // However, its operand list is still the old one, i.e. the
+ // non-predicate one.
MI->setDesc(get(getMatchingCondBranchOpcode(Opc, invertJump)));
- //
- // This assumes that the predicate is always the first operand
- // in the set of inputs.
- //
- MI->addOperand(MI->getOperand(MI->getNumOperands()-1));
- int oper;
- for (oper = MI->getNumOperands() - 3; oper >= 0; --oper) {
- MachineOperand MO = MI->getOperand(oper);
- if ((MO.isReg() && !MO.isUse() && !MO.isImplicit())) {
- break;
- }
- if (MO.isReg()) {
- MI->getOperand(oper+1).ChangeToRegister(MO.getReg(), MO.isDef(),
- MO.isImplicit(), MO.isKill(),
- MO.isDead(), MO.isUndef(),
- MO.isDebug());
- } else if (MO.isImm()) {
- MI->getOperand(oper+1).ChangeToImmediate(MO.getImm());
- } else {
- llvm_unreachable("Unexpected operand type");
+ int oper = -1;
+ unsigned int GAIdx = 0;
+
+ // Indicates whether the current MI has a GlobalAddress operand
+ bool hasGAOpnd = false;
+ std::vector<MachineOperand> tmpOpnds;
+
+ // Indicates whether we need to shift operands to right.
+ bool needShift = true;
+
+ // The predicate is ALWAYS the FIRST input operand !!!
+ if (MI->getNumOperands() == 0) {
+ // The non-predicate version of MI does not take any operands,
+ // i.e. no outs and no ins. In this condition, the predicate
+ // operand will be directly placed at Operands[0]. No operand
+ // shift is needed.
+ // Example: BARRIER
+ needShift = false;
+ oper = -1;
+ }
+ else if ( MI->getOperand(MI->getNumOperands()-1).isReg()
+ && MI->getOperand(MI->getNumOperands()-1).isDef()
+ && !MI->getOperand(MI->getNumOperands()-1).isImplicit()) {
+ // The non-predicate version of MI does not have any input operands.
+ // In this condition, we extend the length of Operands[] by one and
+ // copy the original last operand to the newly allocated slot.
+ // At this moment, it is just a place holder. Later, we will put
+ // predicate operand directly into it. No operand shift is needed.
+ // Example: r0=BARRIER (this is a faked insn used here for illustration)
+ MI->addOperand(MI->getOperand(MI->getNumOperands()-1));
+ needShift = false;
+ oper = MI->getNumOperands() - 2;
+ }
+ else {
+ // We need to right shift all input operands by one. Duplicate the
+ // last operand into the newly allocated slot.
+ MI->addOperand(MI->getOperand(MI->getNumOperands()-1));
+ }
+
+ if (needShift)
+ {
+ // Operands[ MI->getNumOperands() - 2 ] has been copied into
+ // Operands[ MI->getNumOperands() - 1 ], so we start from
+ // Operands[ MI->getNumOperands() - 3 ].
+ // oper is a signed int.
+ // It is ok if "MI->getNumOperands()-3" is -3, -2, or -1.
+ for (oper = MI->getNumOperands() - 3; oper >= 0; --oper)
+ {
+ MachineOperand &MO = MI->getOperand(oper);
+
+ // Opnd[0] Opnd[1] Opnd[2] Opnd[3] Opnd[4] Opnd[5] Opnd[6] Opnd[7]
+ // <Def0> <Def1> <Use0> <Use1> <ImpDef0> <ImpDef1> <ImpUse0> <ImpUse1>
+ // /\~
+ // /||\~
+ // ||
+ // Predicate Operand here
+ if (MO.isReg() && !MO.isUse() && !MO.isImplicit()) {
+ break;
+ }
+ if (MO.isReg()) {
+ MI->getOperand(oper+1).ChangeToRegister(MO.getReg(), MO.isDef(),
+ MO.isImplicit(), MO.isKill(),
+ MO.isDead(), MO.isUndef(),
+ MO.isDebug());
+ }
+ else if (MO.isImm()) {
+ MI->getOperand(oper+1).ChangeToImmediate(MO.getImm());
+ }
+ else if (MO.isGlobal()) {
+ // MI can not have more than one GlobalAddress operand.
+ assert(hasGAOpnd == false && "MI can only have one GlobalAddress opnd");
+
+ // There is no member function called "ChangeToGlobalAddress" in the
+ // MachineOperand class (not like "ChangeToRegister" and
+ // "ChangeToImmediate"). So we have to remove them from Operands[] list
+ // first, and then add them back after we have inserted the predicate
+ // operand. tmpOpnds[] is to remember these operands before we remove
+ // them.
+ tmpOpnds.push_back(MO);
+
+ // Operands[oper] is a GlobalAddress operand;
+ // Operands[oper+1] has been copied into Operands[oper+2];
+ hasGAOpnd = true;
+ GAIdx = oper;
+ continue;
+ }
+ else {
+ assert(false && "Unexpected operand type");
+ }
}
}
int regPos = invertJump ? 1 : 0;
MachineOperand PredMO = Cond[regPos];
+
+ // [oper] now points to the last explicit Def. Predicate operand must be
+ // located at [oper+1]. See diagram above.
+ // This assumes that the predicate is always the first operand,
+ // i.e. Operands[0+numResults], in the set of inputs
+ // It is better to have an assert here to check this. But I don't know how
+ // to write this assert because findFirstPredOperandIdx() would return -1
+ if (oper < -1) oper = -1;
+
MI->getOperand(oper+1).ChangeToRegister(PredMO.getReg(), PredMO.isDef(),
- PredMO.isImplicit(), PredMO.isKill(),
+ PredMO.isImplicit(), false,
PredMO.isDead(), PredMO.isUndef(),
PredMO.isDebug());
+ MachineRegisterInfo &RegInfo = MI->getParent()->getParent()->getRegInfo();
+ RegInfo.clearKillFlags(PredMO.getReg());
+
+ if (hasGAOpnd)
+ {
+ unsigned int i;
+
+ // Operands[GAIdx] is the original GlobalAddress operand, which is
+ // already copied into tmpOpnds[0].
+ // Operands[GAIdx] now stores a copy of Operands[GAIdx-1]
+ // Operands[GAIdx+1] has already been copied into Operands[GAIdx+2],
+ // so we start from [GAIdx+2]
+ for (i = GAIdx + 2; i < MI->getNumOperands(); ++i)
+ tmpOpnds.push_back(MI->getOperand(i));
+
+ // Remove all operands in range [ (GAIdx+1) ... (MI->getNumOperands()-1) ]
+ // It is very important that we always remove from the end of Operands[]
+ // MI->getNumOperands() is at least 2 if program goes to here.
+ for (i = MI->getNumOperands() - 1; i > GAIdx; --i)
+ MI->RemoveOperand(i);
+
+ for (i = 0; i < tmpOpnds.size(); ++i)
+ MI->addOperand(tmpOpnds[i]);
+ }
+
return true;
}
return true;
}
-
+// Returns true if an instruction is predicated irrespective of the predicate
+// sense. For example, all of the following will return true.
+// if (p0) R1 = add(R2, R3)
+// if (!p0) R1 = add(R2, R3)
+// if (p0.new) R1 = add(R2, R3)
+// if (!p0.new) R1 = add(R2, R3)
bool HexagonInstrInfo::isPredicated(const MachineInstr *MI) const {
const uint64_t F = MI->getDesc().TSFlags;
return ((F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask);
}
+bool HexagonInstrInfo::isPredicated(unsigned Opcode) const {
+ const uint64_t F = get(Opcode).TSFlags;
+
+ return ((F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask);
+}
+
+bool HexagonInstrInfo::isPredicatedTrue(const MachineInstr *MI) const {
+ const uint64_t F = MI->getDesc().TSFlags;
+
+ assert(isPredicated(MI));
+ return (!((F >> HexagonII::PredicatedFalsePos) &
+ HexagonII::PredicatedFalseMask));
+}
+
+bool HexagonInstrInfo::isPredicatedTrue(unsigned Opcode) const {
+ const uint64_t F = get(Opcode).TSFlags;
+
+ // Make sure that the instruction is predicated.
+ assert((F>> HexagonII::PredicatedPos) & HexagonII::PredicatedMask);
+ return (!((F >> HexagonII::PredicatedFalsePos) &
+ HexagonII::PredicatedFalseMask));
+}
+
+bool HexagonInstrInfo::isPredicatedNew(const MachineInstr *MI) const {
+ const uint64_t F = MI->getDesc().TSFlags;
+
+ assert(isPredicated(MI));
+ return ((F >> HexagonII::PredicatedNewPos) & HexagonII::PredicatedNewMask);
+}
+
+bool HexagonInstrInfo::isPredicatedNew(unsigned Opcode) const {
+ const uint64_t F = get(Opcode).TSFlags;
+
+ assert(isPredicated(Opcode));
+ return ((F >> HexagonII::PredicatedNewPos) & HexagonII::PredicatedNewMask);
+}
+
+// Returns true, if a ST insn can be promoted to a new-value store.
+bool HexagonInstrInfo::mayBeNewStore(const MachineInstr *MI) const {
+ const HexagonRegisterInfo& QRI = getRegisterInfo();
+ const uint64_t F = MI->getDesc().TSFlags;
+
+ return ((F >> HexagonII::mayNVStorePos) &
+ HexagonII::mayNVStoreMask &
+ QRI.Subtarget.hasV4TOps());
+}
+
bool
HexagonInstrInfo::DefinesPredicate(MachineInstr *MI,
std::vector<MachineOperand> &Pred) const {
// the given "Opcode". If "Offset" is not in the correct range, "ADD_ri" is
// inserted to calculate the final address. Due to this reason, the function
// assumes that the "Offset" has correct alignment.
+ // We used to assert if the offset was not properly aligned, however,
+ // there are cases where a misaligned pointer recast can cause this
+ // problem, and we need to allow for it. The front end warns of such
+ // misaligns with respect to load size.
switch(Opcode) {
case Hexagon::LDriw:
+ case Hexagon::LDriw_indexed:
case Hexagon::LDriw_f:
+ case Hexagon::STriw_indexed:
case Hexagon::STriw:
case Hexagon::STriw_f:
- assert((Offset % 4 == 0) && "Offset has incorrect alignment");
return (Offset >= Hexagon_MEMW_OFFSET_MIN) &&
(Offset <= Hexagon_MEMW_OFFSET_MAX);
case Hexagon::LDrid:
+ case Hexagon::LDrid_indexed:
case Hexagon::LDrid_f:
case Hexagon::STrid:
+ case Hexagon::STrid_indexed:
case Hexagon::STrid_f:
- assert((Offset % 8 == 0) && "Offset has incorrect alignment");
return (Offset >= Hexagon_MEMD_OFFSET_MIN) &&
(Offset <= Hexagon_MEMD_OFFSET_MAX);
case Hexagon::LDrih:
case Hexagon::LDriuh:
case Hexagon::STrih:
- assert((Offset % 2 == 0) && "Offset has incorrect alignment");
return (Offset >= Hexagon_MEMH_OFFSET_MIN) &&
(Offset <= Hexagon_MEMH_OFFSET_MAX);
- case Hexagon::LDrib:
+ case Hexagon::L2_loadrb_io:
case Hexagon::STrib:
- case Hexagon::LDriub:
+ case Hexagon::L2_loadrub_io:
return (Offset >= Hexagon_MEMB_OFFSET_MIN) &&
(Offset <= Hexagon_MEMB_OFFSET_MAX);
return (Offset >= Hexagon_ADDI_OFFSET_MIN) &&
(Offset <= Hexagon_ADDI_OFFSET_MAX);
- case Hexagon::MEMw_ADDi_indexed_MEM_V4 :
- case Hexagon::MEMw_SUBi_indexed_MEM_V4 :
- case Hexagon::MEMw_ADDr_indexed_MEM_V4 :
- case Hexagon::MEMw_SUBr_indexed_MEM_V4 :
- case Hexagon::MEMw_ANDr_indexed_MEM_V4 :
- case Hexagon::MEMw_ORr_indexed_MEM_V4 :
- case Hexagon::MEMw_ADDi_MEM_V4 :
- case Hexagon::MEMw_SUBi_MEM_V4 :
- case Hexagon::MEMw_ADDr_MEM_V4 :
- case Hexagon::MEMw_SUBr_MEM_V4 :
- case Hexagon::MEMw_ANDr_MEM_V4 :
- case Hexagon::MEMw_ORr_MEM_V4 :
- assert ((Offset % 4) == 0 && "MEMOPw offset is not aligned correctly." );
+ case Hexagon::MemOPw_ADDi_V4 :
+ case Hexagon::MemOPw_SUBi_V4 :
+ case Hexagon::MemOPw_ADDr_V4 :
+ case Hexagon::MemOPw_SUBr_V4 :
+ case Hexagon::MemOPw_ANDr_V4 :
+ case Hexagon::MemOPw_ORr_V4 :
return (0 <= Offset && Offset <= 255);
- case Hexagon::MEMh_ADDi_indexed_MEM_V4 :
- case Hexagon::MEMh_SUBi_indexed_MEM_V4 :
- case Hexagon::MEMh_ADDr_indexed_MEM_V4 :
- case Hexagon::MEMh_SUBr_indexed_MEM_V4 :
- case Hexagon::MEMh_ANDr_indexed_MEM_V4 :
- case Hexagon::MEMh_ORr_indexed_MEM_V4 :
- case Hexagon::MEMh_ADDi_MEM_V4 :
- case Hexagon::MEMh_SUBi_MEM_V4 :
- case Hexagon::MEMh_ADDr_MEM_V4 :
- case Hexagon::MEMh_SUBr_MEM_V4 :
- case Hexagon::MEMh_ANDr_MEM_V4 :
- case Hexagon::MEMh_ORr_MEM_V4 :
- assert ((Offset % 2) == 0 && "MEMOPh offset is not aligned correctly." );
+ case Hexagon::MemOPh_ADDi_V4 :
+ case Hexagon::MemOPh_SUBi_V4 :
+ case Hexagon::MemOPh_ADDr_V4 :
+ case Hexagon::MemOPh_SUBr_V4 :
+ case Hexagon::MemOPh_ANDr_V4 :
+ case Hexagon::MemOPh_ORr_V4 :
return (0 <= Offset && Offset <= 127);
- case Hexagon::MEMb_ADDi_indexed_MEM_V4 :
- case Hexagon::MEMb_SUBi_indexed_MEM_V4 :
- case Hexagon::MEMb_ADDr_indexed_MEM_V4 :
- case Hexagon::MEMb_SUBr_indexed_MEM_V4 :
- case Hexagon::MEMb_ANDr_indexed_MEM_V4 :
- case Hexagon::MEMb_ORr_indexed_MEM_V4 :
- case Hexagon::MEMb_ADDi_MEM_V4 :
- case Hexagon::MEMb_SUBi_MEM_V4 :
- case Hexagon::MEMb_ADDr_MEM_V4 :
- case Hexagon::MEMb_SUBr_MEM_V4 :
- case Hexagon::MEMb_ANDr_MEM_V4 :
- case Hexagon::MEMb_ORr_MEM_V4 :
+ case Hexagon::MemOPb_ADDi_V4 :
+ case Hexagon::MemOPb_SUBi_V4 :
+ case Hexagon::MemOPb_ADDr_V4 :
+ case Hexagon::MemOPb_SUBr_V4 :
+ case Hexagon::MemOPb_ANDr_V4 :
+ case Hexagon::MemOPb_ORr_V4 :
return (0 <= Offset && Offset <= 63);
// LDri_pred and STriw_pred are pseudo operations, so it has to take offset of
case Hexagon::LDriw_pred:
return true;
+ case Hexagon::J2_loop0i:
+ return isUInt<10>(Offset);
+
// INLINEASM is very special.
case Hexagon::INLINEASM:
return true;
bool HexagonInstrInfo::
isMemOp(const MachineInstr *MI) const {
+// return MI->getDesc().mayLoad() && MI->getDesc().mayStore();
+
switch (MI->getOpcode())
{
default: return false;
- case Hexagon::MEMw_ADDi_indexed_MEM_V4 :
- case Hexagon::MEMw_SUBi_indexed_MEM_V4 :
- case Hexagon::MEMw_ADDr_indexed_MEM_V4 :
- case Hexagon::MEMw_SUBr_indexed_MEM_V4 :
- case Hexagon::MEMw_ANDr_indexed_MEM_V4 :
- case Hexagon::MEMw_ORr_indexed_MEM_V4 :
- case Hexagon::MEMw_ADDi_MEM_V4 :
- case Hexagon::MEMw_SUBi_MEM_V4 :
- case Hexagon::MEMw_ADDr_MEM_V4 :
- case Hexagon::MEMw_SUBr_MEM_V4 :
- case Hexagon::MEMw_ANDr_MEM_V4 :
- case Hexagon::MEMw_ORr_MEM_V4 :
- case Hexagon::MEMh_ADDi_indexed_MEM_V4 :
- case Hexagon::MEMh_SUBi_indexed_MEM_V4 :
- case Hexagon::MEMh_ADDr_indexed_MEM_V4 :
- case Hexagon::MEMh_SUBr_indexed_MEM_V4 :
- case Hexagon::MEMh_ANDr_indexed_MEM_V4 :
- case Hexagon::MEMh_ORr_indexed_MEM_V4 :
- case Hexagon::MEMh_ADDi_MEM_V4 :
- case Hexagon::MEMh_SUBi_MEM_V4 :
- case Hexagon::MEMh_ADDr_MEM_V4 :
- case Hexagon::MEMh_SUBr_MEM_V4 :
- case Hexagon::MEMh_ANDr_MEM_V4 :
- case Hexagon::MEMh_ORr_MEM_V4 :
- case Hexagon::MEMb_ADDi_indexed_MEM_V4 :
- case Hexagon::MEMb_SUBi_indexed_MEM_V4 :
- case Hexagon::MEMb_ADDr_indexed_MEM_V4 :
- case Hexagon::MEMb_SUBr_indexed_MEM_V4 :
- case Hexagon::MEMb_ANDr_indexed_MEM_V4 :
- case Hexagon::MEMb_ORr_indexed_MEM_V4 :
- case Hexagon::MEMb_ADDi_MEM_V4 :
- case Hexagon::MEMb_SUBi_MEM_V4 :
- case Hexagon::MEMb_ADDr_MEM_V4 :
- case Hexagon::MEMb_SUBr_MEM_V4 :
- case Hexagon::MEMb_ANDr_MEM_V4 :
- case Hexagon::MEMb_ORr_MEM_V4 :
- return true;
+ case Hexagon::MemOPw_ADDi_V4 :
+ case Hexagon::MemOPw_SUBi_V4 :
+ case Hexagon::MemOPw_ADDr_V4 :
+ case Hexagon::MemOPw_SUBr_V4 :
+ case Hexagon::MemOPw_ANDr_V4 :
+ case Hexagon::MemOPw_ORr_V4 :
+ case Hexagon::MemOPh_ADDi_V4 :
+ case Hexagon::MemOPh_SUBi_V4 :
+ case Hexagon::MemOPh_ADDr_V4 :
+ case Hexagon::MemOPh_SUBr_V4 :
+ case Hexagon::MemOPh_ANDr_V4 :
+ case Hexagon::MemOPh_ORr_V4 :
+ case Hexagon::MemOPb_ADDi_V4 :
+ case Hexagon::MemOPb_SUBi_V4 :
+ case Hexagon::MemOPb_ADDr_V4 :
+ case Hexagon::MemOPb_SUBr_V4 :
+ case Hexagon::MemOPb_ANDr_V4 :
+ case Hexagon::MemOPb_ORr_V4 :
+ case Hexagon::MemOPb_SETBITi_V4:
+ case Hexagon::MemOPh_SETBITi_V4:
+ case Hexagon::MemOPw_SETBITi_V4:
+ case Hexagon::MemOPb_CLRBITi_V4:
+ case Hexagon::MemOPh_CLRBITi_V4:
+ case Hexagon::MemOPw_CLRBITi_V4:
+ return true;
}
+ return false;
}
bool HexagonInstrInfo::isNewValueJumpCandidate(const MachineInstr *MI) const {
switch (MI->getOpcode()) {
default: return false;
- case Hexagon::CMPEQrr:
- case Hexagon::CMPEQri:
- case Hexagon::CMPLTrr:
- case Hexagon::CMPGTrr:
- case Hexagon::CMPGTri:
- case Hexagon::CMPLTUrr:
- case Hexagon::CMPGTUrr:
- case Hexagon::CMPGTUri:
- case Hexagon::CMPGEri:
- case Hexagon::CMPGEUri:
+ case Hexagon::C2_cmpeq:
+ case Hexagon::C2_cmpeqi:
+ case Hexagon::C2_cmpgt:
+ case Hexagon::C2_cmpgti:
+ case Hexagon::C2_cmpgtu:
+ case Hexagon::C2_cmpgtui:
return true;
}
}
isConditionalTransfer (const MachineInstr *MI) const {
switch (MI->getOpcode()) {
default: return false;
- case Hexagon::TFR_cPt:
- case Hexagon::TFR_cNotPt:
- case Hexagon::TFRI_cPt:
- case Hexagon::TFRI_cNotPt:
- case Hexagon::TFR_cdnPt:
- case Hexagon::TFR_cdnNotPt:
- case Hexagon::TFRI_cdnPt:
- case Hexagon::TFRI_cdnNotPt:
+ case Hexagon::A2_tfrt:
+ case Hexagon::A2_tfrf:
+ case Hexagon::C2_cmoveit:
+ case Hexagon::C2_cmoveif:
+ case Hexagon::A2_tfrtnew:
+ case Hexagon::A2_tfrfnew:
+ case Hexagon::C2_cmovenewit:
+ case Hexagon::C2_cmovenewif:
return true;
}
}
bool HexagonInstrInfo::isConditionalALU32 (const MachineInstr* MI) const {
- const HexagonRegisterInfo& QRI = getRegisterInfo();
switch (MI->getOpcode())
{
default: return false;
+ case Hexagon::A2_paddf:
+ case Hexagon::A2_paddfnew:
+ case Hexagon::A2_paddt:
+ case Hexagon::A2_paddtnew:
+ case Hexagon::A2_pandf:
+ case Hexagon::A2_pandfnew:
+ case Hexagon::A2_pandt:
+ case Hexagon::A2_pandtnew:
+ case Hexagon::A4_paslhf:
+ case Hexagon::A4_paslhfnew:
+ case Hexagon::A4_paslht:
+ case Hexagon::A4_paslhtnew:
+ case Hexagon::A4_pasrhf:
+ case Hexagon::A4_pasrhfnew:
+ case Hexagon::A4_pasrht:
+ case Hexagon::A4_pasrhtnew:
+ case Hexagon::A2_porf:
+ case Hexagon::A2_porfnew:
+ case Hexagon::A2_port:
+ case Hexagon::A2_portnew:
+ case Hexagon::A2_psubf:
+ case Hexagon::A2_psubfnew:
+ case Hexagon::A2_psubt:
+ case Hexagon::A2_psubtnew:
+ case Hexagon::A2_pxorf:
+ case Hexagon::A2_pxorfnew:
+ case Hexagon::A2_pxort:
+ case Hexagon::A2_pxortnew:
+ case Hexagon::A4_psxthf:
+ case Hexagon::A4_psxthfnew:
+ case Hexagon::A4_psxtht:
+ case Hexagon::A4_psxthtnew:
+ case Hexagon::A4_psxtbf:
+ case Hexagon::A4_psxtbfnew:
+ case Hexagon::A4_psxtbt:
+ case Hexagon::A4_psxtbtnew:
+ case Hexagon::A4_pzxtbf:
+ case Hexagon::A4_pzxtbfnew:
+ case Hexagon::A4_pzxtbt:
+ case Hexagon::A4_pzxtbtnew:
+ case Hexagon::A4_pzxthf:
+ case Hexagon::A4_pzxthfnew:
+ case Hexagon::A4_pzxtht:
+ case Hexagon::A4_pzxthtnew:
case Hexagon::ADD_ri_cPt:
case Hexagon::ADD_ri_cNotPt:
- case Hexagon::ADD_rr_cPt:
- case Hexagon::ADD_rr_cNotPt:
- case Hexagon::XOR_rr_cPt:
- case Hexagon::XOR_rr_cNotPt:
- case Hexagon::AND_rr_cPt:
- case Hexagon::AND_rr_cNotPt:
- case Hexagon::OR_rr_cPt:
- case Hexagon::OR_rr_cNotPt:
- case Hexagon::SUB_rr_cPt:
- case Hexagon::SUB_rr_cNotPt:
- case Hexagon::COMBINE_rr_cPt:
- case Hexagon::COMBINE_rr_cNotPt:
+ case Hexagon::C2_ccombinewt:
+ case Hexagon::C2_ccombinewf:
return true;
- case Hexagon::ASLH_cPt_V4:
- case Hexagon::ASLH_cNotPt_V4:
- case Hexagon::ASRH_cPt_V4:
- case Hexagon::ASRH_cNotPt_V4:
- case Hexagon::SXTB_cPt_V4:
- case Hexagon::SXTB_cNotPt_V4:
- case Hexagon::SXTH_cPt_V4:
- case Hexagon::SXTH_cNotPt_V4:
- case Hexagon::ZXTB_cPt_V4:
- case Hexagon::ZXTB_cNotPt_V4:
- case Hexagon::ZXTH_cPt_V4:
- case Hexagon::ZXTH_cNotPt_V4:
- return QRI.Subtarget.hasV4TOps();
}
}
case Hexagon::LDrih_cNotPt :
case Hexagon::LDrih_indexed_cPt :
case Hexagon::LDrih_indexed_cNotPt :
- case Hexagon::LDrib_cPt :
- case Hexagon::LDrib_cNotPt :
- case Hexagon::LDrib_indexed_cPt :
- case Hexagon::LDrib_indexed_cNotPt :
+ case Hexagon::L2_ploadrbt_io:
+ case Hexagon::L2_ploadrbf_io:
case Hexagon::LDriuh_cPt :
case Hexagon::LDriuh_cNotPt :
case Hexagon::LDriuh_indexed_cPt :
case Hexagon::LDriuh_indexed_cNotPt :
- case Hexagon::LDriub_cPt :
- case Hexagon::LDriub_cNotPt :
- case Hexagon::LDriub_indexed_cPt :
- case Hexagon::LDriub_indexed_cNotPt :
+ case Hexagon::L2_ploadrubt_io:
+ case Hexagon::L2_ploadrubf_io:
return true;
case Hexagon::POST_LDrid_cPt :
case Hexagon::POST_LDrid_cNotPt :
case Hexagon::POST_LDriub_cPt :
case Hexagon::POST_LDriub_cNotPt :
return QRI.Subtarget.hasV4TOps();
- case Hexagon::LDrid_indexed_cPt_V4 :
- case Hexagon::LDrid_indexed_cNotPt_V4 :
case Hexagon::LDrid_indexed_shl_cPt_V4 :
case Hexagon::LDrid_indexed_shl_cNotPt_V4 :
- case Hexagon::LDrib_indexed_cPt_V4 :
- case Hexagon::LDrib_indexed_cNotPt_V4 :
case Hexagon::LDrib_indexed_shl_cPt_V4 :
case Hexagon::LDrib_indexed_shl_cNotPt_V4 :
- case Hexagon::LDriub_indexed_cPt_V4 :
- case Hexagon::LDriub_indexed_cNotPt_V4 :
case Hexagon::LDriub_indexed_shl_cPt_V4 :
case Hexagon::LDriub_indexed_shl_cNotPt_V4 :
- case Hexagon::LDrih_indexed_cPt_V4 :
- case Hexagon::LDrih_indexed_cNotPt_V4 :
case Hexagon::LDrih_indexed_shl_cPt_V4 :
case Hexagon::LDrih_indexed_shl_cNotPt_V4 :
- case Hexagon::LDriuh_indexed_cPt_V4 :
- case Hexagon::LDriuh_indexed_cNotPt_V4 :
case Hexagon::LDriuh_indexed_shl_cPt_V4 :
case Hexagon::LDriuh_indexed_shl_cNotPt_V4 :
- case Hexagon::LDriw_indexed_cPt_V4 :
- case Hexagon::LDriw_indexed_cNotPt_V4 :
case Hexagon::LDriw_indexed_shl_cPt_V4 :
case Hexagon::LDriw_indexed_shl_cNotPt_V4 :
return QRI.Subtarget.hasV4TOps();
return QRI.Subtarget.hasV4TOps();
// V4 global address store before promoting to dot new.
- case Hexagon::STrid_GP_cPt_V4 :
- case Hexagon::STrid_GP_cNotPt_V4 :
- case Hexagon::STrib_GP_cPt_V4 :
- case Hexagon::STrib_GP_cNotPt_V4 :
- case Hexagon::STrih_GP_cPt_V4 :
- case Hexagon::STrih_GP_cNotPt_V4 :
- case Hexagon::STriw_GP_cPt_V4 :
- case Hexagon::STriw_GP_cNotPt_V4 :
case Hexagon::STd_GP_cPt_V4 :
case Hexagon::STd_GP_cNotPt_V4 :
case Hexagon::STb_GP_cPt_V4 :
}
+bool HexagonInstrInfo::isNewValueJump(const MachineInstr *MI) const {
+ if (isNewValue(MI) && isBranch(MI))
+ return true;
+ return false;
+}
+
+bool HexagonInstrInfo::isPostIncrement (const MachineInstr* MI) const {
+ return (getAddrMode(MI) == HexagonII::PostInc);
+}
+
+bool HexagonInstrInfo::isNewValue(const MachineInstr* MI) const {
+ const uint64_t F = MI->getDesc().TSFlags;
+ return ((F >> HexagonII::NewValuePos) & HexagonII::NewValueMask);
+}
+
+// Returns true, if any one of the operands is a dot new
+// insn, whether it is predicated dot new or register dot new.
+bool HexagonInstrInfo::isDotNewInst (const MachineInstr* MI) const {
+ return (isNewValueInst(MI) ||
+ (isPredicated(MI) && isPredicatedNew(MI)));
+}
+
+// Returns the most basic instruction for the .new predicated instructions and
+// new-value stores.
+// For example, all of the following instructions will be converted back to the
+// same instruction:
+// 1) if (p0.new) memw(R0+#0) = R1.new --->
+// 2) if (p0) memw(R0+#0)= R1.new -------> if (p0) memw(R0+#0) = R1
+// 3) if (p0.new) memw(R0+#0) = R1 --->
+//
+
+int HexagonInstrInfo::GetDotOldOp(const int opc) const {
+ int NewOp = opc;
+ if (isPredicated(NewOp) && isPredicatedNew(NewOp)) { // Get predicate old form
+ NewOp = Hexagon::getPredOldOpcode(NewOp);
+ assert(NewOp >= 0 &&
+ "Couldn't change predicate new instruction to its old form.");
+ }
+
+ if (isNewValueStore(NewOp)) { // Convert into non-new-value format
+ NewOp = Hexagon::getNonNVStore(NewOp);
+ assert(NewOp >= 0 && "Couldn't change new-value store to its old form.");
+ }
+ return NewOp;
+}
+
+// Return the new value instruction for a given store.
+int HexagonInstrInfo::GetDotNewOp(const MachineInstr* MI) const {
+ int NVOpcode = Hexagon::getNewValueOpcode(MI->getOpcode());
+ if (NVOpcode >= 0) // Valid new-value store instruction.
+ return NVOpcode;
+
+ switch (MI->getOpcode()) {
+ default: llvm_unreachable("Unknown .new type");
+ // store new value byte
+ case Hexagon::STrib_shl_V4:
+ return Hexagon::STrib_shl_nv_V4;
+
+ case Hexagon::STrih_shl_V4:
+ return Hexagon::STrih_shl_nv_V4;
+
+ case Hexagon::STriw_f:
+ return Hexagon::STriw_nv_V4;
+
+ case Hexagon::STriw_indexed_f:
+ return Hexagon::STriw_indexed_nv_V4;
+
+ case Hexagon::STriw_shl_V4:
+ return Hexagon::STriw_shl_nv_V4;
+
+ }
+ return 0;
+}
+
+// Return .new predicate version for an instruction.
+int HexagonInstrInfo::GetDotNewPredOp(MachineInstr *MI,
+ const MachineBranchProbabilityInfo
+ *MBPI) const {
+
+ int NewOpcode = Hexagon::getPredNewOpcode(MI->getOpcode());
+ if (NewOpcode >= 0) // Valid predicate new instruction
+ return NewOpcode;
+
+ switch (MI->getOpcode()) {
+ default: llvm_unreachable("Unknown .new type");
+ // Condtional Jumps
+ case Hexagon::J2_jumpt:
+ case Hexagon::J2_jumpf:
+ return getDotNewPredJumpOp(MI, MBPI);
+
+ case Hexagon::J2_jumprt:
+ return Hexagon::J2_jumptnewpt;
-DFAPacketizer *HexagonInstrInfo::
-CreateTargetScheduleState(const TargetMachine *TM,
- const ScheduleDAG *DAG) const {
- const InstrItineraryData *II = TM->getInstrItineraryData();
- return TM->getSubtarget<HexagonGenSubtargetInfo>().createDFAPacketizer(II);
+ case Hexagon::J2_jumprf:
+ return Hexagon::J2_jumprfnewpt;
+
+ case Hexagon::JMPrett:
+ return Hexagon::J2_jumprtnewpt;
+
+ case Hexagon::JMPretf:
+ return Hexagon::J2_jumprfnewpt;
+
+
+ // Conditional combine
+ case Hexagon::C2_ccombinewt:
+ return Hexagon::C2_ccombinewnewt;
+ case Hexagon::C2_ccombinewf:
+ return Hexagon::C2_ccombinewnewf;
+ }
+}
+
+
+unsigned HexagonInstrInfo::getAddrMode(const MachineInstr* MI) const {
+ const uint64_t F = MI->getDesc().TSFlags;
+
+ return((F >> HexagonII::AddrModePos) & HexagonII::AddrModeMask);
+}
+
+/// immediateExtend - Changes the instruction in place to one using an immediate
+/// extender.
+void HexagonInstrInfo::immediateExtend(MachineInstr *MI) const {
+ assert((isExtendable(MI)||isConstExtended(MI)) &&
+ "Instruction must be extendable");
+ // Find which operand is extendable.
+ short ExtOpNum = getCExtOpNum(MI);
+ MachineOperand &MO = MI->getOperand(ExtOpNum);
+ // This needs to be something we understand.
+ assert((MO.isMBB() || MO.isImm()) &&
+ "Branch with unknown extendable field type");
+ // Mark given operand as extended.
+ MO.addTargetFlag(HexagonII::HMOTF_ConstExtended);
+}
+
+DFAPacketizer *HexagonInstrInfo::CreateTargetScheduleState(
+ const TargetSubtargetInfo &STI) const {
+ const InstrItineraryData *II = STI.getInstrItineraryData();
+ return static_cast<const HexagonSubtarget &>(STI).createDFAPacketizer(II);
}
bool HexagonInstrInfo::isSchedulingBoundary(const MachineInstr *MI,
return false;
// Terminators and labels can't be scheduled around.
- if (MI->getDesc().isTerminator() || MI->isLabel() || MI->isInlineAsm())
+ if (MI->getDesc().isTerminator() || MI->isPosition() || MI->isInlineAsm())
+ return true;
+
+ return false;
+}
+
+bool HexagonInstrInfo::isConstExtended(MachineInstr *MI) const {
+
+ // Constant extenders are allowed only for V4 and above.
+ if (!Subtarget.hasV4TOps())
+ return false;
+
+ const uint64_t F = MI->getDesc().TSFlags;
+ unsigned isExtended = (F >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask;
+ if (isExtended) // Instruction must be extended.
+ return true;
+
+ unsigned isExtendable = (F >> HexagonII::ExtendablePos)
+ & HexagonII::ExtendableMask;
+ if (!isExtendable)
+ return false;
+
+ short ExtOpNum = getCExtOpNum(MI);
+ const MachineOperand &MO = MI->getOperand(ExtOpNum);
+ // Use MO operand flags to determine if MO
+ // has the HMOTF_ConstExtended flag set.
+ if (MO.getTargetFlags() && HexagonII::HMOTF_ConstExtended)
+ return true;
+ // If this is a Machine BB address we are talking about, and it is
+ // not marked as extended, say so.
+ if (MO.isMBB())
+ return false;
+
+ // We could be using an instruction with an extendable immediate and shoehorn
+ // a global address into it. If it is a global address it will be constant
+ // extended. We do this for COMBINE.
+ // We currently only handle isGlobal() because it is the only kind of
+ // object we are going to end up with here for now.
+ // In the future we probably should add isSymbol(), etc.
+ if (MO.isGlobal() || MO.isSymbol())
+ return true;
+
+ // If the extendable operand is not 'Immediate' type, the instruction should
+ // have 'isExtended' flag set.
+ assert(MO.isImm() && "Extendable operand must be Immediate type");
+
+ int MinValue = getMinValue(MI);
+ int MaxValue = getMaxValue(MI);
+ int ImmValue = MO.getImm();
+
+ return (ImmValue < MinValue || ImmValue > MaxValue);
+}
+
+// Returns the opcode to use when converting MI, which is a conditional jump,
+// into a conditional instruction which uses the .new value of the predicate.
+// We also use branch probabilities to add a hint to the jump.
+int
+HexagonInstrInfo::getDotNewPredJumpOp(MachineInstr *MI,
+ const
+ MachineBranchProbabilityInfo *MBPI) const {
+
+ // We assume that block can have at most two successors.
+ bool taken = false;
+ MachineBasicBlock *Src = MI->getParent();
+ MachineOperand *BrTarget = &MI->getOperand(1);
+ MachineBasicBlock *Dst = BrTarget->getMBB();
+
+ const BranchProbability Prediction = MBPI->getEdgeProbability(Src, Dst);
+ if (Prediction >= BranchProbability(1,2))
+ taken = true;
+
+ switch (MI->getOpcode()) {
+ case Hexagon::J2_jumpt:
+ return taken ? Hexagon::J2_jumptnewpt : Hexagon::J2_jumptnew;
+ case Hexagon::J2_jumpf:
+ return taken ? Hexagon::J2_jumpfnewpt : Hexagon::J2_jumpfnew;
+
+ default:
+ llvm_unreachable("Unexpected jump instruction.");
+ }
+}
+// Returns true if a particular operand is extendable for an instruction.
+bool HexagonInstrInfo::isOperandExtended(const MachineInstr *MI,
+ unsigned short OperandNum) const {
+ // Constant extenders are allowed only for V4 and above.
+ if (!Subtarget.hasV4TOps())
+ return false;
+
+ const uint64_t F = MI->getDesc().TSFlags;
+
+ return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask)
+ == OperandNum;
+}
+
+// Returns Operand Index for the constant extended instruction.
+unsigned short HexagonInstrInfo::getCExtOpNum(const MachineInstr *MI) const {
+ const uint64_t F = MI->getDesc().TSFlags;
+ return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask);
+}
+
+// Returns the min value that doesn't need to be extended.
+int HexagonInstrInfo::getMinValue(const MachineInstr *MI) const {
+ const uint64_t F = MI->getDesc().TSFlags;
+ unsigned isSigned = (F >> HexagonII::ExtentSignedPos)
+ & HexagonII::ExtentSignedMask;
+ unsigned bits = (F >> HexagonII::ExtentBitsPos)
+ & HexagonII::ExtentBitsMask;
+
+ if (isSigned) // if value is signed
+ return -1U << (bits - 1);
+ else
+ return 0;
+}
+
+// Returns the max value that doesn't need to be extended.
+int HexagonInstrInfo::getMaxValue(const MachineInstr *MI) const {
+ const uint64_t F = MI->getDesc().TSFlags;
+ unsigned isSigned = (F >> HexagonII::ExtentSignedPos)
+ & HexagonII::ExtentSignedMask;
+ unsigned bits = (F >> HexagonII::ExtentBitsPos)
+ & HexagonII::ExtentBitsMask;
+
+ if (isSigned) // if value is signed
+ return ~(-1U << (bits - 1));
+ else
+ return ~(-1U << bits);
+}
+
+// Returns true if an instruction can be converted into a non-extended
+// equivalent instruction.
+bool HexagonInstrInfo::NonExtEquivalentExists (const MachineInstr *MI) const {
+
+ short NonExtOpcode;
+ // Check if the instruction has a register form that uses register in place
+ // of the extended operand, if so return that as the non-extended form.
+ if (Hexagon::getRegForm(MI->getOpcode()) >= 0)
return true;
+ if (MI->getDesc().mayLoad() || MI->getDesc().mayStore()) {
+ // Check addressing mode and retrieve non-ext equivalent instruction.
+
+ switch (getAddrMode(MI)) {
+ case HexagonII::Absolute :
+ // Load/store with absolute addressing mode can be converted into
+ // base+offset mode.
+ NonExtOpcode = Hexagon::getBasedWithImmOffset(MI->getOpcode());
+ break;
+ case HexagonII::BaseImmOffset :
+ // Load/store with base+offset addressing mode can be converted into
+ // base+register offset addressing mode. However left shift operand should
+ // be set to 0.
+ NonExtOpcode = Hexagon::getBaseWithRegOffset(MI->getOpcode());
+ break;
+ default:
+ return false;
+ }
+ if (NonExtOpcode < 0)
+ return false;
+ return true;
+ }
return false;
}
+
+// Returns opcode of the non-extended equivalent instruction.
+short HexagonInstrInfo::getNonExtOpcode (const MachineInstr *MI) const {
+
+ // Check if the instruction has a register form that uses register in place
+ // of the extended operand, if so return that as the non-extended form.
+ short NonExtOpcode = Hexagon::getRegForm(MI->getOpcode());
+ if (NonExtOpcode >= 0)
+ return NonExtOpcode;
+
+ if (MI->getDesc().mayLoad() || MI->getDesc().mayStore()) {
+ // Check addressing mode and retrieve non-ext equivalent instruction.
+ switch (getAddrMode(MI)) {
+ case HexagonII::Absolute :
+ return Hexagon::getBasedWithImmOffset(MI->getOpcode());
+ case HexagonII::BaseImmOffset :
+ return Hexagon::getBaseWithRegOffset(MI->getOpcode());
+ default:
+ return -1;
+ }
+ }
+ return -1;
+}
+
+bool HexagonInstrInfo::PredOpcodeHasJMP_c(Opcode_t Opcode) const {
+ return (Opcode == Hexagon::J2_jumpt) ||
+ (Opcode == Hexagon::J2_jumpf) ||
+ (Opcode == Hexagon::J2_jumptnewpt) ||
+ (Opcode == Hexagon::J2_jumpfnewpt) ||
+ (Opcode == Hexagon::J2_jumpt) ||
+ (Opcode == Hexagon::J2_jumpf);
+}
+
+bool HexagonInstrInfo::PredOpcodeHasNot(Opcode_t Opcode) const {
+ return (Opcode == Hexagon::J2_jumpf) ||
+ (Opcode == Hexagon::J2_jumpfnewpt) ||
+ (Opcode == Hexagon::J2_jumpfnew);
+}