RegSequence,
ExtractSubreg,
InsertSubreg,
- Convergent
+ Convergent,
+ Add
};
}
/// \brief Return true if the instruction is a return.
bool isReturn() const { return Flags & (1ULL << MCID::Return); }
+ /// \brief Return true if the instruction is an add instruction.
+ bool isAdd() const { return Flags & (1ULL << MCID::Add); }
+
/// \brief Return true if the instruction is a call.
bool isCall() const { return Flags & (1ULL << MCID::Call); }
bit isSelect = 0; // Is this instruction a select instruction?
bit isBarrier = 0; // Can control flow fall through this instruction?
bit isCall = 0; // Is this instruction a call instruction?
+ bit isAdd = 0; // Is this instruction an add instruction?
bit canFoldAsLoad = 0; // Can this be folded as a simple memory operand?
bit mayLoad = ?; // Is it possible for this inst to read memory?
bit mayStore = ?; // Is it possible for this inst to write memory?
// Arithmetic Instructions.
//
+let isAdd = 1 in
defm ADD : AsI1_bin_irs<0b0100, "add",
IIC_iALUi, IIC_iALUr, IIC_iALUsr, add, 1>;
defm SUB : AsI1_bin_irs<0b0010, "sub",
// FIXME: Eliminate ADDS/SUBS pseudo opcodes after adding tablegen
// support for an optional CPSR definition that corresponds to the DAG
// node's second value. We can then eliminate the implicit def of CPSR.
+let isAdd = 1 in
defm ADDS : AsI1_bin_s_irs<IIC_iALUi, IIC_iALUr, IIC_iALUsr, ARMaddc, 1>;
defm SUBS : AsI1_bin_s_irs<IIC_iALUi, IIC_iALUr, IIC_iALUsr, ARMsubc>;
+let isAdd = 1 in
defm ADC : AI1_adde_sube_irs<0b0101, "adc", ARMadde, 1>;
defm SBC : AI1_adde_sube_irs<0b0110, "sbc", ARMsube>;
let Inst{7-0} = imm8;
}
-// Add with carry register
-let isCommutable = 1, Uses = [CPSR] in
-def tADC : // A8.6.2
- T1sItDPEncode<0b0101, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm), IIC_iALUr,
- "adc", "\t$Rdn, $Rm",
- [(set tGPR:$Rdn, (adde tGPR:$Rn, tGPR:$Rm))]>, Sched<[WriteALU]>;
-
-// Add immediate
-def tADDi3 : // A8.6.4 T1
- T1sIGenEncodeImm<0b01110, (outs tGPR:$Rd), (ins tGPR:$Rm, imm0_7:$imm3),
- IIC_iALUi,
- "add", "\t$Rd, $Rm, $imm3",
- [(set tGPR:$Rd, (add tGPR:$Rm, imm0_7:$imm3))]>,
- Sched<[WriteALU]> {
- bits<3> imm3;
- let Inst{8-6} = imm3;
-}
-
-def tADDi8 : // A8.6.4 T2
- T1sItGenEncodeImm<{1,1,0,?,?}, (outs tGPR:$Rdn),
- (ins tGPR:$Rn, imm0_255:$imm8), IIC_iALUi,
- "add", "\t$Rdn, $imm8",
- [(set tGPR:$Rdn, (add tGPR:$Rn, imm8_255:$imm8))]>,
- Sched<[WriteALU]>;
+let isAdd = 1 in {
+ // Add with carry register
+ let isCommutable = 1, Uses = [CPSR] in
+ def tADC : // A8.6.2
+ T1sItDPEncode<0b0101, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm), IIC_iALUr,
+ "adc", "\t$Rdn, $Rm",
+ [(set tGPR:$Rdn, (adde tGPR:$Rn, tGPR:$Rm))]>, Sched<[WriteALU]>;
+
+ // Add immediate
+ def tADDi3 : // A8.6.4 T1
+ T1sIGenEncodeImm<0b01110, (outs tGPR:$Rd), (ins tGPR:$Rm, imm0_7:$imm3),
+ IIC_iALUi,
+ "add", "\t$Rd, $Rm, $imm3",
+ [(set tGPR:$Rd, (add tGPR:$Rm, imm0_7:$imm3))]>,
+ Sched<[WriteALU]> {
+ bits<3> imm3;
+ let Inst{8-6} = imm3;
+ }
-// Add register
-let isCommutable = 1 in
-def tADDrr : // A8.6.6 T1
- T1sIGenEncode<0b01100, (outs tGPR:$Rd), (ins tGPR:$Rn, tGPR:$Rm),
- IIC_iALUr,
- "add", "\t$Rd, $Rn, $Rm",
- [(set tGPR:$Rd, (add tGPR:$Rn, tGPR:$Rm))]>, Sched<[WriteALU]>;
-
-let hasSideEffects = 0 in
-def tADDhirr : T1pIt<(outs GPR:$Rdn), (ins GPR:$Rn, GPR:$Rm), IIC_iALUr,
- "add", "\t$Rdn, $Rm", []>,
- T1Special<{0,0,?,?}>, Sched<[WriteALU]> {
- // A8.6.6 T2
- bits<4> Rdn;
- bits<4> Rm;
- let Inst{7} = Rdn{3};
- let Inst{6-3} = Rm;
- let Inst{2-0} = Rdn{2-0};
+ def tADDi8 : // A8.6.4 T2
+ T1sItGenEncodeImm<{1,1,0,?,?}, (outs tGPR:$Rdn),
+ (ins tGPR:$Rn, imm0_255:$imm8), IIC_iALUi,
+ "add", "\t$Rdn, $imm8",
+ [(set tGPR:$Rdn, (add tGPR:$Rn, imm8_255:$imm8))]>,
+ Sched<[WriteALU]>;
+
+ // Add register
+ let isCommutable = 1 in
+ def tADDrr : // A8.6.6 T1
+ T1sIGenEncode<0b01100, (outs tGPR:$Rd), (ins tGPR:$Rn, tGPR:$Rm),
+ IIC_iALUr,
+ "add", "\t$Rd, $Rn, $Rm",
+ [(set tGPR:$Rd, (add tGPR:$Rn, tGPR:$Rm))]>, Sched<[WriteALU]>;
+
+ let hasSideEffects = 0 in
+ def tADDhirr : T1pIt<(outs GPR:$Rdn), (ins GPR:$Rn, GPR:$Rm), IIC_iALUr,
+ "add", "\t$Rdn, $Rm", []>,
+ T1Special<{0,0,?,?}>, Sched<[WriteALU]> {
+ // A8.6.6 T2
+ bits<4> Rdn;
+ bits<4> Rm;
+ let Inst{7} = Rdn{3};
+ let Inst{6-3} = Rm;
+ let Inst{2-0} = Rdn{2-0};
+ }
}
// AND register
// Arithmetic Instructions.
//
+let isAdd = 1 in
defm t2ADD : T2I_bin_ii12rs<0b000, "add", add, 1>;
defm t2SUB : T2I_bin_ii12rs<0b101, "sub", sub>;
unsigned PhiOpReg = Phi->getOperand(i).getReg();
MachineInstr *DI = MRI->getVRegDef(PhiOpReg);
- unsigned UpdOpc = DI->getOpcode();
- bool isAdd = (UpdOpc == Hexagon::A2_addi || UpdOpc == Hexagon::A2_addp);
- if (isAdd) {
+ if (DI->getDesc().isAdd()) {
// If the register operand to the add is the PHI we're looking at, this
// meets the induction pattern.
unsigned IndReg = DI->getOperand(1).getReg();
unsigned PhiReg = Phi->getOperand(i).getReg();
MachineInstr *DI = MRI->getVRegDef(PhiReg);
- unsigned UpdOpc = DI->getOpcode();
- bool isAdd = (UpdOpc == Hexagon::A2_addi || UpdOpc == Hexagon::A2_addp);
- if (isAdd) {
+ if (DI->getDesc().isAdd()) {
// If the register operand to the add/sub is the PHI we are looking
// at, this meets the induction pattern.
unsigned IndReg = DI->getOperand(1).getReg();
let isExtendable = 1, isExtentSigned = 1, InputType = "imm" in
multiclass Addri_base<string mnemonic, SDNode OpNode> {
let CextOpcode = mnemonic, BaseOpcode = mnemonic#_ri in {
- let opExtendable = 2, opExtentBits = 16, isPredicable = 1 in
+ let opExtendable = 2, opExtentBits = 16, isPredicable = 1, isAdd = 1 in
def A2_#NAME : T_Addri<s16Ext>;
let opExtendable = 3, opExtentBits = 8, isPredicated = 1 in {
: T_ALU64_rr<mnemonic, !if(IsSat,":sat",""), 0b0011, MajOp, MinOp, OpsRev,
IsComm, "">;
+let isAdd = 1 in
def A2_addp : T_ALU64_arith<"add", 0b000, 0b111, 0, 0, 1>;
def A2_subp : T_ALU64_arith<"sub", 0b001, 0b111, 0, 1, 0>;
target datalayout = "e-p:32:32:32-i64:64:64-i32:32:32-i16:16:16-i1:32:32-f64:64:64-f32:32:32-v64:64:64-v32:32:32-a0:0-n16:32"
target triple = "hexagon-unknown-none"
-%struct.aDataType = type { i16, i16, i16, i16, i16, i16*, i16*, i16*, i8*, i16*, i16*, i16*, i8* }
-define i8* @a_get_score(%struct.aDataType* nocapture %pData, i16 signext %gmmModelIndex, i16* nocapture %pGmmScoreL16Q4) #0 {
-entry:
- %numSubVector = getelementptr inbounds %struct.aDataType, %struct.aDataType* %pData, i32 0, i32 3
- %0 = load i16, i16* %numSubVector, align 2, !tbaa !0
- %and = and i16 %0, -4
- %b = getelementptr inbounds %struct.aDataType, %struct.aDataType* %pData, i32 0, i32 8
- %1 = load i8*, i8** %b, align 4, !tbaa !3
+define i32 @foo(i16 %a, i32 %b) #0 {
+ %and = and i16 %a, -4
%conv3 = sext i16 %and to i32
- %cmp21 = icmp sgt i16 %and, 0
- br i1 %cmp21, label %for.inc.preheader, label %for.end
-
-for.inc.preheader: ; preds = %entry
- br label %for.inc
-
-for.inc: ; preds = %for.inc.preheader, %for.inc
- %j.022 = phi i32 [ %phitmp, %for.inc ], [ 0, %for.inc.preheader ]
- %add13 = mul i32 %j.022, 65536
+ %add13 = mul i32 %b, 65536
%sext = add i32 %add13, 262144
%phitmp = ashr exact i32 %sext, 16
- %cmp = icmp slt i32 %phitmp, %conv3
- br i1 %cmp, label %for.inc, label %for.end.loopexit
-
-for.end.loopexit: ; preds = %for.inc
- br label %for.end
-
-for.end: ; preds = %for.end.loopexit, %entry
- ret i8* %1
+ ret i32 %phitmp
}
+
attributes #0 = { nounwind readonly "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
!0 = !{!"short", !1}
isSelect = R->getValueAsBit("isSelect");
isBarrier = R->getValueAsBit("isBarrier");
isCall = R->getValueAsBit("isCall");
+ isAdd = R->getValueAsBit("isAdd");
canFoldAsLoad = R->getValueAsBit("canFoldAsLoad");
isPredicable = Operands.isPredicable || R->getValueAsBit("isPredicable");
isConvertibleToThreeAddress = R->getValueAsBit("isConvertibleToThreeAddress");
bool isSelect : 1;
bool isBarrier : 1;
bool isCall : 1;
+ bool isAdd : 1;
bool canFoldAsLoad : 1;
bool mayLoad : 1;
bool mayLoad_Unset : 1;
if (Inst.isCompare) OS << "|(1ULL<<MCID::Compare)";
if (Inst.isMoveImm) OS << "|(1ULL<<MCID::MoveImm)";
if (Inst.isBitcast) OS << "|(1ULL<<MCID::Bitcast)";
+ if (Inst.isAdd) OS << "|(1ULL<<MCID::Add)";
if (Inst.isSelect) OS << "|(1ULL<<MCID::Select)";
if (Inst.isBarrier) OS << "|(1ULL<<MCID::Barrier)";
if (Inst.hasDelaySlot) OS << "|(1ULL<<MCID::DelaySlot)";