mader versions of abs() and sgn() returning value in register

This commit is contained in:
Irmen de Jong 2020-10-28 22:56:13 +01:00
parent 44949460ed
commit 3e28ed4fe4
8 changed files with 196 additions and 40 deletions

View File

@ -1282,6 +1282,44 @@ _sign_possibly_zero lda P8ESTACK_LO+1,x
.pend
sign_b_into_A .proc
; -- A = sgn(pop stack byte)
inx
lda P8ESTACK_LO,x
beq _sign_zero
bmi _sign_neg
_sign_pos lda #1
rts
_sign_neg lda #-1
_sign_zero rts
.pend
sign_ub_into_A .proc
; -- A = sgn(pop stack ubyte)
lda P8ESTACK_LO+1,x
bne sign_b._sign_pos
rts
.pend
sign_w_into_A .proc
; -- A = sgn(pop stack word)
lda P8ESTACK_HI+1,x
bmi sign_b._sign_neg
bne sign_b._sign_pos
rts
.pend
sign_uw_into_A .proc
; -- A = sgn(pop stack uword)
lda P8ESTACK_HI+1,x
beq _sign_possibly_zero
_sign_pos lda #1
rts
_sign_possibly_zero lda P8ESTACK_LO+1,x
bne _sign_pos
rts
.pend
; bit shifts.
; anything below 3 is done inline. anything above 7 is done via other optimizations.

View File

@ -259,6 +259,38 @@ abs_w .proc
rts
.pend
abs_b_into_A .proc
; -- A = abs(pop stack byte)
inx
lda P8ESTACK_LO,x
bmi +
rts
+ eor #$ff
clc
adc #1
rts
.pend
abs_w_into_AY .proc
; -- AY = abs(pop stack word)
inx
lda P8ESTACK_LO,x
ldy P8ESTACK_HI,x
bmi +
rts
+ eor #$ff
pha
tya
eor #$ff
tay
pla
clc
adc #1
bcc +
iny
+ rts
.pend
add_w .proc
; -- push word+word / uword+uword
inx

View File

@ -821,7 +821,7 @@ class FunctionCall(override var target: IdentifierReference,
val exprfunc = func.constExpressionFunc
if(exprfunc!=null)
resultValue = exprfunc(args, position, program)
else if(func.returntype==null)
else if(func.known_returntype==null)
throw ExpressionError("builtin function ${target.nameInSource[0]} can't be used here because it doesn't return a value", position)
}

View File

@ -36,17 +36,18 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
when (functionName) {
"msb" -> funcMsb(fcall, resultToStack)
"lsb" -> funcLsb(fcall, resultToStack)
"mkword" -> funcMkword(fcall, func) // TODO resultToStack
"abs" -> funcAbs(fcall, func) // TODO resultToStack
// TODO THE OTHERS
// "mkword" -> funcMkword(fcall, func) // TODO resultToStack
"abs" -> funcAbs(fcall, func, resultToStack)
"swap" -> funcSwap(fcall)
"strlen" -> funcStrlen(fcall) // TODO resultToStack
"min", "max", "sum" -> funcMinMaxSum(fcall, functionName) // TODO resultToStack
"any", "all" -> funcAnyAll(fcall, functionName) // TODO resultToStack
"sgn" -> funcSgn(fcall, func) // TODO resultToStack
// "strlen" -> funcStrlen(fcall) // TODO resultToStack
// "min", "max", "sum" -> funcMinMaxSum(fcall, functionName) // TODO resultToStack
// "any", "all" -> funcAnyAll(fcall, functionName) // TODO resultToStack
"sgn" -> funcSgn(fcall, func, resultToStack)
"sin", "cos", "tan", "atan",
"ln", "log2", "sqrt", "rad",
"deg", "round", "floor", "ceil",
"rdnf" -> funcVariousFloatFuncs(fcall, func, functionName) // TODO resultToStack
// "rdnf" -> funcVariousFloatFuncs(fcall, func, functionName) // TODO resultToStack
"rol" -> funcRol(fcall)
"rol2" -> funcRol2(fcall)
"ror" -> funcRor(fcall)
@ -67,8 +68,13 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
"clear_irqd" -> asmgen.out(" cli")
"set_irqd" -> asmgen.out(" sei")
else -> {
translateFunctionArguments(fcall.args, func)
asmgen.out(" jsr prog8_lib.func_$functionName") // TODO resultToStack
translateArguments(fcall.args, func)
if(resultToStack) {
asmgen.out(" jsr prog8_lib.func_$functionName")
} else {
TODO("builtin function $fcall")
// TODO call function that puts result in registers, not on stack
}
}
}
}
@ -346,20 +352,31 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
}
private fun funcVariousFloatFuncs(fcall: IFunctionCall, func: FSignature, functionName: String) {
translateFunctionArguments(fcall.args, func)
translateArguments(fcall.args, func)
asmgen.out(" jsr floats.func_$functionName")
}
private fun funcSgn(fcall: IFunctionCall, func: FSignature) {
translateFunctionArguments(fcall.args, func)
private fun funcSgn(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean) {
translateArguments(fcall.args, func)
val dt = fcall.args.single().inferType(program)
when (dt.typeOrElse(DataType.STRUCT)) {
DataType.UBYTE -> asmgen.out(" jsr math.sign_ub")
DataType.BYTE -> asmgen.out(" jsr math.sign_b")
DataType.UWORD -> asmgen.out(" jsr math.sign_uw")
DataType.WORD -> asmgen.out(" jsr math.sign_w")
DataType.FLOAT -> asmgen.out(" jsr floats.sign_f")
else -> throw AssemblyError("weird type $dt")
if(resultToStack) {
when (dt.typeOrElse(DataType.STRUCT)) {
DataType.UBYTE -> asmgen.out(" jsr math.sign_ub")
DataType.BYTE -> asmgen.out(" jsr math.sign_b")
DataType.UWORD -> asmgen.out(" jsr math.sign_uw")
DataType.WORD -> asmgen.out(" jsr math.sign_w")
DataType.FLOAT -> asmgen.out(" jsr floats.sign_f")
else -> throw AssemblyError("weird type $dt")
}
} else {
when (dt.typeOrElse(DataType.STRUCT)) {
DataType.UBYTE -> asmgen.out(" jsr math.sign_ub_into_A")
DataType.BYTE -> asmgen.out(" jsr math.sign_b_into_A")
DataType.UWORD -> asmgen.out(" jsr math.sign_uw_into_A")
DataType.WORD -> asmgen.out(" jsr math.sign_w_into_A")
DataType.FLOAT -> TODO("sign float using registers")
else -> throw AssemblyError("weird type $dt")
}
}
}
@ -758,14 +775,23 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
}
}
private fun funcAbs(fcall: IFunctionCall, func: FSignature) {
translateFunctionArguments(fcall.args, func)
private fun funcAbs(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean) {
translateArguments(fcall.args, func)
val dt = fcall.args.single().inferType(program)
when (dt.typeOrElse(DataType.STRUCT)) {
in ByteDatatypes -> asmgen.out(" jsr prog8_lib.abs_b")
in WordDatatypes -> asmgen.out(" jsr prog8_lib.abs_w")
DataType.FLOAT -> asmgen.out(" jsr floats.abs_f")
else -> throw AssemblyError("weird type")
if(resultToStack) {
when (dt.typeOrElse(DataType.STRUCT)) {
in ByteDatatypes -> asmgen.out(" jsr prog8_lib.abs_b")
in WordDatatypes -> asmgen.out(" jsr prog8_lib.abs_w")
DataType.FLOAT -> asmgen.out(" jsr floats.abs_f")
else -> throw AssemblyError("weird type")
}
} else {
when (dt.typeOrElse(DataType.STRUCT)) {
in ByteDatatypes -> asmgen.out(" jsr prog8_lib.abs_b_into_A")
in WordDatatypes -> asmgen.out(" jsr prog8_lib.abs_w_into_AY")
DataType.FLOAT -> TODO("abs(float) via registers")
else -> throw AssemblyError("weird type")
}
}
}
@ -828,9 +854,9 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
""")
}
private fun translateFunctionArguments(args: MutableList<Expression>, signature: FSignature) {
private fun translateArguments(args: MutableList<Expression>, signature: FSignature) {
args.forEach {
asmgen.translateExpression(it)
asmgen.translateExpression(it) // TODO if possible, function args via registers
}
}

View File

@ -11,6 +11,7 @@ import prog8.compiler.target.c64.codegen.AsmGen
import prog8.compiler.target.c64.codegen.ExpressionsAsmGen
import prog8.compiler.toHex
import prog8.functions.BuiltinFunctions
import prog8.functions.builtinFunctionReturnType
internal class AssignmentAsmGen(private val program: Program, private val asmgen: AsmGen, private val exprAsmgen: ExpressionsAsmGen) {
@ -144,12 +145,14 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
is BuiltinFunctionStatementPlaceholder -> {
val signature = BuiltinFunctions.getValue(sub.name)
asmgen.translateBuiltinFunctionCallExpression(value, signature, false)
when(signature.returntype) {
in ByteDatatypes -> assignRegisterByte(assign.target, CpuRegister.A)
in WordDatatypes -> assignRegisterpairWord(assign.target, RegisterOrPair.AY)
val returntype = builtinFunctionReturnType(sub.name, value.args, program)
if(returntype.isUnknown)
throw AssemblyError("weird result type")
when(returntype.typeOrElse(DataType.STRUCT)) {
in ByteDatatypes -> assignRegisterByte(assign.target, CpuRegister.A) // function's byte result is in A
in WordDatatypes -> assignRegisterpairWord(assign.target, RegisterOrPair.AY) // function's word result is in AY
DataType.FLOAT -> TODO("assign float result from ${sub.name}")
null -> {}
else -> throw AssemblyError("weird result type ${signature.returntype}")
else -> throw AssemblyError("weird result type")
}
}
else -> {

View File

@ -17,7 +17,7 @@ typealias ConstExpressionCaller = (args: List<Expression>, position: Position, p
class FSignature(val pure: Boolean, // does it have side effects?
val parameters: List<FParam>,
val returntype: DataType?,
val known_returntype: DataType?, // specify return type if fixed, otherwise null if it depends on the arguments
val constExpressionFunc: ConstExpressionCaller? = null)
@ -144,10 +144,10 @@ fun builtinFunctionReturnType(function: String, args: List<Expression>, program:
}
val func = BuiltinFunctions.getValue(function)
if(func.returntype!=null)
return InferredTypes.knownFor(func.returntype)
// function has return values, but the return type depends on the arguments
if(func.known_returntype!=null)
return InferredTypes.knownFor(func.known_returntype)
// function has return values, but the return type depends on the arguments
return when (function) {
"abs" -> {
val dt = args.single().inferType(program)

View File

@ -4,8 +4,6 @@
; Note: this program is compatible with C64 and CX16.
; TODO the LINES are all wrong...
main {
sub start() {

View File

@ -1,9 +1,67 @@
%import textio
%import floats
%import syslib
%option enable_floats ; TODO remove this option, only import floats is requires
%zeropage basicsafe
; Note: this program is compatible with C64 and CX16.
; TODO fix abs() and the other builtin funcs
main {
sub start() {
byte bb
word ww
bb = 0
bb = sgn(bb)
txt.print_b(bb)
txt.chrout('\n')
bb = 127
bb = sgn(bb)
txt.print_b(bb)
txt.chrout('\n')
bb = -1
bb = sgn(bb)
txt.print_b(bb)
txt.chrout('\n')
bb = -127
bb = sgn(bb)
txt.print_b(bb)
txt.chrout('\n')
bb = -128
bb = sgn(bb)
txt.print_b(bb)
txt.chrout('\n')
txt.chrout('\n')
ww = 0
ww = sgn(ww)
txt.print_w(ww)
txt.chrout('\n')
ww = 32767
ww = sgn(ww)
txt.print_w(ww)
txt.chrout('\n')
ww = -1
ww = sgn(ww)
txt.print_w(ww)
txt.chrout('\n')
ww = -32767
ww = sgn(ww)
txt.print_w(ww)
txt.chrout('\n')
ww = -32768
ww = sgn(ww)
txt.print_w(ww)
txt.chrout('\n')
main22.testX()
}
}
main22 {
sub start() {
ubyte char
@ -13,6 +71,7 @@ main {
;char = 1+(lsb(ssss) * 2)
;fl = 2.0*(abs(fl) + 1.0)
char = abs(char)
char = lsb(ssss)
char++
char = msb(ssss)