mirror of
https://github.com/KarolS/millfork.git
synced 2024-12-23 23:30:22 +00:00
8080: Fix some stack-related optimizations
This commit is contained in:
parent
f04f5ec111
commit
5b3e812bb1
@ -419,7 +419,7 @@ object AlwaysGoodI80Optimizations {
|
|||||||
},
|
},
|
||||||
//20
|
//20
|
||||||
(Elidable & HasOpcode(PUSH) & HasRegisterParam(ZRegister.HL) & DoesntMatterWhatItDoesWith(ZRegister.DE)) ~
|
(Elidable & HasOpcode(PUSH) & HasRegisterParam(ZRegister.HL) & DoesntMatterWhatItDoesWith(ZRegister.DE)) ~
|
||||||
(Linear & Not(HasOpcodeIn(Set(POP, PUSH))) & Not(ReadsStackPointer)).* ~
|
(Linear & Not(HasOpcodeIn(Set(POP, PUSH))) & Not(ReadsStackPointer) & Not(Changes(DE))).* ~
|
||||||
(Elidable & HasOpcode(POP) & HasRegisterParam(ZRegister.DE)) ~~> { code =>
|
(Elidable & HasOpcode(POP) & HasRegisterParam(ZRegister.DE)) ~~> { code =>
|
||||||
ZLine.ld8(ZRegister.D, ZRegister.H) ::
|
ZLine.ld8(ZRegister.D, ZRegister.H) ::
|
||||||
ZLine.ld8(ZRegister.E, ZRegister.L) ::
|
ZLine.ld8(ZRegister.E, ZRegister.L) ::
|
||||||
@ -427,7 +427,7 @@ object AlwaysGoodI80Optimizations {
|
|||||||
},
|
},
|
||||||
//21
|
//21
|
||||||
(Elidable & HasOpcode(PUSH) & HasRegisterParam(ZRegister.HL) & DoesntMatterWhatItDoesWith(ZRegister.BC)) ~
|
(Elidable & HasOpcode(PUSH) & HasRegisterParam(ZRegister.HL) & DoesntMatterWhatItDoesWith(ZRegister.BC)) ~
|
||||||
(Linear & Not(HasOpcodeIn(Set(POP, PUSH))) & Not(ReadsStackPointer)).* ~
|
(Linear & Not(HasOpcodeIn(Set(POP, PUSH))) & Not(ReadsStackPointer) & Not(Changes(BC))).* ~
|
||||||
(Elidable & HasOpcode(POP) & HasRegisterParam(ZRegister.BC)) ~~> { code =>
|
(Elidable & HasOpcode(POP) & HasRegisterParam(ZRegister.BC)) ~~> { code =>
|
||||||
ZLine.ld8(ZRegister.B, ZRegister.H) ::
|
ZLine.ld8(ZRegister.B, ZRegister.H) ::
|
||||||
ZLine.ld8(ZRegister.C, ZRegister.L) ::
|
ZLine.ld8(ZRegister.C, ZRegister.L) ::
|
||||||
@ -435,7 +435,7 @@ object AlwaysGoodI80Optimizations {
|
|||||||
},
|
},
|
||||||
//22
|
//22
|
||||||
(Elidable & HasOpcode(PUSH) & HasRegisterParam(ZRegister.DE) & DoesntMatterWhatItDoesWith(ZRegister.HL)) ~
|
(Elidable & HasOpcode(PUSH) & HasRegisterParam(ZRegister.DE) & DoesntMatterWhatItDoesWith(ZRegister.HL)) ~
|
||||||
(Linear & Not(HasOpcodeIn(Set(POP, PUSH))) & Not(ReadsStackPointer)).* ~
|
(Linear & Not(HasOpcodeIn(Set(POP, PUSH))) & Not(ReadsStackPointer) & Not(Changes(HL))).* ~
|
||||||
(Elidable & HasOpcode(POP) & HasRegisterParam(ZRegister.HL)) ~~> { code =>
|
(Elidable & HasOpcode(POP) & HasRegisterParam(ZRegister.HL)) ~~> { code =>
|
||||||
ZLine.ld8(ZRegister.H, ZRegister.D) ::
|
ZLine.ld8(ZRegister.H, ZRegister.D) ::
|
||||||
ZLine.ld8(ZRegister.L, ZRegister.E) ::
|
ZLine.ld8(ZRegister.L, ZRegister.E) ::
|
||||||
@ -443,7 +443,7 @@ object AlwaysGoodI80Optimizations {
|
|||||||
},
|
},
|
||||||
//23
|
//23
|
||||||
(Elidable & HasOpcode(PUSH) & HasRegisterParam(ZRegister.BC) & DoesntMatterWhatItDoesWith(ZRegister.HL)) ~
|
(Elidable & HasOpcode(PUSH) & HasRegisterParam(ZRegister.BC) & DoesntMatterWhatItDoesWith(ZRegister.HL)) ~
|
||||||
(Linear & Not(HasOpcodeIn(Set(POP, PUSH))) & Not(ReadsStackPointer)).* ~
|
(Linear & Not(HasOpcodeIn(Set(POP, PUSH))) & Not(ReadsStackPointer) & Not(Changes(HL))).* ~
|
||||||
(Elidable & HasOpcode(POP) & HasRegisterParam(ZRegister.HL)) ~~> { code =>
|
(Elidable & HasOpcode(POP) & HasRegisterParam(ZRegister.HL)) ~~> { code =>
|
||||||
ZLine.ld8(ZRegister.H, ZRegister.B) ::
|
ZLine.ld8(ZRegister.H, ZRegister.B) ::
|
||||||
ZLine.ld8(ZRegister.L, ZRegister.C) ::
|
ZLine.ld8(ZRegister.L, ZRegister.C) ::
|
||||||
@ -451,7 +451,7 @@ object AlwaysGoodI80Optimizations {
|
|||||||
},
|
},
|
||||||
//24
|
//24
|
||||||
(Elidable & HasOpcode(PUSH) & HasRegisterParam(ZRegister.BC) & DoesntMatterWhatItDoesWith(ZRegister.DE)) ~
|
(Elidable & HasOpcode(PUSH) & HasRegisterParam(ZRegister.BC) & DoesntMatterWhatItDoesWith(ZRegister.DE)) ~
|
||||||
(Linear & Not(HasOpcodeIn(Set(POP, PUSH))) & Not(ReadsStackPointer)).* ~
|
(Linear & Not(HasOpcodeIn(Set(POP, PUSH))) & Not(ReadsStackPointer) & Not(Changes(DE))).* ~
|
||||||
(Elidable & HasOpcode(POP) & HasRegisterParam(ZRegister.DE)) ~~> { code =>
|
(Elidable & HasOpcode(POP) & HasRegisterParam(ZRegister.DE)) ~~> { code =>
|
||||||
ZLine.ld8(ZRegister.D, ZRegister.B) ::
|
ZLine.ld8(ZRegister.D, ZRegister.B) ::
|
||||||
ZLine.ld8(ZRegister.E, ZRegister.C) ::
|
ZLine.ld8(ZRegister.E, ZRegister.C) ::
|
||||||
@ -459,7 +459,7 @@ object AlwaysGoodI80Optimizations {
|
|||||||
},
|
},
|
||||||
//25
|
//25
|
||||||
(Elidable & HasOpcode(PUSH) & HasRegisterParam(ZRegister.DE) & DoesntMatterWhatItDoesWith(ZRegister.BC)) ~
|
(Elidable & HasOpcode(PUSH) & HasRegisterParam(ZRegister.DE) & DoesntMatterWhatItDoesWith(ZRegister.BC)) ~
|
||||||
(Linear & Not(HasOpcodeIn(Set(POP, PUSH))) & Not(ReadsStackPointer)).* ~
|
(Linear & Not(HasOpcodeIn(Set(POP, PUSH))) & Not(ReadsStackPointer) & Not(Changes(BC))).* ~
|
||||||
(Elidable & HasOpcode(POP) & HasRegisterParam(ZRegister.BC)) ~~> { code =>
|
(Elidable & HasOpcode(POP) & HasRegisterParam(ZRegister.BC)) ~~> { code =>
|
||||||
ZLine.ld8(ZRegister.B, ZRegister.D) ::
|
ZLine.ld8(ZRegister.B, ZRegister.D) ::
|
||||||
ZLine.ld8(ZRegister.C, ZRegister.E) ::
|
ZLine.ld8(ZRegister.C, ZRegister.E) ::
|
||||||
|
@ -99,8 +99,10 @@ abstract class AbstractStatementPreprocessor(protected val ctx: CompilationConte
|
|||||||
}
|
}
|
||||||
// generic warnings:
|
// generic warnings:
|
||||||
stmt match {
|
stmt match {
|
||||||
case ExpressionStatement(expr@FunctionCallExpression("strzlen" | "putstrz" | "strzcmp" | "strzcopy", params)) =>
|
case ExpressionStatement(expr@FunctionCallExpression("strzlen" | "putstrz" | "strzcmp" | "strzcopy" | "strzpaste", params)) =>
|
||||||
for (param <- params) checkIfNullTerminated(ctx, stmt, param)
|
for (param <- params) checkIfNullTerminated(ctx, stmt, param)
|
||||||
|
case ExpressionStatement(expr@FunctionCallExpression("pstrlen" | "putpstr" | "pstrcmp" | "pstrcopy" | "pstrpaste", params)) =>
|
||||||
|
for (param <- params) checkIfLengthPrefixed(ctx, stmt, param)
|
||||||
|
|
||||||
case ExpressionStatement(expr@FunctionCallExpression(f, List(VariableExpression(v)))) if hiddenEffectFreeFunctions(f)=>
|
case ExpressionStatement(expr@FunctionCallExpression(f, List(VariableExpression(v)))) if hiddenEffectFreeFunctions(f)=>
|
||||||
val volatile = ctx.env.maybeGet[ThingInMemory](v).fold(false)(_.isVolatile)
|
val volatile = ctx.env.maybeGet[ThingInMemory](v).fold(false)(_.isVolatile)
|
||||||
@ -276,14 +278,34 @@ abstract class AbstractStatementPreprocessor(protected val ctx: CompilationConte
|
|||||||
val TERMINATOR = ctx.options.platform.defaultCodec.stringTerminator.head
|
val TERMINATOR = ctx.options.platform.defaultCodec.stringTerminator.head
|
||||||
param match {
|
param match {
|
||||||
case TextLiteralExpression(ch) =>
|
case TextLiteralExpression(ch) =>
|
||||||
ch.last match {
|
ch.lastOption match {
|
||||||
case LiteralExpression(TERMINATOR, _) => //ok
|
case Some(LiteralExpression(TERMINATOR, _)) => //ok
|
||||||
case _ => ctx.log.warn("Passing a non-null-terminated string to a function that expects a null-terminated string.", stmt.position)
|
case _ => ctx.log.warn("Passing a non-null-terminated string to a function that expects a null-terminated string.", stmt.position)
|
||||||
}
|
}
|
||||||
case _ =>
|
case _ =>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private def checkIfLengthPrefixed(ctx: CompilationContext, stmt: ExecutableStatement, param: Expression): Unit = {
|
||||||
|
if (!ctx.options.flag(CompilationFlag.BuggyCodeWarning)) return
|
||||||
|
val TERMINATOR = ctx.options.platform.defaultCodec.stringTerminator.head
|
||||||
|
param match {
|
||||||
|
case TextLiteralExpression(ch) =>
|
||||||
|
if (ch.headOption match {
|
||||||
|
case Some(LiteralExpression(length, _)) if length == ch.size - 1 => false
|
||||||
|
case Some(LiteralExpression(length, _)) if length == ch.size + 2 =>
|
||||||
|
ch.lastOption match {
|
||||||
|
case Some(LiteralExpression(TERMINATOR, _)) => false
|
||||||
|
case _ => true
|
||||||
|
}
|
||||||
|
case _ => true
|
||||||
|
}) {
|
||||||
|
ctx.log.warn("Passing a non-length-prefixed string to a function that expects a length-prefixed string.", stmt.position)
|
||||||
|
}
|
||||||
|
case _ =>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def search(expr: Expression, cv: VV): VV = {
|
def search(expr: Expression, cv: VV): VV = {
|
||||||
expr match {
|
expr match {
|
||||||
case FunctionCallExpression(op, List(VariableExpression(v), arg)) if op.endsWith("=") && op != "<=" && op != ">=" =>
|
case FunctionCallExpression(op, List(VariableExpression(v), arg)) if op.endsWith("=") && op != "<=" && op != ">=" =>
|
||||||
|
Loading…
Reference in New Issue
Block a user