diff --git a/llvm/lib/Target/SBF/SBFInstrInfo.td b/llvm/lib/Target/SBF/SBFInstrInfo.td index 41a66c375408a9..c91a7fbe9bed50 100644 --- a/llvm/lib/Target/SBF/SBFInstrInfo.td +++ b/llvm/lib/Target/SBF/SBFInstrInfo.td @@ -54,6 +54,8 @@ def SBFIsBigEndian : Predicate<"!CurDAG->getDataLayout().isLittleEndian()">; def SBFHasALU32 : Predicate<"Subtarget->getHasAlu32()">; def SBFNoALU32 : Predicate<"!Subtarget->getHasAlu32()">; def SBFSubtargetSolana : Predicate<"Subtarget->isSolana()">; +def SBFv2 : Predicate<"Subtarget->isSBFv2()">; +def NoSBFv2 : Predicate<"!Subtarget->isSBFv2()">; def brtarget : Operand { let PrintMethod = "printBrTargetOperand"; @@ -263,7 +265,7 @@ class ALU_RR { +multiclass ALU { def _rr : ALU_RR { (outs GPR:$dst), (ins GPR:$src2, i64imm:$imm), Mnemonic # "64 $dst, $imm", - [(set GPR:$dst, (OpNode GPR:$src2, i64immSExt32:$imm))]>; + !if(UseImmPat, + [(set GPR:$dst, + (OpNode GPR:$src2, i64immSExt32:$imm))], [])>; def _rr_32 : ALU_RR { (outs GPR32:$dst), (ins GPR32:$src2, i32imm:$imm), Mnemonic # "32 $dst, $imm", - [(set GPR32:$dst, (OpNode GPR32:$src2, i32immSExt32:$imm))]>; + !if(UseImmPat, + [(set GPR32:$dst, + (OpNode GPR32:$src2, i32immSExt32:$imm))], [])>; } let Constraints = "$dst = $src2" in { let isAsCheapAsAMove = 1 in { defm ADD : ALU; - defm SUB : ALU; + defm SUB : ALU; defm OR : ALU; defm AND : ALU; defm SLL : ALU; @@ -306,6 +312,19 @@ let Constraints = "$dst = $src2" in { } } +// Special case for SBFv2 +// In SBFv1, `sub reg, imm` is interpreted as reg = reg - imm, +// but in SBFv2 it means reg = imm - reg +def : Pat<(sub GPR:$src, i64immSExt32:$imm), + (SUB_ri GPR:$src, i64immSExt32:$imm)>, Requires<[NoSBFv2]>; +def : Pat<(sub GPR32:$src, i32immSExt32:$imm), + (SUB_ri_32 GPR32:$src, i32immSExt32:$imm)>, Requires<[NoSBFv2]>; + +def : Pat<(sub i64immSExt32:$imm, GPR:$src), + (SUB_ri GPR:$src, i64immSExt32:$imm)>, Requires<[SBFv2]>; +def : Pat<(sub i32immSExt32:$imm, GPR32:$src), + (SUB_ri_32 GPR32:$src, i32immSExt32:$imm)>, Requires<[SBFv2]>; + class NEG_RR pattern> : TYPE_ALU_JMP { @@ -318,12 +337,21 @@ class NEG_RR; + []>; def NEG_32: NEG_RR; + []>; } +// Instruction `neg` exists on SBFv1, but not on SBFv2 +// In SBFv2, the negate operation is done with a subtraction +def : Pat<(ineg i64:$src), (NEG_64 GPR:$src)>, Requires<[NoSBFv2]>; +def : Pat<(ineg i32:$src), (NEG_32 GPR32:$src)>, Requires<[NoSBFv2]>; + +def : Pat<(ineg i64:$src), (SUB_ri GPR:$src, 0)>, Requires<[SBFv2]>; +def : Pat<(ineg i32:$src), (SUB_ri_32 GPR32:$src, 0)>, Requires<[SBFv2]>; + + class LD_IMM64 Pseudo, string Mnemonic> : TYPE_LD_ST