[Hexagon] Updating rr/ri 32/64 transfer encodings and adding tests.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@223821 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Colin LeMahieu 2014-12-09 20:23:30 +00:00
parent b8755d9ddd
commit 20856353b8
11 changed files with 218 additions and 180 deletions

View File

@ -114,7 +114,7 @@ static bool isCombinableInstType(MachineInstr *MI,
const HexagonInstrInfo *TII,
bool ShouldCombineAggressively) {
switch(MI->getOpcode()) {
case Hexagon::TFR: {
case Hexagon::A2_tfr: {
// A COPY instruction can be combined if its arguments are IntRegs (32bit).
assert(MI->getOperand(0).isReg() && MI->getOperand(1).isReg());
@ -124,7 +124,7 @@ static bool isCombinableInstType(MachineInstr *MI,
Hexagon::IntRegsRegClass.contains(SrcReg);
}
case Hexagon::TFRI: {
case Hexagon::A2_tfrsi: {
// A transfer-immediate can be combined if its argument is a signed 8bit
// value.
assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm());
@ -158,11 +158,11 @@ static bool isCombinableInstType(MachineInstr *MI,
}
static bool isGreaterThan8BitTFRI(MachineInstr *I) {
return I->getOpcode() == Hexagon::TFRI &&
return I->getOpcode() == Hexagon::A2_tfrsi &&
!isInt<8>(I->getOperand(1).getImm());
}
static bool isGreaterThan6BitTFRI(MachineInstr *I) {
return I->getOpcode() == Hexagon::TFRI &&
return I->getOpcode() == Hexagon::A2_tfrsi &&
!isUInt<6>(I->getOperand(1).getImm());
}
@ -171,11 +171,11 @@ static bool isGreaterThan6BitTFRI(MachineInstr *I) {
static bool areCombinableOperations(const TargetRegisterInfo *TRI,
MachineInstr *HighRegInst,
MachineInstr *LowRegInst) {
assert((HighRegInst->getOpcode() == Hexagon::TFR ||
HighRegInst->getOpcode() == Hexagon::TFRI ||
assert((HighRegInst->getOpcode() == Hexagon::A2_tfr ||
HighRegInst->getOpcode() == Hexagon::A2_tfrsi ||
HighRegInst->getOpcode() == Hexagon::TFRI_V4) &&
(LowRegInst->getOpcode() == Hexagon::TFR ||
LowRegInst->getOpcode() == Hexagon::TFRI ||
(LowRegInst->getOpcode() == Hexagon::A2_tfr ||
LowRegInst->getOpcode() == Hexagon::A2_tfrsi ||
LowRegInst->getOpcode() == Hexagon::TFRI_V4) &&
"Assume individual instructions are of a combinable type");

View File

@ -172,7 +172,7 @@ void HexagonFixupHwLoops::convertLoopInstr(MachineFunction &MF,
.addReg(MII->getOperand(1).getReg());
} else {
// Trip count is an immediate.
BuildMI(*MBB, MII, DL, TII->get(Hexagon::TFRI), Scratch)
BuildMI(*MBB, MII, DL, TII->get(Hexagon::A2_tfrsi), Scratch)
.addImm(MII->getOperand(1).getImm());
BuildMI(*MBB, MII, DL, TII->get(Hexagon::TFCR), Hexagon::LC0)
.addReg(Scratch);

View File

@ -626,12 +626,12 @@ CountValue *HexagonHardwareLoops::computeCount(MachineLoop *Loop,
// If so, use the immediate value rather than the register.
if (Start->isReg()) {
const MachineInstr *StartValInstr = MRI->getVRegDef(Start->getReg());
if (StartValInstr && StartValInstr->getOpcode() == Hexagon::TFRI)
if (StartValInstr && StartValInstr->getOpcode() == Hexagon::A2_tfrsi)
Start = &StartValInstr->getOperand(1);
}
if (End->isReg()) {
const MachineInstr *EndValInstr = MRI->getVRegDef(End->getReg());
if (EndValInstr && EndValInstr->getOpcode() == Hexagon::TFRI)
if (EndValInstr && EndValInstr->getOpcode() == Hexagon::A2_tfrsi)
End = &EndValInstr->getOperand(1);
}
@ -1097,7 +1097,7 @@ bool HexagonHardwareLoops::convertToHardwareLoop(MachineLoop *L) {
int64_t CountImm = TripCount->getImm();
if (!TII->isValidOffset(Hexagon::LOOP0_i, CountImm)) {
unsigned CountReg = MRI->createVirtualRegister(&Hexagon::IntRegsRegClass);
BuildMI(*Preheader, InsertPos, DL, TII->get(Hexagon::TFRI), CountReg)
BuildMI(*Preheader, InsertPos, DL, TII->get(Hexagon::A2_tfrsi), CountReg)
.addImm(CountImm);
BuildMI(*Preheader, InsertPos, DL, TII->get(Hexagon::LOOP0_r))
.addMBB(LoopStart).addReg(CountReg);
@ -1194,7 +1194,7 @@ MachineInstr *HexagonHardwareLoops::defWithImmediate(unsigned R) {
MachineInstr *DI = MRI->getVRegDef(R);
unsigned DOpc = DI->getOpcode();
switch (DOpc) {
case Hexagon::TFRI:
case Hexagon::A2_tfrsi:
case Hexagon::TFRI64:
case Hexagon::CONST32_Int_Real:
case Hexagon::CONST64_Int_Real:

View File

@ -521,7 +521,7 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedLoadZeroExtend64(LoadSDNode *LD,
SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
MVT::i32, MVT::Other, Base,
TargetConstVal, Chain);
SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_tfrsi, dl, MVT::i32,
TargetConst0);
SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::A2_combinew, dl,
MVT::i64, MVT::Other,
@ -548,7 +548,7 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedLoadZeroExtend64(LoadSDNode *LD,
SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
MVT::Other,
Base, TargetConst0, Chain);
SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_tfrsi, dl, MVT::i32,
TargetConst0);
SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::A2_combinew, dl,
MVT::i64, MVT::Other,
@ -1180,7 +1180,7 @@ SDNode *HexagonDAGToDAGISel::SelectZeroExtend(SDNode *N) {
SDNode *Result_1 = CurDAG->getMachineNode(Hexagon::C2_tfrpr, dl,
MVT::i32,
SDValue(IsIntrinsic, 0));
SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl,
SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_tfrsi, dl,
MVT::i32,
TargetConst0);
SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::A2_combinew, dl,
@ -1289,7 +1289,7 @@ SDNode *HexagonDAGToDAGISel::SelectConstant(SDNode *N) {
if (Val == -1) {
// Create the IntReg = 1 node.
SDNode* IntRegTFR =
CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
CurDAG->getMachineNode(Hexagon::A2_tfrsi, dl, MVT::i32,
CurDAG->getTargetConstant(0, MVT::i32));
// Pd = IntReg

View File

@ -418,11 +418,11 @@ void HexagonInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
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::TFR64), DestReg).addReg(SrcReg);
BuildMI(MBB, I, DL, get(Hexagon::A2_tfrp), DestReg).addReg(SrcReg);
return;
}
if (Hexagon::PredRegsRegClass.contains(SrcReg, DestReg)) {
@ -436,13 +436,13 @@ void HexagonInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
// 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;
@ -648,7 +648,7 @@ bool HexagonInstrInfo::isPredicable(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:
@ -1278,14 +1278,14 @@ bool HexagonInstrInfo::
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;
}
}

View File

@ -88,12 +88,6 @@ def SDTHexagonI64I32I32 : SDTypeProfile<1, 2,
def HexagonCOMBINE : SDNode<"HexagonISD::COMBINE", SDTHexagonI64I32I32>;
def HexagonWrapperCombineII :
SDNode<"HexagonISD::WrapperCombineII", SDTHexagonI64I32I32>;
def HexagonWrapperCombineRR :
SDNode<"HexagonISD::WrapperCombineRR", SDTHexagonI64I32I32>;
let hasSideEffects = 0, hasNewValue = 1, InputType = "reg" in
class T_ALU32_3op<string mnemonic, bits<3> MajOp, bits<3> MinOp, bit OpsRev,
bit IsComm>
@ -495,132 +489,154 @@ multiclass ALU32_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
}
}
// Rd = neg(Rs) gets mapped to Rd=sub(#0, Rs).
// Pattern definition for 'neg' was not necessary.
multiclass TFR_Pred<bit PredNot> {
let isPredicatedFalse = PredNot in {
def _c#NAME : ALU32_rr<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2),
!if(PredNot, "if (!$src1", "if ($src1")#") $dst = $src2",
[]>;
// Predicate new
let isPredicatedNew = 1 in
def _cdn#NAME : ALU32_rr<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2),
!if(PredNot, "if (!$src1", "if ($src1")#".new) $dst = $src2",
[]>;
}
}
let InputType = "reg", hasSideEffects = 0 in
multiclass TFR_base<string CextOp> {
let CextOpcode = CextOp, BaseOpcode = CextOp in {
let isPredicable = 1 in
def NAME : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1),
"$dst = $src1",
[]>;
let isPredicated = 1 in {
defm Pt : TFR_Pred<0>;
defm NotPt : TFR_Pred<1>;
}
}
}
class T_TFR64_Pred<bit PredNot, bit isPredNew>
: ALU32_rr<(outs DoubleRegs:$dst),
(ins PredRegs:$src1, DoubleRegs:$src2),
!if(PredNot, "if (!$src1", "if ($src1")#
!if(isPredNew, ".new) ", ") ")#"$dst = $src2", []>
{
// Conditional transfer is an alias to conditional "Rd = add(Rs, #0)".
let isPredicated = 1, hasNewValue = 1, opNewValue = 0 in
class T_tfr_pred<bit isPredNot, bit isPredNew>
: ALU32Inst<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2),
"if ("#!if(isPredNot, "!", "")#
"$src1"#!if(isPredNew, ".new", "")#
") $dst = $src2"> {
bits<5> dst;
bits<2> src1;
bits<5> src2;
let IClass = 0b1111;
let Inst{27-24} = 0b1101;
let isPredicatedFalse = isPredNot;
let isPredicatedNew = isPredNew;
let IClass = 0b0111;
let Inst{27-24} = 0b0100;
let Inst{23} = isPredNot;
let Inst{13} = isPredNew;
let Inst{7} = PredNot;
let Inst{12-5} = 0;
let Inst{4-0} = dst;
let Inst{6-5} = src1;
let Inst{20-17} = src2{4-1};
let Inst{16} = 0b1;
let Inst{12-9} = src2{4-1};
let Inst{8} = 0b0;
}
let Inst{22-21} = src1;
let Inst{20-16} = src2;
}
multiclass TFR64_Pred<bit PredNot> {
let isPredicatedFalse = PredNot in {
def _c#NAME : T_TFR64_Pred<PredNot, 0>;
let isPredicable = 1 in
class T_tfr : ALU32Inst<(outs IntRegs:$dst), (ins IntRegs:$src),
"$dst = $src"> {
bits<5> dst;
bits<5> src;
let isPredicatedNew = 1 in
def _cdn#NAME : T_TFR64_Pred<PredNot, 1>; // Predicate new
let IClass = 0b0111;
let Inst{27-21} = 0b0000011;
let Inst{20-16} = src;
let Inst{13} = 0b0;
let Inst{4-0} = dst;
}
let InputType = "reg", hasNewValue = 1, hasSideEffects = 0 in
multiclass tfr_base<string CextOp> {
let CextOpcode = CextOp, BaseOpcode = CextOp in {
def NAME : T_tfr;
// Predicate
def t : T_tfr_pred<0, 0>;
def f : T_tfr_pred<1, 0>;
// Predicate new
def tnew : T_tfr_pred<0, 1>;
def fnew : T_tfr_pred<1, 1>;
}
}
// Assembler mapped to C2_ccombinew[t|f|newt|newf].
// Please don't add bits to this instruction as it'll be converted into
// 'combine' before object code emission.
let isPredicated = 1 in
class T_tfrp_pred<bit PredNot, bit PredNew>
: ALU32_rr <(outs DoubleRegs:$dst),
(ins PredRegs:$src1, DoubleRegs:$src2),
"if ("#!if(PredNot, "!", "")#"$src1"
#!if(PredNew, ".new", "")#") $dst = $src2" > {
let isPredicatedFalse = PredNot;
let isPredicatedNew = PredNew;
}
// Assembler mapped to A2_combinew.
// Please don't add bits to this instruction as it'll be converted into
// 'combine' before object code emission.
class T_tfrp : ALU32Inst <(outs DoubleRegs:$dst),
(ins DoubleRegs:$src),
"$dst = $src">;
let hasSideEffects = 0 in
multiclass TFR64_base<string BaseName> {
let BaseOpcode = BaseName in {
let isPredicable = 1 in
def NAME : ALU32Inst <(outs DoubleRegs:$dst),
(ins DoubleRegs:$src1),
"$dst = $src1" > {
bits<5> dst;
bits<5> src1;
let IClass = 0b1111;
let Inst{27-23} = 0b01010;
let Inst{4-0} = dst;
let Inst{20-17} = src1{4-1};
let Inst{16} = 0b1;
let Inst{12-9} = src1{4-1};
let Inst{8} = 0b0;
}
let isPredicated = 1 in {
defm Pt : TFR64_Pred<0>;
defm NotPt : TFR64_Pred<1>;
}
}
}
multiclass TFRI_Pred<bit PredNot> {
let isMoveImm = 1, isPredicatedFalse = PredNot in {
def _c#NAME : ALU32_ri<(outs IntRegs:$dst),
(ins PredRegs:$src1, s12Ext:$src2),
!if(PredNot, "if (!$src1", "if ($src1")#") $dst = #$src2",
[]>;
def NAME : T_tfrp;
// Predicate
def t : T_tfrp_pred <0, 0>;
def f : T_tfrp_pred <1, 0>;
// Predicate new
let isPredicatedNew = 1 in
def _cdn#NAME : ALU32_rr<(outs IntRegs:$dst),
(ins PredRegs:$src1, s12Ext:$src2),
!if(PredNot, "if (!$src1", "if ($src1")#".new) $dst = #$src2",
[]>;
def tnew : T_tfrp_pred <0, 1>;
def fnew : T_tfrp_pred <1, 1>;
}
}
let InputType = "imm", isExtendable = 1, isExtentSigned = 1 in
multiclass TFRI_base<string CextOp> {
let CextOpcode = CextOp, BaseOpcode = CextOp#I in {
let isAsCheapAsAMove = 1 , opExtendable = 1, opExtentBits = 16,
isMoveImm = 1, isPredicable = 1, isReMaterializable = 1 in
def NAME : ALU32_ri<(outs IntRegs:$dst), (ins s16Ext:$src1),
"$dst = #$src1",
[(set (i32 IntRegs:$dst), s16ExtPred:$src1)]>;
let InputType = "imm", isExtendable = 1, isExtentSigned = 1, opExtentBits = 12,
isMoveImm = 1, opExtendable = 2, BaseOpcode = "TFRI", CextOpcode = "TFR",
hasSideEffects = 0, isPredicated = 1, hasNewValue = 1 in
class T_TFRI_Pred<bit PredNot, bit PredNew>
: ALU32_ri<(outs IntRegs:$Rd), (ins PredRegs:$Pu, s12Ext:$s12),
"if ("#!if(PredNot,"!","")#"$Pu"#!if(PredNew,".new","")#") $Rd = #$s12",
[], "", ALU32_2op_tc_1_SLOT0123>, ImmRegRel, PredNewRel {
let isPredicatedFalse = PredNot;
let isPredicatedNew = PredNew;
let opExtendable = 2, opExtentBits = 12, hasSideEffects = 0,
isPredicated = 1 in {
defm Pt : TFRI_Pred<0>;
defm NotPt : TFRI_Pred<1>;
}
}
bits<5> Rd;
bits<2> Pu;
bits<12> s12;
let IClass = 0b0111;
let Inst{27-24} = 0b1110;
let Inst{23} = PredNot;
let Inst{22-21} = Pu;
let Inst{20} = 0b0;
let Inst{19-16,12-5} = s12;
let Inst{13} = PredNew;
let Inst{4-0} = Rd;
}
defm TFRI : TFRI_base<"TFR">, ImmRegRel, PredNewRel;
defm TFR : TFR_base<"TFR">, ImmRegRel, PredNewRel;
defm TFR64 : TFR64_base<"TFR64">, PredNewRel;
let isCodeGenOnly = 0 in {
def C2_cmoveit : T_TFRI_Pred<0, 0>;
def C2_cmoveif : T_TFRI_Pred<1, 0>;
def C2_cmovenewit : T_TFRI_Pred<0, 1>;
def C2_cmovenewif : T_TFRI_Pred<1, 1>;
}
let InputType = "imm", isExtendable = 1, isExtentSigned = 1,
CextOpcode = "TFR", BaseOpcode = "TFRI", hasNewValue = 1, opNewValue = 0,
isAsCheapAsAMove = 1 , opExtendable = 1, opExtentBits = 16, isMoveImm = 1,
isPredicated = 0, isPredicable = 1, isReMaterializable = 1 in
def A2_tfrsi : ALU32Inst<(outs IntRegs:$Rd), (ins s16Ext:$s16), "$Rd = #$s16",
[(set (i32 IntRegs:$Rd), s16ExtPred:$s16)], "", ALU32_2op_tc_1_SLOT0123>,
ImmRegRel, PredRel {
bits<5> Rd;
bits<16> s16;
let IClass = 0b0111;
let Inst{27-24} = 0b1000;
let Inst{23-22,20-16,13-5} = s16;
let Inst{4-0} = Rd;
}
let isCodeGenOnly = 0 in
defm A2_tfr : tfr_base<"TFR">, ImmRegRel, PredNewRel;
defm A2_tfrp : TFR64_base<"TFR64">, PredNewRel;
// Assembler mapped
let isReMaterializable = 1, isMoveImm = 1, isAsCheapAsAMove = 1 in
def A2_tfrpi : ALU64_rr<(outs DoubleRegs:$dst), (ins s8Imm64:$src1),
"$dst = #$src1",
[(set (i64 DoubleRegs:$dst), s8Imm64Pred:$src1)]>;
// TODO: see if this instruction can be deleted..
let isExtendable = 1, opExtendable = 1, opExtentBits = 6 in
def TFRI64_V4 : ALU64_rr<(outs DoubleRegs:$dst), (ins u6Ext:$src1),
"$dst = #$src1">;
// Transfer control register.
let hasSideEffects = 0 in
@ -2768,14 +2784,14 @@ def : Pat <(and (i1 PredRegs:$src1), (not (i1 PredRegs:$src2))),
let AddedComplexity = 100 in
def : Pat <(i64 (zextloadi1 (HexagonCONST32 tglobaladdr:$global))),
(i64 (A2_combinew (TFRI 0),
(i64 (A2_combinew (A2_tfrsi 0),
(LDriub_indexed (CONST32_set tglobaladdr:$global), 0)))>,
Requires<[NoV4T]>;
// Map from i1 loads to 32 bits. This assumes that the i1* is byte aligned.
let AddedComplexity = 10 in
def : Pat <(i32 (zextloadi1 ADDRriS11_0:$addr)),
(i32 (A2_and (i32 (LDrib ADDRriS11_0:$addr)), (TFRI 0x1)))>;
(i32 (A2_and (i32 (LDrib ADDRriS11_0:$addr)), (A2_tfrsi 0x1)))>;
// Map from Rdd = sign_extend_inreg(Rss, i32) -> Rdd = SXTW(Rss.lo).
def : Pat <(i64 (sext_inreg (i64 DoubleRegs:$src1), i32)),
@ -2890,12 +2906,12 @@ def : Pat<(truncstorei32 (i64 DoubleRegs:$src), ADDRriS11_0:$addr),
// Map from i1 = constant<-1>; memw(addr) = i1 -> r0 = 1; memw(addr) = r0.
def : Pat<(store (i1 -1), ADDRriS11_2:$addr),
(STrib ADDRriS11_2:$addr, (TFRI 1))>;
(STrib ADDRriS11_2:$addr, (A2_tfrsi 1))>;
// Map from i1 = constant<-1>; store i1 -> r0 = 1; store r0.
def : Pat<(store (i1 -1), ADDRriS11_2:$addr),
(STrib ADDRriS11_2:$addr, (TFRI 1))>;
(STrib ADDRriS11_2:$addr, (A2_tfrsi 1))>;
// Map from memb(Rs) = Pd -> Rt = mux(Pd, #0, #1); store Rt.
def : Pat<(store (i1 PredRegs:$src1), ADDRriS11_2:$addr),
@ -3023,7 +3039,7 @@ def : Pat <(i32 (sext (i1 PredRegs:$src1))),
// i1 -> i64
def : Pat <(i64 (sext (i1 PredRegs:$src1))),
(i64 (A2_combinew (TFRI -1), (C2_muxii (i1 PredRegs:$src1), -1, 0)))>;
(i64 (A2_combinew (A2_tfrsi -1), (C2_muxii (i1 PredRegs:$src1), -1, 0)))>;
// Convert sign-extended load back to load and sign extend.
// i8 -> i64
@ -3053,58 +3069,58 @@ def : Pat <(i32 (zext (i1 PredRegs:$src1))),
// i1 -> i64
def : Pat <(i64 (zext (i1 PredRegs:$src1))),
(i64 (A2_combinew (TFRI 0), (C2_muxii (i1 PredRegs:$src1), 1, 0)))>,
(i64 (A2_combinew (A2_tfrsi 0), (C2_muxii (i1 PredRegs:$src1), 1, 0)))>,
Requires<[NoV4T]>;
// i32 -> i64
def : Pat <(i64 (zext (i32 IntRegs:$src1))),
(i64 (A2_combinew (TFRI 0), (i32 IntRegs:$src1)))>,
(i64 (A2_combinew (A2_tfrsi 0), (i32 IntRegs:$src1)))>,
Requires<[NoV4T]>;
// i8 -> i64
def: Pat <(i64 (zextloadi8 ADDRriS11_0:$src1)),
(i64 (A2_combinew (TFRI 0), (LDriub ADDRriS11_0:$src1)))>,
(i64 (A2_combinew (A2_tfrsi 0), (LDriub ADDRriS11_0:$src1)))>,
Requires<[NoV4T]>;
let AddedComplexity = 20 in
def: Pat <(i64 (zextloadi8 (add (i32 IntRegs:$src1),
s11_0ExtPred:$offset))),
(i64 (A2_combinew (TFRI 0), (LDriub_indexed IntRegs:$src1,
(i64 (A2_combinew (A2_tfrsi 0), (LDriub_indexed IntRegs:$src1,
s11_0ExtPred:$offset)))>,
Requires<[NoV4T]>;
// i1 -> i64
def: Pat <(i64 (zextloadi1 ADDRriS11_0:$src1)),
(i64 (A2_combinew (TFRI 0), (LDriub ADDRriS11_0:$src1)))>,
(i64 (A2_combinew (A2_tfrsi 0), (LDriub ADDRriS11_0:$src1)))>,
Requires<[NoV4T]>;
let AddedComplexity = 20 in
def: Pat <(i64 (zextloadi1 (add (i32 IntRegs:$src1),
s11_0ExtPred:$offset))),
(i64 (A2_combinew (TFRI 0), (LDriub_indexed IntRegs:$src1,
(i64 (A2_combinew (A2_tfrsi 0), (LDriub_indexed IntRegs:$src1,
s11_0ExtPred:$offset)))>,
Requires<[NoV4T]>;
// i16 -> i64
def: Pat <(i64 (zextloadi16 ADDRriS11_1:$src1)),
(i64 (A2_combinew (TFRI 0), (LDriuh ADDRriS11_1:$src1)))>,
(i64 (A2_combinew (A2_tfrsi 0), (LDriuh ADDRriS11_1:$src1)))>,
Requires<[NoV4T]>;
let AddedComplexity = 20 in
def: Pat <(i64 (zextloadi16 (add (i32 IntRegs:$src1),
s11_1ExtPred:$offset))),
(i64 (A2_combinew (TFRI 0), (LDriuh_indexed IntRegs:$src1,
(i64 (A2_combinew (A2_tfrsi 0), (LDriuh_indexed IntRegs:$src1,
s11_1ExtPred:$offset)))>,
Requires<[NoV4T]>;
// i32 -> i64
def: Pat <(i64 (zextloadi32 ADDRriS11_2:$src1)),
(i64 (A2_combinew (TFRI 0), (LDriw ADDRriS11_2:$src1)))>,
(i64 (A2_combinew (A2_tfrsi 0), (LDriw ADDRriS11_2:$src1)))>,
Requires<[NoV4T]>;
let AddedComplexity = 100 in
def: Pat <(i64 (zextloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))),
(i64 (A2_combinew (TFRI 0), (LDriw_indexed IntRegs:$src1,
(i64 (A2_combinew (A2_tfrsi 0), (LDriw_indexed IntRegs:$src1,
s11_2ExtPred:$offset)))>,
Requires<[NoV4T]>;
@ -3170,7 +3186,7 @@ def: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh),
// Any extended 64-bit load.
// anyext i32 -> i64
def: Pat <(i64 (extloadi32 ADDRriS11_2:$src1)),
(i64 (A2_combinew (TFRI 0), (LDriw ADDRriS11_2:$src1)))>,
(i64 (A2_combinew (A2_tfrsi 0), (LDriw ADDRriS11_2:$src1)))>,
Requires<[NoV4T]>;
// When there is an offset we should prefer the pattern below over the pattern above.
@ -3185,25 +3201,25 @@ def: Pat <(i64 (extloadi32 ADDRriS11_2:$src1)),
// ********************************************
let AddedComplexity = 100 in
def: Pat <(i64 (extloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))),
(i64 (A2_combinew (TFRI 0), (LDriw_indexed IntRegs:$src1,
(i64 (A2_combinew (A2_tfrsi 0), (LDriw_indexed IntRegs:$src1,
s11_2ExtPred:$offset)))>,
Requires<[NoV4T]>;
// anyext i16 -> i64.
def: Pat <(i64 (extloadi16 ADDRriS11_2:$src1)),
(i64 (A2_combinew (TFRI 0), (LDrih ADDRriS11_2:$src1)))>,
(i64 (A2_combinew (A2_tfrsi 0), (LDrih ADDRriS11_2:$src1)))>,
Requires<[NoV4T]>;
let AddedComplexity = 20 in
def: Pat <(i64 (extloadi16 (add (i32 IntRegs:$src1),
s11_1ExtPred:$offset))),
(i64 (A2_combinew (TFRI 0), (LDrih_indexed IntRegs:$src1,
(i64 (A2_combinew (A2_tfrsi 0), (LDrih_indexed IntRegs:$src1,
s11_1ExtPred:$offset)))>,
Requires<[NoV4T]>;
// Map from Rdd = zxtw(Rs) -> Rdd = combine(0, Rs).
def : Pat<(i64 (zext (i32 IntRegs:$src1))),
(i64 (A2_combinew (TFRI 0), (i32 IntRegs:$src1)))>,
(i64 (A2_combinew (A2_tfrsi 0), (i32 IntRegs:$src1)))>,
Requires<[NoV4T]>;
// Multiply 64-bit unsigned and use upper result.
@ -3212,7 +3228,7 @@ def : Pat <(mulhu (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2)),
(MPYU64_acc
(i64
(A2_combinew
(TFRI 0),
(A2_tfrsi 0),
(i32
(EXTRACT_SUBREG
(i64
@ -3222,7 +3238,7 @@ def : Pat <(mulhu (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2)),
(i64
(MPYU64_acc
(i64
(A2_combinew (TFRI 0),
(A2_combinew (A2_tfrsi 0),
(i32
(EXTRACT_SUBREG
(i64
@ -3246,7 +3262,7 @@ def : Pat <(mulhs (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2)),
(i64
(MPY64_acc
(i64
(A2_combinew (TFRI 0),
(A2_combinew (A2_tfrsi 0),
(i32
(EXTRACT_SUBREG
(i64
@ -3256,7 +3272,7 @@ def : Pat <(mulhs (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2)),
(i64
(MPY64_acc
(i64
(A2_combinew (TFRI 0),
(A2_combinew (A2_tfrsi 0),
(i32
(EXTRACT_SUBREG
(i64

View File

@ -2874,7 +2874,7 @@ def : Pat<(truncstorei8 (i32 IntRegs:$src1),
// to "r0 = 1; memw(#foo) = r0"
let AddedComplexity = 100 in
def : Pat<(store (i1 -1), (HexagonCONST32_GP tglobaladdr:$global)),
(STb_GP_V4 tglobaladdr:$global, (TFRI 1))>;
(STb_GP_V4 tglobaladdr:$global, (A2_tfrsi 1))>;
def : Pat<(atomic_store_16 (HexagonCONST32_GP tglobaladdr:$global),
(i32 IntRegs:$src1)),

View File

@ -458,19 +458,19 @@ def CONVERT_sf2ud_nchop : ALU64_rr<(outs DoubleRegs:$dst), (ins IntRegs:$src),
// Bitcast is different than [fp|sint|uint]_to_[sint|uint|fp].
def : Pat <(i32 (bitconvert (f32 IntRegs:$src))),
(i32 (TFR IntRegs:$src))>,
(i32 (A2_tfr IntRegs:$src))>,
Requires<[HasV5T]>;
def : Pat <(f32 (bitconvert (i32 IntRegs:$src))),
(f32 (TFR IntRegs:$src))>,
(f32 (A2_tfr IntRegs:$src))>,
Requires<[HasV5T]>;
def : Pat <(i64 (bitconvert (f64 DoubleRegs:$src))),
(i64 (TFR64 DoubleRegs:$src))>,
(i64 (A2_tfrp DoubleRegs:$src))>,
Requires<[HasV5T]>;
def : Pat <(f64 (bitconvert (i64 DoubleRegs:$src))),
(f64 (TFR64 DoubleRegs:$src))>,
(f64 (A2_tfrp DoubleRegs:$src))>,
Requires<[HasV5T]>;
// Floating point fused multiply-add.

View File

@ -99,12 +99,12 @@ bool HexagonSplitTFRCondSets::runOnMachineFunction(MachineFunction &Fn) {
int SrcReg2 = MI->getOperand(3).getReg();
if (MI->getOpcode() == Hexagon::TFR_condset_rr_f) {
Opc1 = Hexagon::TFR_cPt;
Opc2 = Hexagon::TFR_cNotPt;
Opc1 = Hexagon::A2_tfrt;
Opc2 = Hexagon::A2_tfrf;
}
else if (MI->getOpcode() == Hexagon::TFR_condset_rr64_f) {
Opc1 = Hexagon::TFR64_cPt;
Opc2 = Hexagon::TFR64_cNotPt;
Opc1 = Hexagon::A2_tfrpt;
Opc2 = Hexagon::A2_tfrpf;
}
// Minor optimization: do not emit the predicated copy if the source
@ -130,12 +130,12 @@ bool HexagonSplitTFRCondSets::runOnMachineFunction(MachineFunction &Fn) {
// is the same register.
if (DestReg != SrcReg1) {
BuildMI(*MBB, MII, MI->getDebugLoc(),
TII->get(Hexagon::TFR_cPt), DestReg).
TII->get(Hexagon::A2_tfrt), DestReg).
addReg(MI->getOperand(1).getReg()).addReg(SrcReg1);
}
if (MI->getOpcode() == Hexagon::TFR_condset_ri ) {
BuildMI(*MBB, MII, MI->getDebugLoc(),
TII->get(Hexagon::TFRI_cNotPt), DestReg).
TII->get(Hexagon::C2_cmoveif), DestReg).
addReg(MI->getOperand(1).getReg()).
addImm(MI->getOperand(3).getImm());
} else if (MI->getOpcode() == Hexagon::TFR_condset_ri_f ) {
@ -156,7 +156,7 @@ bool HexagonSplitTFRCondSets::runOnMachineFunction(MachineFunction &Fn) {
if (MI->getOpcode() == Hexagon::TFR_condset_ir ) {
BuildMI(*MBB, MII, MI->getDebugLoc(),
TII->get(Hexagon::TFRI_cPt), DestReg).
TII->get(Hexagon::C2_cmoveit), DestReg).
addReg(MI->getOperand(1).getReg()).
addImm(MI->getOperand(2).getImm());
} else if (MI->getOpcode() == Hexagon::TFR_condset_ir_f ) {
@ -170,7 +170,7 @@ bool HexagonSplitTFRCondSets::runOnMachineFunction(MachineFunction &Fn) {
// the destination is the same register.
if (DestReg != SrcReg2) {
BuildMI(*MBB, MII, MI->getDebugLoc(),
TII->get(Hexagon::TFR_cNotPt), DestReg).
TII->get(Hexagon::A2_tfrf), DestReg).
addReg(MI->getOperand(1).getReg()).addReg(SrcReg2);
}
MII = MBB->erase(MI);
@ -186,10 +186,10 @@ bool HexagonSplitTFRCondSets::runOnMachineFunction(MachineFunction &Fn) {
int Immed1 = MI->getOperand(2).getImm();
int Immed2 = MI->getOperand(3).getImm();
BuildMI(*MBB, MII, MI->getDebugLoc(),
TII->get(Hexagon::TFRI_cPt),
TII->get(Hexagon::C2_cmoveit),
DestReg).addReg(SrcReg1).addImm(Immed1);
BuildMI(*MBB, MII, MI->getDebugLoc(),
TII->get(Hexagon::TFRI_cNotPt),
TII->get(Hexagon::C2_cmoveif),
DestReg).addReg(SrcReg1).addImm(Immed2);
} else if (MI->getOpcode() == Hexagon::TFR_condset_ii_f ) {
BuildMI(*MBB, MII, MI->getDebugLoc(),

View File

@ -30,5 +30,11 @@
# CHECK: r17.h = #21
0x15 0xc0 0x31 0x71
# CHECK: r17.l = #21
0xf1 0xff 0x5f 0x78
# CHECK: { r17 = #32767 }
0xf1 0xff 0xdf 0x78
# CHECK: { r17 = #-1 }
0x11 0xc0 0x75 0x70
# CHECK: { r17 = r21 }
0x11 0xc0 0xd5 0x70
# CHECK: r17 = zxth(r21)

View File

@ -16,6 +16,12 @@
0x03 0x40 0x45 0x85 0xf0 0xff 0x15 0xfd
# CHECK: p3 = r5
# CHECK-NEXT: if (!p3.new) r17:16 = combine(r21, r31)
0x03 0x40 0x45 0x85 0x70 0xff 0x15 0xfd
# CHECK: { p3 = r5
# CHECK-NEXT: if (p3.new) r17:16 = combine(r21, r31) }
0x03 0x40 0x45 0x85 0xf0 0xff 0x15 0xfd
# CHECK: { p3 = r5
# CHECK-NEXT: if (!p3.new) r17:16 = combine(r21, r31) }
0x71 0xdf 0x15 0xf9
# CHECK: if (p3) r17 = and(r21, r31)
0x71 0xdf 0x35 0xf9
@ -28,6 +34,16 @@
# CHECK: if (p3) r17 = sxtb(r21)
0x11 0xe3 0xf5 0x70
# CHECK: if (p3) r17 = sxth(r21)
0xb1 0xc2 0x60 0x7e
# CHECK: { if (p3) r17 = #21 }
0xb1 0xc2 0xe0 0x7e
# CHECK: { if (!p3) r17 = #21 }
0x03 0x40 0x45 0x85 0xb1 0xe2 0x60 0x7e
# CHECK: { p3 = r5
# CHECK-NEXT: if (p3.new) r17 = #21 }
0x03 0x40 0x45 0x85 0xb1 0xe2 0xe0 0x7e
# CHECK: { p3 = r5
# CHECK-NEXT: if (!p3.new) r17 = #21 }
0x11 0xe3 0x95 0x70
# CHECK: if (p3) r17 = zxtb(r21)
0x11 0xe3 0xd5 0x70