//===----------------------------------------------------------------------===//
#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/MathExtras.h"
#define GET_INSTRINFO_CTOR
+#define GET_INSTRMAP_INFO
#include "HexagonGenInstrInfo.inc"
#include "HexagonGenDFAPacketizer.inc"
-#include "HexagonConstExtInfo.h"
using namespace llvm;
int &FrameIndex) const {
switch (MI->getOpcode()) {
default: break;
- case Hexagon::STriw_indexed:
case Hexagon::STriw:
case Hexagon::STrid:
case Hexagon::STrih:
MachineBasicBlock *&FBB,
SmallVectorImpl<MachineOperand> &Cond,
bool AllowModify) const {
+ TBB = NULL;
FBB = NULL;
// If the block has no terminators, it just falls into the block after it.
return;
}
if (Hexagon::DoubleRegsRegClass.contains(SrcReg, DestReg)) {
- BuildMI(MBB, I, DL, get(Hexagon::TFR_64), DestReg).addReg(SrcReg);
+ BuildMI(MBB, I, DL, get(Hexagon::TFR64), DestReg).addReg(SrcReg);
return;
}
if (Hexagon::PredRegsRegClass.contains(SrcReg, DestReg)) {
Align);
if (Hexagon::IntRegsRegClass.hasSubClassEq(RC)) {
- BuildMI(MBB, I, DL, get(Hexagon::STriw_indexed))
+ BuildMI(MBB, I, DL, get(Hexagon::STriw))
.addFrameIndex(FI).addImm(0)
.addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
} else if (Hexagon::DoubleRegsRegClass.hasSubClassEq(RC)) {
case Hexagon::TFR_FI:
return Hexagon::TFR_FI_immext_V4;
- case Hexagon::MEMw_ADDSUBi_indexed_MEM_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_ADDSUBi_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_ADDSUBi_indexed_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_ADDSUBi_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_ADDSUBi_indexed_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_ADDSUBi_MEM_V4 :
case Hexagon::MEMb_ADDi_MEM_V4 :
case Hexagon::MEMb_SUBi_MEM_V4 :
case Hexagon::MEMb_ADDr_MEM_V4 :
return false;
const int Opc = MI->getOpcode();
- int NumOperands = MI->getNumOperands();
-
- // Keep a flag for upto 4 operands in the instructions, to indicate if
- // that operand has been constant extended.
- bool OpCExtended[4];
- if (NumOperands > 4)
- NumOperands = 4;
-
- for (int i=0; i<NumOperands; i++)
- OpCExtended[i] = (HexagonConstExt::isOperandExtended(Opc, 1) &&
- isConstExtended(MI));
switch(Opc) {
case Hexagon::TFRI:
- // Return true if MI is constant extended as predicated form will also be
- // extended so immediate value doesn't have to fit within range.
- return OpCExtended[1] || isInt<12>(MI->getOperand(1).getImm());
+ return isInt<12>(MI->getOperand(1).getImm());
case Hexagon::STrid:
case Hexagon::STrid_indexed:
- return OpCExtended[1] || isShiftedUInt<6,3>(MI->getOperand(1).getImm());
+ return isShiftedUInt<6,3>(MI->getOperand(1).getImm());
case Hexagon::STriw:
case Hexagon::STriw_indexed:
case Hexagon::STriw_nv_V4:
- return OpCExtended[1] || isShiftedUInt<6,2>(MI->getOperand(1).getImm());
+ return isShiftedUInt<6,2>(MI->getOperand(1).getImm());
case Hexagon::STrih:
case Hexagon::STrih_indexed:
case Hexagon::STrih_nv_V4:
- return OpCExtended[1] || isShiftedUInt<6,1>(MI->getOperand(1).getImm());
+ return isShiftedUInt<6,1>(MI->getOperand(1).getImm());
case Hexagon::STrib:
case Hexagon::STrib_indexed:
case Hexagon::STrib_nv_V4:
- return OpCExtended[1] || isUInt<6>(MI->getOperand(1).getImm());
+ return isUInt<6>(MI->getOperand(1).getImm());
case Hexagon::LDrid:
case Hexagon::LDrid_indexed:
- return OpCExtended[2] || isShiftedUInt<6,3>(MI->getOperand(2).getImm());
+ return isShiftedUInt<6,3>(MI->getOperand(2).getImm());
case Hexagon::LDriw:
case Hexagon::LDriw_indexed:
- return OpCExtended[2] || isShiftedUInt<6,2>(MI->getOperand(2).getImm());
+ return isShiftedUInt<6,2>(MI->getOperand(2).getImm());
case Hexagon::LDrih:
case Hexagon::LDriuh:
case Hexagon::LDrih_indexed:
case Hexagon::LDriuh_indexed:
- return OpCExtended[2] || isShiftedUInt<6,1>(MI->getOperand(2).getImm());
+ return isShiftedUInt<6,1>(MI->getOperand(2).getImm());
case Hexagon::LDrib:
case Hexagon::LDriub:
case Hexagon::LDrib_indexed:
case Hexagon::LDriub_indexed:
- return OpCExtended[2] || isUInt<6>(MI->getOperand(2).getImm());
+ return isUInt<6>(MI->getOperand(2).getImm());
case Hexagon::POST_LDrid:
- return OpCExtended[3] || isShiftedInt<4,3>(MI->getOperand(3).getImm());
+ return isShiftedInt<4,3>(MI->getOperand(3).getImm());
case Hexagon::POST_LDriw:
- return OpCExtended[3] || isShiftedInt<4,2>(MI->getOperand(3).getImm());
+ return isShiftedInt<4,2>(MI->getOperand(3).getImm());
case Hexagon::POST_LDrih:
case Hexagon::POST_LDriuh:
- return OpCExtended[3] || isShiftedInt<4,1>(MI->getOperand(3).getImm());
+ return isShiftedInt<4,1>(MI->getOperand(3).getImm());
case Hexagon::POST_LDrib:
case Hexagon::POST_LDriub:
- return OpCExtended[3] || isInt<4>(MI->getOperand(3).getImm());
+ return isInt<4>(MI->getOperand(3).getImm());
case Hexagon::STrib_imm_V4:
case Hexagon::STrih_imm_V4:
case Hexagon::STriw_imm_V4:
- return ((OpCExtended[1] || isUInt<6>(MI->getOperand(1).getImm())) &&
- (OpCExtended[2] || isInt<6>(MI->getOperand(2).getImm())));
+ return (isUInt<6>(MI->getOperand(1).getImm()) &&
+ isInt<6>(MI->getOperand(2).getImm()));
case Hexagon::ADD_ri:
- return OpCExtended[2] || isInt<8>(MI->getOperand(2).getImm());
+ return isInt<8>(MI->getOperand(2).getImm());
case Hexagon::ASLH:
case Hexagon::ASRH:
int HexagonInstrInfo::
getMatchingCondBranchOpcode(int Opc, bool invertPredicate) const {
+ enum Hexagon::PredSense inPredSense;
+ inPredSense = invertPredicate ? Hexagon::PredSense_false :
+ Hexagon::PredSense_true;
+ int CondOpcode = Hexagon::getPredOpcode(Opc, inPredSense);
+ if (CondOpcode >= 0) // Valid Conditional opcode/instruction
+ return CondOpcode;
+
+ // 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 :
case Hexagon::JMP_EQriPt_nv_V4:
return !invertPredicate ? Hexagon::JMP_EQriPt_nv_V4 :
Hexagon::JMP_EQriNotPt_nv_V4;
- case Hexagon::ADD_ri:
- return !invertPredicate ? Hexagon::ADD_ri_cPt :
- Hexagon::ADD_ri_cNotPt;
- case Hexagon::ADD_rr:
- return !invertPredicate ? Hexagon::ADD_rr_cPt :
- Hexagon::ADD_rr_cNotPt;
- case Hexagon::XOR_rr:
- return !invertPredicate ? Hexagon::XOR_rr_cPt :
- Hexagon::XOR_rr_cNotPt;
- case Hexagon::AND_rr:
- return !invertPredicate ? Hexagon::AND_rr_cPt :
- Hexagon::AND_rr_cNotPt;
- case Hexagon::OR_rr:
- return !invertPredicate ? Hexagon::OR_rr_cPt :
- Hexagon::OR_rr_cNotPt;
- case Hexagon::SUB_rr:
- return !invertPredicate ? Hexagon::SUB_rr_cPt :
- Hexagon::SUB_rr_cNotPt;
case Hexagon::COMBINE_rr:
return !invertPredicate ? Hexagon::COMBINE_rr_cPt :
Hexagon::COMBINE_rr_cNotPt;
case Hexagon::DEALLOC_RET_V4:
return !invertPredicate ? Hexagon::DEALLOC_RET_cPt_V4 :
Hexagon::DEALLOC_RET_cNotPt_V4;
-
- // Load Absolute Addressing -- global address.
- case Hexagon::LDrib_abs_V4:
- return !invertPredicate ? Hexagon::LDrib_abs_cPt_V4 :
- Hexagon::LDrib_abs_cNotPt_V4;
- case Hexagon::LDriub_abs_V4:
- return !invertPredicate ? Hexagon::LDriub_abs_cPt_V4 :
- Hexagon::LDriub_abs_cNotPt_V4;
- case Hexagon::LDrih_abs_V4:
- return !invertPredicate ? Hexagon::LDrih_abs_cPt_V4 :
- Hexagon::LDrih_abs_cNotPt_V4;
- case Hexagon::LDriuh_abs_V4:
- return !invertPredicate ? Hexagon::LDriuh_abs_cPt_V4 :
- Hexagon::LDriuh_abs_cNotPt_V4;
- case Hexagon::LDriw_abs_V4:
- return !invertPredicate ? Hexagon::LDriw_abs_cPt_V4 :
- Hexagon::LDriw_abs_cNotPt_V4;
- case Hexagon::LDrid_abs_V4:
- return !invertPredicate ? Hexagon::LDrid_abs_cPt_V4 :
- Hexagon::LDrid_abs_cNotPt_V4;
-
- // Load Absolute Addressing -- immediate value.
- case Hexagon::LDrib_imm_abs_V4:
- return !invertPredicate ? Hexagon::LDrib_imm_abs_cPt_V4 :
- Hexagon::LDrib_imm_abs_cNotPt_V4;
- case Hexagon::LDriub_imm_abs_V4:
- return !invertPredicate ? Hexagon::LDriub_imm_abs_cPt_V4 :
- Hexagon::LDriub_imm_abs_cNotPt_V4;
- case Hexagon::LDrih_imm_abs_V4:
- return !invertPredicate ? Hexagon::LDrih_imm_abs_cPt_V4 :
- Hexagon::LDrih_imm_abs_cNotPt_V4;
- case Hexagon::LDriuh_imm_abs_V4:
- return !invertPredicate ? Hexagon::LDriuh_imm_abs_cPt_V4 :
- Hexagon::LDriuh_imm_abs_cNotPt_V4;
- case Hexagon::LDriw_imm_abs_V4:
- return !invertPredicate ? Hexagon::LDriw_imm_abs_cPt_V4 :
- Hexagon::LDriw_imm_abs_cNotPt_V4;
-
- // Store Absolute Addressing.
- case Hexagon::STrib_abs_V4:
- return !invertPredicate ? Hexagon::STrib_abs_cPt_V4 :
- Hexagon::STrib_abs_cNotPt_V4;
- case Hexagon::STrih_abs_V4:
- return !invertPredicate ? Hexagon::STrih_abs_cPt_V4 :
- Hexagon::STrih_abs_cNotPt_V4;
- case Hexagon::STriw_abs_V4:
- return !invertPredicate ? Hexagon::STriw_abs_cPt_V4 :
- Hexagon::STriw_abs_cNotPt_V4;
- case Hexagon::STrid_abs_V4:
- return !invertPredicate ? Hexagon::STrid_abs_cPt_V4 :
- Hexagon::STrid_abs_cNotPt_V4;
-
- // Store Absolute Addressing - global address.
- case Hexagon::STrib_imm_abs_V4:
- return !invertPredicate ? Hexagon::STrib_imm_abs_cPt_V4 :
- Hexagon::STrib_imm_abs_cNotPt_V4;
- case Hexagon::STrih_imm_abs_V4:
- return !invertPredicate ? Hexagon::STrih_imm_abs_cPt_V4 :
- Hexagon::STrih_imm_abs_cNotPt_V4;
- case Hexagon::STriw_imm_abs_V4:
- return !invertPredicate ? Hexagon::STriw_imm_abs_cPt_V4 :
- Hexagon::STriw_imm_abs_cNotPt_V4;
-
- // Transfer
- case Hexagon::TFRI_V4:
- return !invertPredicate ? Hexagon::TFRI_cPt_V4 :
- Hexagon::TFRI_cNotPt_V4;
}
llvm_unreachable("Unexpected predicable instruction");
}
bool
HexagonInstrInfo::
isProfitableToIfCvt(MachineBasicBlock &MBB,
- unsigned NumCyles,
+ unsigned NumCycles,
unsigned ExtraPredCycles,
const BranchProbability &Probability) const {
return true;
case Hexagon::LDriw:
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_ADDI_OFFSET_MIN) &&
(Offset <= Hexagon_ADDI_OFFSET_MAX);
- case Hexagon::MEMw_ADDSUBi_indexed_MEM_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_ADDSUBi_MEM_V4 :
case Hexagon::MEMw_ADDi_MEM_V4 :
case Hexagon::MEMw_SUBi_MEM_V4 :
case Hexagon::MEMw_ADDr_MEM_V4 :
assert ((Offset % 4) == 0 && "MEMOPw offset is not aligned correctly." );
return (0 <= Offset && Offset <= 255);
- case Hexagon::MEMh_ADDSUBi_indexed_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_ADDSUBi_MEM_V4 :
case Hexagon::MEMh_ADDi_MEM_V4 :
case Hexagon::MEMh_SUBi_MEM_V4 :
case Hexagon::MEMh_ADDr_MEM_V4 :
assert ((Offset % 2) == 0 && "MEMOPh offset is not aligned correctly." );
return (0 <= Offset && Offset <= 127);
- case Hexagon::MEMb_ADDSUBi_indexed_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_ADDSUBi_MEM_V4 :
case Hexagon::MEMb_ADDi_MEM_V4 :
case Hexagon::MEMb_SUBi_MEM_V4 :
case Hexagon::MEMb_ADDr_MEM_V4 :
switch (MI->getOpcode())
{
default: return false;
- case Hexagon::MEMw_ADDSUBi_indexed_MEM_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_ADDSUBi_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_ADDSUBi_indexed_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_ADDSUBi_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_ADDSUBi_indexed_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_ADDSUBi_MEM_V4 :
case Hexagon::MEMb_ADDi_MEM_V4 :
case Hexagon::MEMb_SUBi_MEM_V4 :
case Hexagon::MEMb_ADDr_MEM_V4 :
return false;
}
-
-bool HexagonInstrInfo::isExpr(unsigned OpType) const {
- switch(OpType) {
- case MachineOperand::MO_MachineBasicBlock:
- case MachineOperand::MO_GlobalAddress:
- case MachineOperand::MO_ExternalSymbol:
- case MachineOperand::MO_JumpTableIndex:
- case MachineOperand::MO_ConstantPoolIndex:
- case MachineOperand::MO_BlockAddress:
- return true;
- default:
- return false;
- }
-}
-
-bool HexagonInstrInfo::isConstExtended(MachineInstr *MI) const {
- unsigned short Opcode = MI->getOpcode();
- short ExtOpNum = HexagonConstExt::getCExtOpNum(Opcode);
-
- // Instruction has no constant extended operand.
- if (ExtOpNum == -1)
- return false;
-
-
- int MinValue = HexagonConstExt::getMinValue(Opcode);
- int MaxValue = HexagonConstExt::getMaxValue(Opcode);
- const MachineOperand &MO = MI->getOperand(ExtOpNum);
- if (!MO.isImm()) // no range check if the operand is non-immediate.
- return true;
-
- int ImmValue = MO.getImm();
- return (ImmValue < MinValue || ImmValue > MaxValue);
-
-}
-
-// Returns true if a particular operand is extended for an instruction.
-bool HexagonConstExt::isOperandExtended(unsigned short Opcode,
- unsigned short OperandNum) {
- return HexagonCExt[Opcode].CExtOpNum == OperandNum;
-}
-
-// Returns Operand Index for the constant extended instruction.
-unsigned short HexagonConstExt::getCExtOpNum(unsigned short Opcode) {
- return HexagonCExt[Opcode].CExtOpNum;
-}
-
-// Returns the min value that doesn't need to be extended.
-int HexagonConstExt::getMinValue(unsigned short Opcode) {
- return HexagonCExt[Opcode].MinValue;
-}
-
-// Returns the max value that doesn't need to be extended.
-int HexagonConstExt::getMaxValue(unsigned short Opcode) {
- return HexagonCExt[Opcode].MaxValue;
-}
-
-// Returns true if an instruction can be converted into a non-extended
-// equivalent instruction.
-bool HexagonConstExt::NonExtEquivalentExists (unsigned short Opcode) {
- if (HexagonCExt[Opcode].NonExtOpcode < 0 )
- return false;
- return true;
-}
-
-// Returns opcode of the non-extended equivalent instruction.
-int HexagonConstExt::getNonExtOpcode (unsigned short Opcode) {
- return HexagonCExt[Opcode].NonExtOpcode;
-}