diff --git a/llvm/lib/Target/SBF/SBF.td b/llvm/lib/Target/SBF/SBF.td index 30520e99cad7d3..c718c9f92bbad6 100644 --- a/llvm/lib/Target/SBF/SBF.td +++ b/llvm/lib/Target/SBF/SBF.td @@ -38,6 +38,12 @@ def FeatureRelocAbs64 : SubtargetFeature<"reloc-abs64", "UseRelocAbs64", "true", def FeatureStaticSyscalls : SubtargetFeature<"static-syscalls", "HasStaticSyscalls", "true", "Marker feature used for conditional compilation">; +def FeatureDisableNeg : SubtargetFeature<"no-neg", "DisableNeg", "true", + "Disable the neg instruction">; + +def FeatureReverseSubImm : SubtargetFeature<"reverse-sub", "ReverseSubImm", "true", + "Reverse the operands in the 'sub reg, imm' instruction">; + class Proc Features> : Processor; @@ -46,7 +52,8 @@ def : Proc<"v1", []>; def : Proc<"v2", []>; def : Proc<"v3", []>; def : Proc<"probe", []>; -def : Proc<"sbfv2", [FeatureSolana, FeatureDynamicFrames, FeatureSdiv, FeatureRelocAbs64, FeatureStaticSyscalls]>; +def : Proc<"sbfv2", [FeatureSolana, FeatureDynamicFrames, FeatureSdiv, FeatureRelocAbs64, FeatureStaticSyscalls, + FeatureDisableNeg, FeatureReverseSubImm]>; //===----------------------------------------------------------------------===// // Assembly printer diff --git a/llvm/lib/Target/SBF/SBFInstrInfo.td b/llvm/lib/Target/SBF/SBFInstrInfo.td index 2acc18db400563..9874b80e23e20a 100644 --- a/llvm/lib/Target/SBF/SBFInstrInfo.td +++ b/llvm/lib/Target/SBF/SBFInstrInfo.td @@ -56,6 +56,10 @@ def SBFNoALU32 : Predicate<"!Subtarget->getHasAlu32()">; def SBFSubtargetSolana : Predicate<"Subtarget->isSolana()">; def SBFv2 : Predicate<"Subtarget->isSBFv2()">; def NoSBFv2 : Predicate<"!Subtarget->isSBFv2()">; +def SBFHasNeg : Predicate<"!Subtarget->getDisableNeg()">; +def SBFNoNeg: Predicate<"Subtarget->getDisableNeg()">; +def SBFRevSub : Predicate<"Subtarget->getReverseSubImm()">; +def SBFNoRevSub : Predicate<"!Subtarget->getReverseSubImm()">; def brtarget : Operand { let PrintMethod = "printBrTargetOperand"; @@ -347,14 +351,14 @@ let Constraints = "$dst = $src2" in { // 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]>; + (SUB_ri GPR:$src, i64immSExt32:$imm)>, Requires<[SBFNoRevSub]>; def : Pat<(sub GPR32:$src, i32immSExt32:$imm), - (SUB_ri_32 GPR32:$src, i32immSExt32:$imm)>, Requires<[NoSBFv2]>; + (SUB_ri_32 GPR32:$src, i32immSExt32:$imm)>, Requires<[SBFNoRevSub]>; def : Pat<(sub i64immSExt32:$imm, GPR:$src), - (SUB_ri GPR:$src, i64immSExt32:$imm)>, Requires<[SBFv2]>; + (SUB_ri GPR:$src, i64immSExt32:$imm)>, Requires<[SBFRevSub]>; def : Pat<(sub i32immSExt32:$imm, GPR32:$src), - (SUB_ri_32 GPR32:$src, i32immSExt32:$imm)>, Requires<[SBFv2]>; + (SUB_ri_32 GPR32:$src, i32immSExt32:$imm)>, Requires<[SBFRevSub]>; class NEG_RR pattern> @@ -376,11 +380,11 @@ let Constraints = "$dst = $src", isAsCheapAsAMove = 1 in { // 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), (NEG_64 GPR:$src)>, Requires<[SBFHasNeg]>; +def : Pat<(ineg i32:$src), (NEG_32 GPR32:$src)>, Requires<[SBFHasNeg]>; -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]>; +def : Pat<(ineg i64:$src), (SUB_ri GPR:$src, 0)>, Requires<[SBFNoNeg]>; +def : Pat<(ineg i32:$src), (SUB_ri_32 GPR32:$src, 0)>, Requires<[SBFNoNeg]>; class LD_IMM64 Pseudo, string Mnemonic> diff --git a/llvm/lib/Target/SBF/SBFSubtarget.h b/llvm/lib/Target/SBF/SBFSubtarget.h index 613e0168f45c3a..0f1fb78f2522e5 100644 --- a/llvm/lib/Target/SBF/SBFSubtarget.h +++ b/llvm/lib/Target/SBF/SBFSubtarget.h @@ -75,6 +75,13 @@ class SBFSubtarget : public SBFGenSubtargetInfo { // whether we are targeting SBFv2 bool IsSBFv2; + // Whether to disable the negate (neg) instruction + bool DisableNeg; + + // Whether to consider 'sub reg, imm' as 'reg = imm - reg', instead of 'reg = + // reg - imm'. + bool ReverseSubImm; + public: // This constructor initializes the data members to match that // of the specified triple. @@ -95,6 +102,8 @@ class SBFSubtarget : public SBFGenSubtargetInfo { bool getHasSdiv() const { return HasSdiv; } bool getUseDwarfRIS() const { return UseDwarfRIS; } bool isSBFv2() const { return IsSBFv2; } + bool getDisableNeg() const { return DisableNeg; } + bool getReverseSubImm() const { return ReverseSubImm; } const SBFInstrInfo *getInstrInfo() const override { return &InstrInfo; } const SBFFrameLowering *getFrameLowering() const override {