mirror of
https://github.com/irmen/prog8.git
synced 2024-12-25 23:29:55 +00:00
use non-stack call conv for builtin functions
This commit is contained in:
parent
29f5a85158
commit
ebc2c614d7
@ -1045,10 +1045,36 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
||||
|
||||
private fun translateArguments(args: MutableList<Expression>, signature: FSignature) {
|
||||
val callConv = signature.callConvention(args.map { it.inferType(program).typeOrElse(DataType.STRUCT) })
|
||||
print("ARGS FOR ${signature.name} -> CALLCONV = $callConv") // TODO actually use the call convention
|
||||
|
||||
args.forEach {
|
||||
asmgen.translateExpression(it) // TODO if possible, function args via registers
|
||||
args.zip(callConv.params).zip(signature.parameters).forEach {
|
||||
val paramName = it.second.name
|
||||
val conv = it.first.second
|
||||
val value = it.first.first
|
||||
when {
|
||||
conv.variable -> {
|
||||
val varname = "prog8_lib.func_${signature.name}_cc.arg_${paramName}" // TODO after all builtin funcs have been changed into _cc, remove that suffix again
|
||||
val src = AsmAssignSource.fromAstSource(value, program, asmgen)
|
||||
val tgt = AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, conv.dt, null, variableAsmName = varname)
|
||||
val assign = AsmAssignment(src, tgt, false, value.position)
|
||||
asmgen.translateNormalAssignment(assign)
|
||||
}
|
||||
conv.reg != null -> {
|
||||
if(conv.dt==DataType.FLOAT || conv.dt in PassByReferenceDatatypes) {
|
||||
// put the address of the argument in AY
|
||||
val addr = AddressOf(value as IdentifierReference, value.position)
|
||||
val src = AsmAssignSource.fromAstSource(addr, program, asmgen)
|
||||
val tgt = AsmAssignTarget.fromRegisters(conv.reg, null, program, asmgen)
|
||||
val assign = AsmAssignment(src, tgt, false, value.position)
|
||||
asmgen.translateNormalAssignment(assign)
|
||||
} else {
|
||||
val src = AsmAssignSource.fromAstSource(value, program, asmgen)
|
||||
val tgt = AsmAssignTarget.fromRegisters(conv.reg, null, program, asmgen)
|
||||
val assign = AsmAssignment(src, tgt, false, value.position)
|
||||
asmgen.translateNormalAssignment(assign)
|
||||
}
|
||||
}
|
||||
else -> throw AssemblyError("callconv")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,8 +15,8 @@ class FParam(val name: String, val possibleDatatypes: Set<DataType>)
|
||||
typealias ConstExpressionCaller = (args: List<Expression>, position: Position, program: Program) -> NumericLiteralValue
|
||||
|
||||
|
||||
class ReturnConvention(val reg: RegisterOrPair?, val floatFac1: Boolean)
|
||||
class ParamConvention(val reg: RegisterOrPair?, val variable: Boolean)
|
||||
class ReturnConvention(val dt: DataType, val reg: RegisterOrPair?, val floatFac1: Boolean)
|
||||
class ParamConvention(val dt: DataType, val reg: RegisterOrPair?, val variable: Boolean)
|
||||
class CallConvention(val params: List<ParamConvention>, val returns: ReturnConvention) {
|
||||
override fun toString(): String {
|
||||
val paramConvs = params.mapIndexed { index, it ->
|
||||
@ -45,22 +45,23 @@ class FSignature(val name: String,
|
||||
|
||||
fun callConvention(actualParamTypes: List<DataType>): CallConvention {
|
||||
val returns = when(known_returntype) {
|
||||
DataType.UBYTE, DataType.BYTE -> ReturnConvention(RegisterOrPair.A, false)
|
||||
DataType.UWORD, DataType.WORD -> ReturnConvention(RegisterOrPair.AY, false)
|
||||
DataType.FLOAT -> ReturnConvention(null, true)
|
||||
in PassByReferenceDatatypes -> ReturnConvention(RegisterOrPair.AY, false)
|
||||
DataType.UBYTE, DataType.BYTE -> ReturnConvention(known_returntype, RegisterOrPair.A, false)
|
||||
DataType.UWORD, DataType.WORD -> ReturnConvention(known_returntype, RegisterOrPair.AY, false)
|
||||
DataType.FLOAT -> ReturnConvention(known_returntype, null, true)
|
||||
in PassByReferenceDatatypes -> ReturnConvention(known_returntype!!, RegisterOrPair.AY, false)
|
||||
else -> {
|
||||
val paramType = actualParamTypes.first()
|
||||
if(pure)
|
||||
// return type depends on arg type
|
||||
when(actualParamTypes.first()) {
|
||||
DataType.UBYTE, DataType.BYTE -> ReturnConvention(RegisterOrPair.A, false)
|
||||
DataType.UWORD, DataType.WORD -> ReturnConvention(RegisterOrPair.AY, false)
|
||||
DataType.FLOAT -> ReturnConvention(null, true)
|
||||
in PassByReferenceDatatypes -> ReturnConvention(RegisterOrPair.AY, false)
|
||||
else -> ReturnConvention(null, false)
|
||||
when(paramType) {
|
||||
DataType.UBYTE, DataType.BYTE -> ReturnConvention(paramType, RegisterOrPair.A, false)
|
||||
DataType.UWORD, DataType.WORD -> ReturnConvention(paramType, RegisterOrPair.AY, false)
|
||||
DataType.FLOAT -> ReturnConvention(paramType, null, true)
|
||||
in PassByReferenceDatatypes -> ReturnConvention(paramType, RegisterOrPair.AY, false)
|
||||
else -> ReturnConvention(paramType, null, false)
|
||||
}
|
||||
else {
|
||||
ReturnConvention(null, false)
|
||||
ReturnConvention(paramType, null, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -68,18 +69,19 @@ class FSignature(val name: String,
|
||||
actualParamTypes.isEmpty() -> CallConvention(emptyList(), returns)
|
||||
actualParamTypes.size==1 -> {
|
||||
// one parameter? via register/registerpair
|
||||
val paramConv = when(actualParamTypes[0]) {
|
||||
DataType.UBYTE, DataType.BYTE -> ParamConvention(RegisterOrPair.A, false)
|
||||
DataType.UWORD, DataType.WORD -> ParamConvention(RegisterOrPair.AY, false)
|
||||
DataType.FLOAT -> ParamConvention(RegisterOrPair.AY, false)
|
||||
in PassByReferenceDatatypes -> ParamConvention(RegisterOrPair.AY, false)
|
||||
else -> ParamConvention(null, false)
|
||||
val paramType = actualParamTypes[0]
|
||||
val paramConv = when(paramType) {
|
||||
DataType.UBYTE, DataType.BYTE -> ParamConvention(paramType, RegisterOrPair.A, false)
|
||||
DataType.UWORD, DataType.WORD -> ParamConvention(paramType, RegisterOrPair.AY, false)
|
||||
DataType.FLOAT -> ParamConvention(paramType, RegisterOrPair.AY, false)
|
||||
in PassByReferenceDatatypes -> ParamConvention(paramType, RegisterOrPair.AY, false)
|
||||
else -> ParamConvention(paramType, null, false)
|
||||
}
|
||||
CallConvention(listOf(paramConv), returns)
|
||||
}
|
||||
else -> {
|
||||
// multiple parameters? via variables
|
||||
val paramConvs = actualParamTypes.map { ParamConvention(null, true) }
|
||||
val paramConvs = actualParamTypes.map { ParamConvention(it, null, true) }
|
||||
CallConvention(paramConvs, returns)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user