mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
mader versions of abs() and sgn() returning value in register
This commit is contained in:
parent
44949460ed
commit
3e28ed4fe4
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 -> {
|
||||
|
@ -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)
|
||||
|
@ -4,8 +4,6 @@
|
||||
|
||||
; Note: this program is compatible with C64 and CX16.
|
||||
|
||||
; TODO the LINES are all wrong...
|
||||
|
||||
main {
|
||||
|
||||
sub start() {
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user