added msw() and lsw() builtin functions (experimental)

This commit is contained in:
Irmen de Jong 2024-11-24 03:53:03 +01:00
parent cb86206698
commit cc53d698bf
13 changed files with 40 additions and 9 deletions

View File

@ -92,7 +92,7 @@ sealed class PtExpression(val type: DataType, position: Position) : PtNode(posit
is PtBinaryExpression -> false is PtBinaryExpression -> false
is PtBuiltinFunctionCall -> { is PtBuiltinFunctionCall -> {
when (name) { when (name) {
in arrayOf("msb", "lsb", "bankof", "mkword", "set_carry", "set_irqd", "clear_carry", "clear_irqd") -> this.args.all { it.isSimple() } in arrayOf("msb", "lsb", "msw", "lsw", "bankof", "mkword", "set_carry", "set_irqd", "clear_carry", "clear_irqd") -> this.args.all { it.isSimple() }
else -> false else -> false
} }
} }

View File

@ -110,7 +110,9 @@ val BuiltinFunctions: Map<String, FSignature> = mapOf(
"divmod__ubyte" to FSignature(false, listOf(FParam("dividend", arrayOf(DataType.UBYTE)), FParam("divisor", arrayOf(DataType.UBYTE)), FParam("quotient", arrayOf(DataType.UBYTE)), FParam("remainder", arrayOf(DataType.UBYTE))), null), "divmod__ubyte" to FSignature(false, listOf(FParam("dividend", arrayOf(DataType.UBYTE)), FParam("divisor", arrayOf(DataType.UBYTE)), FParam("quotient", arrayOf(DataType.UBYTE)), FParam("remainder", arrayOf(DataType.UBYTE))), null),
"divmod__uword" to FSignature(false, listOf(FParam("dividend", arrayOf(DataType.UWORD)), FParam("divisor", arrayOf(DataType.UWORD)), FParam("quotient", arrayOf(DataType.UWORD)), FParam("remainder", arrayOf(DataType.UWORD))), null), "divmod__uword" to FSignature(false, listOf(FParam("dividend", arrayOf(DataType.UWORD)), FParam("divisor", arrayOf(DataType.UWORD)), FParam("quotient", arrayOf(DataType.UWORD)), FParam("remainder", arrayOf(DataType.UWORD))), null),
"lsb" to FSignature(true, listOf(FParam("value", arrayOf(DataType.UWORD, DataType.WORD, DataType.LONG))), DataType.UBYTE), "lsb" to FSignature(true, listOf(FParam("value", arrayOf(DataType.UWORD, DataType.WORD, DataType.LONG))), DataType.UBYTE),
"lsw" to FSignature(true, listOf(FParam("value", arrayOf(DataType.UWORD, DataType.WORD, DataType.LONG))), DataType.UWORD),
"msb" to FSignature(true, listOf(FParam("value", arrayOf(DataType.UWORD, DataType.WORD, DataType.LONG))), DataType.UBYTE), "msb" to FSignature(true, listOf(FParam("value", arrayOf(DataType.UWORD, DataType.WORD, DataType.LONG))), DataType.UBYTE),
"msw" to FSignature(true, listOf(FParam("value", arrayOf(DataType.UWORD, DataType.WORD, DataType.LONG))), DataType.UWORD),
"bankof" to FSignature(true, listOf(FParam("value", arrayOf(DataType.UWORD, DataType.WORD, DataType.LONG))), DataType.UBYTE), "bankof" to FSignature(true, listOf(FParam("value", arrayOf(DataType.UWORD, DataType.WORD, DataType.LONG))), DataType.UBYTE),
"mkword" to FSignature(true, listOf(FParam("msb", arrayOf(DataType.UBYTE)), FParam("lsb", arrayOf(DataType.UBYTE))), DataType.UWORD), "mkword" to FSignature(true, listOf(FParam("msb", arrayOf(DataType.UBYTE)), FParam("lsb", arrayOf(DataType.UBYTE))), DataType.UWORD),
"clamp" to FSignature(true, listOf(FParam("value", arrayOf(DataType.BYTE)), FParam("minimum", arrayOf(DataType.BYTE)), FParam("maximum", arrayOf(DataType.BYTE))), null), "clamp" to FSignature(true, listOf(FParam("value", arrayOf(DataType.BYTE)), FParam("minimum", arrayOf(DataType.BYTE)), FParam("maximum", arrayOf(DataType.BYTE))), null),

View File

@ -25,6 +25,8 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
when (fcall.name) { when (fcall.name) {
"bankof" -> throw AssemblyError("bankof() should have been replaced by a const value (either the bank number of a long const, or zero for any other smaller value)") "bankof" -> throw AssemblyError("bankof() should have been replaced by a const value (either the bank number of a long const, or zero for any other smaller value)")
"lsw" -> throw AssemblyError("lsw() should have been removed or replaced by a const value")
"msw" -> throw AssemblyError("msw() should have been removed or replaced by a const value")
"msb" -> funcMsb(fcall, resultRegister) "msb" -> funcMsb(fcall, resultRegister)
"lsb" -> funcLsb(fcall, resultRegister) "lsb" -> funcLsb(fcall, resultRegister)
"mkword" -> funcMkword(fcall, resultRegister) "mkword" -> funcMkword(fcall, resultRegister)

View File

@ -161,7 +161,7 @@ internal class FunctionCallAsmGen(private val program: PtProgram, private val as
private fun usesOtherRegistersWhileEvaluating(arg: PtExpression): Boolean { private fun usesOtherRegistersWhileEvaluating(arg: PtExpression): Boolean {
return when(arg) { return when(arg) {
is PtBuiltinFunctionCall -> { is PtBuiltinFunctionCall -> {
if (arg.name in arrayOf("lsb", "msb", "bankof")) if (arg.name in arrayOf("lsb", "msb", "lsw", "msw", "bankof"))
return usesOtherRegistersWhileEvaluating(arg.args[0]) return usesOtherRegistersWhileEvaluating(arg.args[0])
if (arg.name == "mkword") if (arg.name == "mkword")
return usesOtherRegistersWhileEvaluating(arg.args[0]) || usesOtherRegistersWhileEvaluating(arg.args[1]) return usesOtherRegistersWhileEvaluating(arg.args[0]) || usesOtherRegistersWhileEvaluating(arg.args[1])

View File

@ -928,7 +928,7 @@ internal class AssignmentAsmGen(
is PtIdentifier -> true is PtIdentifier -> true
is PtIrRegister -> true is PtIrRegister -> true
is PtNumber -> true is PtNumber -> true
is PtBuiltinFunctionCall -> expr.name in arrayOf("lsb", "msb", "bankof") is PtBuiltinFunctionCall -> expr.name in arrayOf("lsb", "msb", "lsw", "msw", "bankof")
else -> false else -> false
} }
} }

View File

@ -20,6 +20,8 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
"callfar2" -> funcCallfar2(call) "callfar2" -> funcCallfar2(call)
"call" -> funcCall(call) "call" -> funcCall(call)
"bankof" -> throw AssemblyError("bankof() should have been replaced by a const value (either the bank number of a long const, or zero for any other smaller value)") "bankof" -> throw AssemblyError("bankof() should have been replaced by a const value (either the bank number of a long const, or zero for any other smaller value)")
"lsw" -> throw AssemblyError("lsw() should have been removed or replaced by a const value")
"msw" -> throw AssemblyError("msw() should have been removed or replaced by a const value")
"msb" -> funcMsb(call) "msb" -> funcMsb(call)
"lsb" -> funcLsb(call) "lsb" -> funcLsb(call)
"memory" -> funcMemory(call) "memory" -> funcMemory(call)

View File

@ -20,7 +20,9 @@ internal val constEvaluatorsForBuiltinFuncs: Map<String, ConstExpressionCaller>
"sqrt__uword" to { a, p, prg -> oneIntArgOutputInt(a, p, prg, false) { sqrt(it.toDouble()) } }, "sqrt__uword" to { a, p, prg -> oneIntArgOutputInt(a, p, prg, false) { sqrt(it.toDouble()) } },
"sqrt__float" to { a, p, prg -> oneFloatArgOutputFloat(a, p, prg) { sqrt(it) } }, "sqrt__float" to { a, p, prg -> oneFloatArgOutputFloat(a, p, prg) { sqrt(it) } },
"lsb" to { a, p, prg -> oneIntArgOutputInt(a, p, prg, true) { x: Int -> (x and 255).toDouble() } }, "lsb" to { a, p, prg -> oneIntArgOutputInt(a, p, prg, true) { x: Int -> (x and 255).toDouble() } },
"lsw" to { a, p, prg -> oneIntArgOutputInt(a, p, prg, true) { x: Int -> (x and 65535).toDouble() } },
"msb" to { a, p, prg -> oneIntArgOutputInt(a, p, prg, true) { x: Int -> (x ushr 8 and 255).toDouble()} }, "msb" to { a, p, prg -> oneIntArgOutputInt(a, p, prg, true) { x: Int -> (x ushr 8 and 255).toDouble()} },
"msw" to { a, p, prg -> oneIntArgOutputInt(a, p, prg, true) { x: Int -> (x ushr 16 and 65535).toDouble()} },
"bankof" to { a, p, prg -> oneIntArgOutputInt(a, p, prg, true) { x: Int -> (x ushr 16 and 255).toDouble()} }, "bankof" to { a, p, prg -> oneIntArgOutputInt(a, p, prg, true) { x: Int -> (x ushr 16 and 255).toDouble()} },
"mkword" to ::builtinMkword, "mkword" to ::builtinMkword,
"clamp__ubyte" to ::builtinClampUByte, "clamp__ubyte" to ::builtinClampUByte,

View File

@ -1514,7 +1514,8 @@ internal class AstChecker(private val program: Program,
ident = arg.value as IdentifierReference ident = arg.value as IdentifierReference
else if(arg.value is FunctionCallExpression) { else if(arg.value is FunctionCallExpression) {
val fcall = arg.value as FunctionCallExpression val fcall = arg.value as FunctionCallExpression
if(fcall.target.nameInSource == listOf("lsb") || fcall.target.nameInSource == listOf("msb") || fcall.target.nameInSource == listOf("bankof")) val name = fcall.target.nameInSource
if(name==listOf("lsb") || name==listOf("msb") || name==listOf("bankof") || name==listOf("msw") || name==listOf("lsw"))
ident = fcall.args[0] as? IdentifierReference ident = fcall.args[0] as? IdentifierReference
} }
if(ident!=null && ident.nameInSource[0] == "cx16" && ident.nameInSource[1].startsWith("r")) { if(ident!=null && ident.nameInSource[0] == "cx16" && ident.nameInSource[1].startsWith("r")) {

View File

@ -118,7 +118,7 @@ private fun integrateDefers(subdefers: Map<PtSub, List<PtDefer>>, program: PtPro
is PtAddressOf -> value.arrayIndexExpr == null || notComplex(value.arrayIndexExpr!!) is PtAddressOf -> value.arrayIndexExpr == null || notComplex(value.arrayIndexExpr!!)
is PtBuiltinFunctionCall -> { is PtBuiltinFunctionCall -> {
when (value.name) { when (value.name) {
in arrayOf("msb", "lsb", "bankof", "mkword", "set_carry", "set_irqd", "clear_carry", "clear_irqd") -> value.args.all { notComplex(it) } in arrayOf("msb", "lsb", "msw", "lsw", "bankof", "mkword", "set_carry", "set_irqd", "clear_carry", "clear_irqd") -> value.args.all { notComplex(it) }
else -> false else -> false
} }
} }

View File

@ -366,12 +366,27 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter,
} }
override fun after(functionCallExpr: FunctionCallExpression, parent: Node): Iterable<IAstModification> { override fun after(functionCallExpr: FunctionCallExpression, parent: Node): Iterable<IAstModification> {
if(functionCallExpr.target.nameInSource==listOf("bankof")) { val name = functionCallExpr.target.nameInSource
if(name==listOf("bankof")) {
val valueDt = functionCallExpr.args[0].inferType(program) val valueDt = functionCallExpr.args[0].inferType(program)
if(valueDt.isWords || valueDt.isBytes) { if(valueDt.isWords || valueDt.isBytes) {
val zero = NumericLiteral.optimalInteger(0, functionCallExpr.position) val zero = NumericLiteral(DataType.UBYTE, 0.0, functionCallExpr.position)
return listOf(IAstModification.ReplaceNode(functionCallExpr, zero, parent)) return listOf(IAstModification.ReplaceNode(functionCallExpr, zero, parent))
} }
} else if(name==listOf("msw")) {
val valueDt = functionCallExpr.args[0].inferType(program)
if(valueDt.isWords || valueDt.isBytes) {
val zero = NumericLiteral(DataType.UWORD, 0.0, functionCallExpr.position)
return listOf(IAstModification.ReplaceNode(functionCallExpr, zero, parent))
}
} else if(name==listOf("lsw")) {
val valueDt = functionCallExpr.args[0].inferType(program)
if(valueDt.isWords)
return listOf(IAstModification.ReplaceNode(functionCallExpr, functionCallExpr.args[0], parent))
if(valueDt.isBytes) {
val cast = TypecastExpression(functionCallExpr.args[0], DataType.UWORD, true, functionCallExpr.position)
return listOf(IAstModification.ReplaceNode(functionCallExpr, cast, parent))
}
} }
return noModifications return noModifications
} }

View File

@ -13,7 +13,6 @@ import prog8.code.target.encodings.JapaneseCharacterConverter
import java.io.CharConversionException import java.io.CharConversionException
import java.util.Objects import java.util.Objects
import kotlin.math.abs import kotlin.math.abs
import kotlin.math.exp
import kotlin.math.floor import kotlin.math.floor
import kotlin.math.truncate import kotlin.math.truncate

View File

@ -5,7 +5,8 @@ what to do with bankof(): keep it? add another syntax like \`value or ^value t
add a function like addr() or lsw() to complement bnk() in getting easy access to the lower 16 bits of a long integer? add a function like addr() or lsw() to complement bnk() in getting easy access to the lower 16 bits of a long integer?
-> added unary ^ operator as alternative to bankof() -> added unary ^ operator as alternative to bankof()
-> added unary << operator as alternative to addr() / lsb(x>>16) / lsw() -> added unary << operator as alternative to addr() / lsb(x>>16) / lsw()
-> TODO document whatever remains of those! -> added msw() and lsw() . note: msw() on a 24 bits constant can ALSO be used to get the bank byte because the value, while a word type, will be <=255
-> TODO document whatever remains of those! (and add to syntax files)
... ...

View File

@ -21,6 +21,13 @@ main {
txt.print_ubhex(bankof(foo2), true) txt.print_ubhex(bankof(foo2), true)
txt.spc() txt.spc()
txt.print_uwhex(foo2 &$ffff, false) txt.print_uwhex(foo2 &$ffff, false)
txt.nl()
txt.print_ubhex(msw(foo2), true)
txt.spc()
txt.print_uwhex(lsw(foo2), false)
txt.nl()
} }
} }