diff --git a/DMCompiler/DM/Builders/DMASTFolder.cs b/DMCompiler/DM/Builders/DMASTFolder.cs index b3058f23a6..89f01fd584 100644 --- a/DMCompiler/DM/Builders/DMASTFolder.cs +++ b/DMCompiler/DM/Builders/DMASTFolder.cs @@ -219,27 +219,6 @@ private DMASTExpression FoldExpression(DMASTExpression? expression) { break; } - case DMASTBinaryAnd binaryAnd: { - if (binaryAnd is { LHS: DMASTConstantInteger lhsInt, RHS: DMASTConstantInteger rhsInt }) { - return new DMASTConstantInteger(expression.Location, lhsInt.Value & rhsInt.Value); - } - - break; - } - case DMASTBinaryOr binaryOr: { - if (binaryOr is { LHS: DMASTConstantInteger lhsInt, RHS: DMASTConstantInteger rhsInt }) { - return new DMASTConstantInteger(expression.Location, lhsInt.Value | rhsInt.Value); - } - - break; - } - case DMASTBinaryNot binaryNot: { - if (binaryNot.Value is DMASTConstantInteger exprInt) { - return new DMASTConstantInteger(expression.Location, (~exprInt.Value) & 0xFFFFFF); - } - - break; - } case DMASTAdd add: { DMASTConstantString? lhsString = add.LHS as DMASTConstantString; DMASTConstantString? rhsString = add.RHS as DMASTConstantString; diff --git a/DMCompiler/Optimizer/PeepholeOptimizations.cs b/DMCompiler/Optimizer/PeepholeOptimizations.cs index 6f5c04d2f7..228faaf4cf 100644 --- a/DMCompiler/Optimizer/PeepholeOptimizations.cs +++ b/DMCompiler/Optimizer/PeepholeOptimizations.cs @@ -618,6 +618,78 @@ public void Apply(List input, int index) { } #region Constant Folding + +// PushFloat [constant] +// BitNot +// -> PushFloat [result] +internal sealed class ConstFoldBitNot : IPeepholeOptimization { + public ReadOnlySpan GetOpcodes() { + return [ + DreamProcOpcode.PushFloat, + DreamProcOpcode.BitNot + ]; + } + + public void Apply(List input, int index) { + var firstInstruction = IPeepholeOptimization.GetInstructionAndValue(input[index], out var pushVal1); + + var args = new List(1) {new AnnotatedBytecodeFloat(((~(int)pushVal1) & 0xFFFFFF), firstInstruction.Location)}; + + IPeepholeOptimization.ReplaceInstructions(input, index, 2, + new AnnotatedBytecodeInstruction(DreamProcOpcode.PushFloat, 1, args)); + } +} + +// PushFloat [constant] +// PushFloat [constant] +// BitOr +// -> PushFloat [result] +internal sealed class ConstFoldBitOr : IPeepholeOptimization { + public ReadOnlySpan GetOpcodes() { + return [ + DreamProcOpcode.PushFloat, + DreamProcOpcode.PushFloat, + DreamProcOpcode.BitOr, + ]; + } + + public void Apply(List input, int index) { + var firstInstruction = IPeepholeOptimization.GetInstructionAndValue(input[index], out var pushVal1); + + IPeepholeOptimization.GetInstructionAndValue(input[index + 1], out var pushVal2); + + var args = new List(1) {new AnnotatedBytecodeFloat(((int)pushVal1 | (int)pushVal2), firstInstruction.Location)}; + + IPeepholeOptimization.ReplaceInstructions(input, index, 3, + new AnnotatedBytecodeInstruction(DreamProcOpcode.PushFloat, 1, args)); + } +} + +// PushFloat [constant] +// PushFloat [constant] +// BitAnd +// -> PushFloat [result] +internal sealed class ConstFoldBitAnd : IPeepholeOptimization { + public ReadOnlySpan GetOpcodes() { + return [ + DreamProcOpcode.PushFloat, + DreamProcOpcode.PushFloat, + DreamProcOpcode.BitAnd, + ]; + } + + public void Apply(List input, int index) { + var firstInstruction = IPeepholeOptimization.GetInstructionAndValue(input[index], out var pushVal1); + + IPeepholeOptimization.GetInstructionAndValue(input[index + 1], out var pushVal2); + + var args = new List(1) {new AnnotatedBytecodeFloat(((int)pushVal1 & (int)pushVal2), firstInstruction.Location)}; + + IPeepholeOptimization.ReplaceInstructions(input, index, 3, + new AnnotatedBytecodeInstruction(DreamProcOpcode.PushFloat, 1, args)); + } +} + // PushFloat [constant] // PushFloat [constant] // Multiply