1
0
mirror of https://github.com/KarolS/millfork.git synced 2024-07-05 09:28:54 +00:00

Z80: Faster calling convention

This commit is contained in:
Karol Stasiak 2018-07-24 01:43:59 +02:00
parent c9cbd267c5
commit 9bcaffaa30
6 changed files with 67 additions and 9 deletions

View File

@ -38,7 +38,11 @@
#### Parameters:
* all parameters are passed via static locations
* if the function has one parameter of size one byte, it is passed via the A register
* if the function has one parameter of size two bytes, it is passed via the HL register pair
* otherwise, all parameters are passed via static locations
#### Return values:

View File

@ -322,15 +322,53 @@ object ReverseFlowAnalyzer {
currentImportance = currentImportance.butWritesRegister(r)
case ZLine(PUSH, OneRegister(r), _, _) =>
currentImportance = currentImportance.butReadsRegister(r)
case ZLine(CALL, NoRegisters, MemoryAddressConstant(fun: FunctionInMemory), _) =>
case ZLine(CALL | JP, NoRegisters, MemoryAddressConstant(fun: FunctionInMemory), _) =>
fun.params match {
case NormalParamSignature(_) | AssemblyParamSignature(Nil) =>
currentImportance.copy(
case NormalParamSignature(List(v)) if v.typ.size == 1 =>
currentImportance = currentImportance.copy(
a = Important,
b = Unimportant,
c = Unimportant,
d = Unimportant,
e = Unimportant,
h = Unimportant,
l = Unimportant,
hlNumeric = Unimportant,
iyh = Unimportant,
iyl = Unimportant,
zf = Unimportant,
cf = Unimportant,
nf = Unimportant,
sf = Unimportant,
hf = Unimportant
)
case NormalParamSignature(List(v)) if v.typ.size == 2 =>
currentImportance = currentImportance.copy(
a = Unimportant,
b = Unimportant,
c = Unimportant,
d = Unimportant,
e = Unimportant,
h = Important,
l = Important,
hlNumeric = Unimportant,
iyh = Unimportant,
iyl = Unimportant,
zf = Unimportant,
cf = Unimportant,
nf = Unimportant,
sf = Unimportant,
hf = Unimportant
)
case NormalParamSignature(_) | AssemblyParamSignature(Nil) =>
currentImportance = currentImportance.copy(
a = Unimportant,
b = Unimportant,
c = Unimportant,
d = Unimportant,
e = Unimportant,
h = Unimportant,
l = Unimportant,
hlNumeric = Unimportant,
iyh = Unimportant,
iyl = Unimportant,

View File

@ -24,8 +24,10 @@ object VariableStatus {
val flow = FlowAnalyzer.analyze(f, code, optimizationContext.options, FlowInfoRequirement.BothFlows)
import millfork.node.ZRegister._
val paramVariables = f.params match {
// case NormalParamSignature(List(MemoryVariable(_, typ, _))) if typ.size == 1 =>
// Set[String]()
case NormalParamSignature(List(MemoryVariable(_, typ, _))) if typ.size == 1 =>
Set[String]()
case NormalParamSignature(List(MemoryVariable(_, typ, _))) if typ.size == 2 =>
Set[String]()
case NormalParamSignature(ps) =>
ps.map(_.name).toSet
case _ =>

View File

@ -5,7 +5,7 @@ import java.util.concurrent.atomic.AtomicLong
import millfork.CompilationFlag
import millfork.assembly.z80.ZLine
import millfork.compiler.{AbstractCompiler, CompilationContext}
import millfork.env.Label
import millfork.env.{Label, NormalParamSignature}
import millfork.error.ErrorReporting
import millfork.node.ZRegister
@ -22,8 +22,14 @@ object Z80Compiler extends AbstractCompiler[ZLine] {
ctx.env.nameCheck(ctx.function.code)
val chunk = Z80StatementCompiler.compile(ctx, ctx.function.code)
val label = ZLine.label(Label(ctx.function.name)).copy(elidable = false)
val prefix = Nil // TODO
label :: (prefix ++ stackPointerFixAtBeginning(ctx) ++ chunk)
val storeParamsFromRegisters = ctx.function.params match {
case NormalParamSignature(List(param)) if param.typ.size == 1 =>
List(ZLine.ldAbs8(param.toAddress, ZRegister.A))
case NormalParamSignature(List(param)) if param.typ.size == 2 =>
List(ZLine.ldAbs16(param.toAddress, ZRegister.HL))
case _ => Nil
}
label :: (storeParamsFromRegisters ++ stackPointerFixAtBeginning(ctx) ++ chunk)
}
def stackPointerFixAtBeginning(ctx: CompilationContext): List[ZLine] = {

View File

@ -545,6 +545,10 @@ object Z80ExpressionCompiler extends AbstractExpressionCompiler[ZLine] {
case AssemblyParamSignature(paramConvs) =>
// TODO: stop being lazy and implement this
???
case NormalParamSignature(List(param)) if param.typ.size == 1 =>
compileToA(ctx, params.head) :+ ZLine(CALL, NoRegisters, function.toAddress)
case NormalParamSignature(List(param)) if param.typ.size == 2 =>
compileToHL(ctx, params.head) :+ ZLine(CALL, NoRegisters, function.toAddress)
case NormalParamSignature(paramVars) =>
params.zip(paramVars).flatMap {
case (paramExpr, paramVar) =>

View File

@ -109,6 +109,10 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa
f.params match {
case NormalParamSignature(List(MemoryVariable(_, typ, _))) if typ.size == 1 && options.platform.cpuFamily == CpuFamily.M6502 =>
Nil
case NormalParamSignature(List(MemoryVariable(_, typ, _))) if typ.size == 1 && options.platform.cpuFamily == CpuFamily.I80 =>
Nil
case NormalParamSignature(List(MemoryVariable(_, typ, _))) if typ.size == 2 && options.platform.cpuFamily == CpuFamily.I80 =>
Nil
case NormalParamSignature(ps) =>
ps.map(p => p.name)
case _ =>