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
|
||||
(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 =>
|
||||
ZLine.ld8(ZRegister.D, ZRegister.H) ::
|
||||
ZLine.ld8(ZRegister.E, ZRegister.L) ::
|
||||
@ -427,7 +427,7 @@ object AlwaysGoodI80Optimizations {
|
||||
},
|
||||
//21
|
||||
(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 =>
|
||||
ZLine.ld8(ZRegister.B, ZRegister.H) ::
|
||||
ZLine.ld8(ZRegister.C, ZRegister.L) ::
|
||||
@ -435,7 +435,7 @@ object AlwaysGoodI80Optimizations {
|
||||
},
|
||||
//22
|
||||
(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 =>
|
||||
ZLine.ld8(ZRegister.H, ZRegister.D) ::
|
||||
ZLine.ld8(ZRegister.L, ZRegister.E) ::
|
||||
@ -443,7 +443,7 @@ object AlwaysGoodI80Optimizations {
|
||||
},
|
||||
//23
|
||||
(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 =>
|
||||
ZLine.ld8(ZRegister.H, ZRegister.B) ::
|
||||
ZLine.ld8(ZRegister.L, ZRegister.C) ::
|
||||
@ -451,7 +451,7 @@ object AlwaysGoodI80Optimizations {
|
||||
},
|
||||
//24
|
||||
(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 =>
|
||||
ZLine.ld8(ZRegister.D, ZRegister.B) ::
|
||||
ZLine.ld8(ZRegister.E, ZRegister.C) ::
|
||||
@ -459,7 +459,7 @@ object AlwaysGoodI80Optimizations {
|
||||
},
|
||||
//25
|
||||
(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 =>
|
||||
ZLine.ld8(ZRegister.B, ZRegister.D) ::
|
||||
ZLine.ld8(ZRegister.C, ZRegister.E) ::
|
||||
|
@ -99,8 +99,10 @@ abstract class AbstractStatementPreprocessor(protected val ctx: CompilationConte
|
||||
}
|
||||
// generic warnings:
|
||||
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)
|
||||
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)=>
|
||||
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
|
||||
param match {
|
||||
case TextLiteralExpression(ch) =>
|
||||
ch.last match {
|
||||
case LiteralExpression(TERMINATOR, _) => //ok
|
||||
ch.lastOption match {
|
||||
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 _ =>
|
||||
}
|
||||
}
|
||||
|
||||
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 = {
|
||||
expr match {
|
||||
case FunctionCallExpression(op, List(VariableExpression(v), arg)) if op.endsWith("=") && op != "<=" && op != ">=" =>
|
||||
|
Loading…
Reference in New Issue
Block a user