mirror of
https://github.com/irmen/prog8.git
synced 2024-11-27 03:50:27 +00:00
made versions of various builtin funcs returning value in registers
This commit is contained in:
parent
3e28ed4fe4
commit
3efa8da8e0
@ -573,6 +573,18 @@ func_ceil .proc
|
|||||||
+ jmp push_fac1_as_result
|
+ jmp push_fac1_as_result
|
||||||
.pend
|
.pend
|
||||||
|
|
||||||
|
func_any_f_into_A .proc
|
||||||
|
jsr func_any_f
|
||||||
|
_popA inx
|
||||||
|
lda P8ESTACK_LO,x
|
||||||
|
rts
|
||||||
|
.pend
|
||||||
|
|
||||||
|
func_all_f_into_A .proc
|
||||||
|
jsr func_all_f
|
||||||
|
jmp func_any_f_into_A._popA
|
||||||
|
.pend
|
||||||
|
|
||||||
func_any_f .proc
|
func_any_f .proc
|
||||||
inx
|
inx
|
||||||
lda P8ESTACK_LO,x ; array size
|
lda P8ESTACK_LO,x ; array size
|
||||||
|
@ -702,6 +702,10 @@ func_read_flags .proc
|
|||||||
rts
|
rts
|
||||||
.pend
|
.pend
|
||||||
|
|
||||||
|
func_sqrt16_into_A .proc
|
||||||
|
jsr func_sqrt16
|
||||||
|
jmp func_any_b_into_A._popA
|
||||||
|
.pend
|
||||||
|
|
||||||
func_sqrt16 .proc
|
func_sqrt16 .proc
|
||||||
; TODO is this one faster? http://6502org.wikidot.com/software-math-sqrt
|
; TODO is this one faster? http://6502org.wikidot.com/software-math-sqrt
|
||||||
@ -754,6 +758,78 @@ _stab .byte $01,$02,$04,$08,$10,$20,$40,$80
|
|||||||
.pend
|
.pend
|
||||||
|
|
||||||
|
|
||||||
|
func_sin8_into_A .proc
|
||||||
|
inx
|
||||||
|
ldy P8ESTACK_LO,x
|
||||||
|
lda func_sin8._sinecos8,y
|
||||||
|
rts
|
||||||
|
.pend
|
||||||
|
|
||||||
|
func_sin8u_into_A .proc
|
||||||
|
inx
|
||||||
|
ldy P8ESTACK_LO,x
|
||||||
|
lda func_sin8u._sinecos8u,y
|
||||||
|
rts
|
||||||
|
.pend
|
||||||
|
|
||||||
|
func_sin16_into_AY .proc
|
||||||
|
inx
|
||||||
|
ldy P8ESTACK_LO,x
|
||||||
|
lda func_sin16._sinecos8lo,y
|
||||||
|
pha
|
||||||
|
lda func_sin16._sinecos8hi,y
|
||||||
|
tay
|
||||||
|
pla
|
||||||
|
rts
|
||||||
|
.pend
|
||||||
|
|
||||||
|
func_sin16u_into_AY .proc
|
||||||
|
inx
|
||||||
|
ldy P8ESTACK_LO,x
|
||||||
|
lda func_sin16u._sinecos8ulo,y
|
||||||
|
pha
|
||||||
|
lda func_sin16u._sinecos8uhi,y
|
||||||
|
tay
|
||||||
|
pla
|
||||||
|
rts
|
||||||
|
.pend
|
||||||
|
|
||||||
|
func_cos8_into_A .proc
|
||||||
|
inx
|
||||||
|
ldy P8ESTACK_LO,x
|
||||||
|
lda func_sin8._sinecos8+64,y
|
||||||
|
rts
|
||||||
|
.pend
|
||||||
|
|
||||||
|
func_cos8u_into_A .proc
|
||||||
|
inx
|
||||||
|
ldy P8ESTACK_LO,x
|
||||||
|
lda func_sin8u._sinecos8u+64,y
|
||||||
|
rts
|
||||||
|
.pend
|
||||||
|
|
||||||
|
func_cos16_into_AY .proc
|
||||||
|
inx
|
||||||
|
ldy P8ESTACK_LO,x
|
||||||
|
lda func_sin16._sinecos8lo+64,y
|
||||||
|
pha
|
||||||
|
lda func_sin16._sinecos8hi+64,y
|
||||||
|
tay
|
||||||
|
pla
|
||||||
|
rts
|
||||||
|
.pend
|
||||||
|
|
||||||
|
func_cos16u_into_AY .proc
|
||||||
|
inx
|
||||||
|
ldy P8ESTACK_LO,x
|
||||||
|
lda func_sin16u._sinecos8ulo+64,y
|
||||||
|
pha
|
||||||
|
lda func_sin16u._sinecos8uhi+64,y
|
||||||
|
tay
|
||||||
|
pla
|
||||||
|
rts
|
||||||
|
.pend
|
||||||
|
|
||||||
func_sin8 .proc
|
func_sin8 .proc
|
||||||
ldy P8ESTACK_LO+1,x
|
ldy P8ESTACK_LO+1,x
|
||||||
lda _sinecos8,y
|
lda _sinecos8,y
|
||||||
@ -838,6 +914,29 @@ peek_address .proc
|
|||||||
rts
|
rts
|
||||||
.pend
|
.pend
|
||||||
|
|
||||||
|
func_any_b_into_A .proc
|
||||||
|
jsr func_any_b
|
||||||
|
_popA inx
|
||||||
|
lda P8ESTACK_LO,x
|
||||||
|
rts
|
||||||
|
.pend
|
||||||
|
|
||||||
|
func_all_b_into_A .proc
|
||||||
|
jsr func_all_b
|
||||||
|
jmp func_any_b_into_A._popA
|
||||||
|
.pend
|
||||||
|
|
||||||
|
func_any_w_into_A .proc
|
||||||
|
jsr func_any_w
|
||||||
|
jmp func_any_b_into_A._popA
|
||||||
|
.pend
|
||||||
|
|
||||||
|
func_all_w_into_A .proc
|
||||||
|
jsr func_all_w
|
||||||
|
jmp func_any_b_into_A._popA
|
||||||
|
.pend
|
||||||
|
|
||||||
|
|
||||||
func_any_b .proc
|
func_any_b .proc
|
||||||
inx
|
inx
|
||||||
lda P8ESTACK_LO,x ; array size
|
lda P8ESTACK_LO,x ; array size
|
||||||
@ -1103,6 +1202,72 @@ pop_array_and_lengthmin1Y .proc
|
|||||||
rts
|
rts
|
||||||
.pend
|
.pend
|
||||||
|
|
||||||
|
func_min_ub_into_A .proc
|
||||||
|
jsr func_min_ub
|
||||||
|
_popA inx
|
||||||
|
lda P8ESTACK_LO,x
|
||||||
|
rts
|
||||||
|
.pend
|
||||||
|
|
||||||
|
func_min_b_into_A .proc
|
||||||
|
jsr func_min_b
|
||||||
|
jmp func_min_ub_into_A._popA
|
||||||
|
.pend
|
||||||
|
|
||||||
|
func_max_ub_into_A .proc
|
||||||
|
jsr func_max_ub
|
||||||
|
jmp func_min_ub_into_A._popA
|
||||||
|
.pend
|
||||||
|
|
||||||
|
func_max_b_into_A .proc
|
||||||
|
jsr func_max_b
|
||||||
|
jmp func_min_ub_into_A._popA
|
||||||
|
.pend
|
||||||
|
|
||||||
|
func_sum_ub_into_AY .proc
|
||||||
|
jsr func_sum_ub
|
||||||
|
_popAY inx
|
||||||
|
lda P8ESTACK_LO,x
|
||||||
|
ldy P8ESTACK_HI,x
|
||||||
|
rts
|
||||||
|
.pend
|
||||||
|
|
||||||
|
func_sum_b_into_AY .proc
|
||||||
|
jsr func_sum_b
|
||||||
|
jmp func_sum_ub_into_AY._popAY
|
||||||
|
.pend
|
||||||
|
|
||||||
|
func_min_uw_into_AY .proc
|
||||||
|
jsr func_min_uw
|
||||||
|
jmp func_sum_ub_into_AY._popAY
|
||||||
|
.pend
|
||||||
|
|
||||||
|
func_min_w_into_AY .proc
|
||||||
|
jsr func_min_w
|
||||||
|
jmp func_sum_ub_into_AY._popAY
|
||||||
|
.pend
|
||||||
|
|
||||||
|
func_max_uw_into_AY .proc
|
||||||
|
jsr func_max_uw
|
||||||
|
jmp func_sum_ub_into_AY._popAY
|
||||||
|
.pend
|
||||||
|
|
||||||
|
func_max_w_into_AY .proc
|
||||||
|
jsr func_max_w
|
||||||
|
jmp func_sum_ub_into_AY._popAY
|
||||||
|
.pend
|
||||||
|
|
||||||
|
func_sum_uw_into_AY .proc
|
||||||
|
jsr func_sum_uw
|
||||||
|
jmp func_sum_ub_into_AY._popAY
|
||||||
|
.pend
|
||||||
|
|
||||||
|
func_sum_w_into_AY .proc
|
||||||
|
jsr func_sum_w
|
||||||
|
jmp func_sum_ub_into_AY._popAY
|
||||||
|
.pend
|
||||||
|
|
||||||
|
|
||||||
func_min_ub .proc
|
func_min_ub .proc
|
||||||
jsr pop_array_and_lengthmin1Y
|
jsr pop_array_and_lengthmin1Y
|
||||||
lda #255
|
lda #255
|
||||||
@ -2165,5 +2330,6 @@ func_strcmp .proc
|
|||||||
lda P8ESTACK_LO+1,x
|
lda P8ESTACK_LO+1,x
|
||||||
jsr strcmp_mem
|
jsr strcmp_mem
|
||||||
sta P8ESTACK_LO+1,x
|
sta P8ESTACK_LO+1,x
|
||||||
|
; make sure A contains the result value as well
|
||||||
rts
|
rts
|
||||||
.pend
|
.pend
|
||||||
|
@ -263,7 +263,6 @@ private class AsmSubroutineParameter(name: String,
|
|||||||
type: DataType,
|
type: DataType,
|
||||||
val registerOrPair: RegisterOrPair?,
|
val registerOrPair: RegisterOrPair?,
|
||||||
val statusflag: Statusflag?,
|
val statusflag: Statusflag?,
|
||||||
// TODO implement: val stack: Boolean,
|
|
||||||
position: Position) : SubroutineParameter(name, type, position)
|
position: Position) : SubroutineParameter(name, type, position)
|
||||||
|
|
||||||
private class AsmSubroutineReturn(val type: DataType,
|
private class AsmSubroutineReturn(val type: DataType,
|
||||||
|
@ -44,7 +44,7 @@ class BuiltinFunctionStatementPlaceholder(val name: String, override val positio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class RegisterOrStatusflag(val registerOrPair: RegisterOrPair?, val statusflag: Statusflag?, val stack: Boolean)
|
data class RegisterOrStatusflag(val registerOrPair: RegisterOrPair?, val statusflag: Statusflag?, val stack: Boolean) // TODO get rid of stack?
|
||||||
|
|
||||||
class Block(override val name: String,
|
class Block(override val name: String,
|
||||||
val address: Int?,
|
val address: Int?,
|
||||||
|
@ -550,22 +550,19 @@ internal class AsmGen(private val program: Program,
|
|||||||
|
|
||||||
private fun fixNameSymbols(name: String) = name.replace("<", "prog8_").replace(">", "") // take care of the autogenerated invalid (anon) label names
|
private fun fixNameSymbols(name: String) = name.replace("<", "prog8_").replace(">", "") // take care of the autogenerated invalid (anon) label names
|
||||||
|
|
||||||
internal fun saveRegister(register: CpuRegister, dontUseStack: Boolean, scope: Subroutine?) {
|
internal fun saveRegister(register: CpuRegister, dontUseStack: Boolean, scope: Subroutine) {
|
||||||
if(dontUseStack) {
|
if(dontUseStack) {
|
||||||
when (register) {
|
when (register) {
|
||||||
CpuRegister.A -> {
|
CpuRegister.A -> {
|
||||||
out(" sta _prog8_regsaveA")
|
out(" sta _prog8_regsaveA")
|
||||||
if (scope != null)
|
|
||||||
scope.asmGenInfo.usedRegsaveA = true
|
scope.asmGenInfo.usedRegsaveA = true
|
||||||
}
|
}
|
||||||
CpuRegister.X -> {
|
CpuRegister.X -> {
|
||||||
out(" stx _prog8_regsaveX")
|
out(" stx _prog8_regsaveX")
|
||||||
if (scope != null)
|
|
||||||
scope.asmGenInfo.usedRegsaveX = true
|
scope.asmGenInfo.usedRegsaveX = true
|
||||||
}
|
}
|
||||||
CpuRegister.Y -> {
|
CpuRegister.Y -> {
|
||||||
out(" sty _prog8_regsaveY")
|
out(" sty _prog8_regsaveY")
|
||||||
if (scope != null)
|
|
||||||
scope.asmGenInfo.usedRegsaveY = true
|
scope.asmGenInfo.usedRegsaveY = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -577,7 +574,6 @@ internal class AsmGen(private val program: Program,
|
|||||||
if (CompilationTarget.instance.machine.cpu == CpuType.CPU65c02) out(" phx")
|
if (CompilationTarget.instance.machine.cpu == CpuType.CPU65c02) out(" phx")
|
||||||
else {
|
else {
|
||||||
out(" stx _prog8_regsaveX")
|
out(" stx _prog8_regsaveX")
|
||||||
if (scope != null)
|
|
||||||
scope.asmGenInfo.usedRegsaveX = true
|
scope.asmGenInfo.usedRegsaveX = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -585,7 +581,6 @@ internal class AsmGen(private val program: Program,
|
|||||||
if (CompilationTarget.instance.machine.cpu == CpuType.CPU65c02) out(" phy")
|
if (CompilationTarget.instance.machine.cpu == CpuType.CPU65c02) out(" phy")
|
||||||
else {
|
else {
|
||||||
out(" sty _prog8_regsaveY")
|
out(" sty _prog8_regsaveY")
|
||||||
if (scope != null)
|
|
||||||
scope.asmGenInfo.usedRegsaveY = true
|
scope.asmGenInfo.usedRegsaveY = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,18 +36,21 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
when (functionName) {
|
when (functionName) {
|
||||||
"msb" -> funcMsb(fcall, resultToStack)
|
"msb" -> funcMsb(fcall, resultToStack)
|
||||||
"lsb" -> funcLsb(fcall, resultToStack)
|
"lsb" -> funcLsb(fcall, resultToStack)
|
||||||
// TODO THE OTHERS
|
"mkword" -> funcMkword(fcall, resultToStack)
|
||||||
// "mkword" -> funcMkword(fcall, func) // TODO resultToStack
|
|
||||||
"abs" -> funcAbs(fcall, func, resultToStack)
|
"abs" -> funcAbs(fcall, func, resultToStack)
|
||||||
"swap" -> funcSwap(fcall)
|
"swap" -> funcSwap(fcall)
|
||||||
// "strlen" -> funcStrlen(fcall) // TODO resultToStack
|
"min", "max" -> funcMinMax(fcall, functionName, resultToStack)
|
||||||
// "min", "max", "sum" -> funcMinMaxSum(fcall, functionName) // TODO resultToStack
|
"sum" -> funcSum(fcall, resultToStack)
|
||||||
// "any", "all" -> funcAnyAll(fcall, functionName) // TODO resultToStack
|
"any", "all" -> funcAnyAll(fcall, functionName, resultToStack)
|
||||||
|
"sin8", "sin8u", "sin16", "sin16u",
|
||||||
|
"cos8", "cos8u", "cos16", "cos16u" -> funcSinCosInt(fcall, func, functionName, resultToStack)
|
||||||
"sgn" -> funcSgn(fcall, func, resultToStack)
|
"sgn" -> funcSgn(fcall, func, resultToStack)
|
||||||
"sin", "cos", "tan", "atan",
|
"sin", "cos", "tan", "atan",
|
||||||
"ln", "log2", "sqrt", "rad",
|
"ln", "log2", "sqrt", "rad",
|
||||||
"deg", "round", "floor", "ceil",
|
"deg", "round", "floor", "ceil",
|
||||||
// "rdnf" -> funcVariousFloatFuncs(fcall, func, functionName) // TODO resultToStack
|
"rdnf" -> funcVariousFloatFuncs(fcall, func, functionName, resultToStack)
|
||||||
|
"rnd", "rndw" -> funcRnd(functionName, resultToStack)
|
||||||
|
"sqrt16" -> funcSqrt16(fcall, func, resultToStack)
|
||||||
"rol" -> funcRol(fcall)
|
"rol" -> funcRol(fcall)
|
||||||
"rol2" -> funcRol2(fcall)
|
"rol2" -> funcRol2(fcall)
|
||||||
"ror" -> funcRor(fcall)
|
"ror" -> funcRor(fcall)
|
||||||
@ -63,19 +66,52 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
// restore all registers and cpu status flag
|
// restore all registers and cpu status flag
|
||||||
asmgen.out(" pla | tay | pla | tax | pla | plp")
|
asmgen.out(" pla | tay | pla | tax | pla | plp")
|
||||||
}
|
}
|
||||||
|
"read_flags" -> {
|
||||||
|
if(resultToStack)
|
||||||
|
asmgen.out(" jsr prog8_lib.func_read_flags")
|
||||||
|
else
|
||||||
|
asmgen.out(" php | pla")
|
||||||
|
}
|
||||||
"clear_carry" -> asmgen.out(" clc")
|
"clear_carry" -> asmgen.out(" clc")
|
||||||
"set_carry" -> asmgen.out(" sec")
|
"set_carry" -> asmgen.out(" sec")
|
||||||
"clear_irqd" -> asmgen.out(" cli")
|
"clear_irqd" -> asmgen.out(" cli")
|
||||||
"set_irqd" -> asmgen.out(" sei")
|
"set_irqd" -> asmgen.out(" sei")
|
||||||
else -> {
|
"strlen" -> funcStrlen(fcall, resultToStack)
|
||||||
|
"strcmp" -> funcStrcmp(fcall, func, resultToStack)
|
||||||
|
"substr", "leftstr", "rightstr",
|
||||||
|
"memcopy", "memset", "memsetw" -> {
|
||||||
translateArguments(fcall.args, func)
|
translateArguments(fcall.args, func)
|
||||||
if(resultToStack) {
|
|
||||||
asmgen.out(" jsr prog8_lib.func_$functionName")
|
asmgen.out(" jsr prog8_lib.func_$functionName")
|
||||||
} else {
|
}
|
||||||
TODO("builtin function $fcall")
|
"exit" -> asmgen.out(" jmp prog8_lib.func_exit")
|
||||||
// TODO call function that puts result in registers, not on stack
|
else -> TODO("missing asmgen for builtin func $functionName")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun funcStrcmp(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean) {
|
||||||
|
translateArguments(fcall.args, func)
|
||||||
|
if(resultToStack)
|
||||||
|
asmgen.out(" jsr prog8_lib.func_strcmp")
|
||||||
|
else
|
||||||
|
asmgen.out(" jsr prog8_lib.func_strcmp | inx") // result is also in register A
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun funcSqrt16(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean) {
|
||||||
|
translateArguments(fcall.args, func)
|
||||||
|
if(resultToStack)
|
||||||
|
asmgen.out(" jsr prog8_lib.func_sqrt16")
|
||||||
|
else
|
||||||
|
asmgen.out(" jsr prog8_lib.func_sqrt16_into_A")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun funcSinCosInt(fcall: IFunctionCall, func: FSignature, functionName: String, resultToStack: Boolean) {
|
||||||
|
translateArguments(fcall.args, func)
|
||||||
|
if(resultToStack)
|
||||||
|
asmgen.out(" jsr prog8_lib.func_$functionName")
|
||||||
|
else
|
||||||
|
when(functionName) {
|
||||||
|
"sin8", "sin8u", "cos8", "cos8u" -> asmgen.out(" jsr prog8_lib.func_${functionName}_into_A")
|
||||||
|
"sin16", "sin16u", "cos16", "cos16u" -> asmgen.out(" jsr prog8_lib.func_${functionName}_into_AY")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -351,9 +387,13 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun funcVariousFloatFuncs(fcall: IFunctionCall, func: FSignature, functionName: String) {
|
private fun funcVariousFloatFuncs(fcall: IFunctionCall, func: FSignature, functionName: String, resultToStack: Boolean) {
|
||||||
translateArguments(fcall.args, func)
|
translateArguments(fcall.args, func)
|
||||||
|
if(resultToStack) {
|
||||||
asmgen.out(" jsr floats.func_$functionName")
|
asmgen.out(" jsr floats.func_$functionName")
|
||||||
|
} else {
|
||||||
|
TODO("float func result via registers $functionName")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun funcSgn(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean) {
|
private fun funcSgn(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean) {
|
||||||
@ -380,20 +420,30 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun funcAnyAll(fcall: IFunctionCall, functionName: String) {
|
private fun funcAnyAll(fcall: IFunctionCall, functionName: String, resultToStack: Boolean) {
|
||||||
outputPushAddressAndLenghtOfArray(fcall.args[0])
|
outputPushAddressAndLenghtOfArray(fcall.args[0])
|
||||||
val dt = fcall.args.single().inferType(program)
|
val dt = fcall.args.single().inferType(program)
|
||||||
|
if(resultToStack) {
|
||||||
when (dt.typeOrElse(DataType.STRUCT)) {
|
when (dt.typeOrElse(DataType.STRUCT)) {
|
||||||
DataType.ARRAY_B, DataType.ARRAY_UB, DataType.STR -> asmgen.out(" jsr prog8_lib.func_${functionName}_b")
|
DataType.ARRAY_B, DataType.ARRAY_UB, DataType.STR -> asmgen.out(" jsr prog8_lib.func_${functionName}_b")
|
||||||
DataType.ARRAY_UW, DataType.ARRAY_W -> asmgen.out(" jsr prog8_lib.func_${functionName}_w")
|
DataType.ARRAY_UW, DataType.ARRAY_W -> asmgen.out(" jsr prog8_lib.func_${functionName}_w")
|
||||||
DataType.ARRAY_F -> asmgen.out(" jsr floats.func_${functionName}_f")
|
DataType.ARRAY_F -> asmgen.out(" jsr floats.func_${functionName}_f")
|
||||||
else -> throw AssemblyError("weird type $dt")
|
else -> throw AssemblyError("weird type $dt")
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
when (dt.typeOrElse(DataType.STRUCT)) {
|
||||||
|
DataType.ARRAY_B, DataType.ARRAY_UB, DataType.STR -> asmgen.out(" jsr prog8_lib.func_${functionName}_b_into_A")
|
||||||
|
DataType.ARRAY_UW, DataType.ARRAY_W -> asmgen.out(" jsr prog8_lib.func_${functionName}_w_into_A")
|
||||||
|
DataType.ARRAY_F -> asmgen.out(" jsr floats.func_${functionName}_f_into_A")
|
||||||
|
else -> throw AssemblyError("weird type $dt")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun funcMinMaxSum(fcall: IFunctionCall, functionName: String) {
|
private fun funcMinMax(fcall: IFunctionCall, functionName: String, resultToStack: Boolean) {
|
||||||
outputPushAddressAndLenghtOfArray(fcall.args[0])
|
outputPushAddressAndLenghtOfArray(fcall.args[0])
|
||||||
val dt = fcall.args.single().inferType(program)
|
val dt = fcall.args.single().inferType(program)
|
||||||
|
if(resultToStack) {
|
||||||
when (dt.typeOrElse(DataType.STRUCT)) {
|
when (dt.typeOrElse(DataType.STRUCT)) {
|
||||||
DataType.ARRAY_UB, DataType.STR -> asmgen.out(" jsr prog8_lib.func_${functionName}_ub")
|
DataType.ARRAY_UB, DataType.STR -> asmgen.out(" jsr prog8_lib.func_${functionName}_ub")
|
||||||
DataType.ARRAY_B -> asmgen.out(" jsr prog8_lib.func_${functionName}_b")
|
DataType.ARRAY_B -> asmgen.out(" jsr prog8_lib.func_${functionName}_b")
|
||||||
@ -402,24 +452,56 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
DataType.ARRAY_F -> asmgen.out(" jsr floats.func_${functionName}_f")
|
DataType.ARRAY_F -> asmgen.out(" jsr floats.func_${functionName}_f")
|
||||||
else -> throw AssemblyError("weird type $dt")
|
else -> throw AssemblyError("weird type $dt")
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
when (dt.typeOrElse(DataType.STRUCT)) {
|
||||||
|
DataType.ARRAY_UB, DataType.STR -> asmgen.out(" jsr prog8_lib.func_${functionName}_ub_into_A")
|
||||||
|
DataType.ARRAY_B -> asmgen.out(" jsr prog8_lib.func_${functionName}_b_into_A")
|
||||||
|
DataType.ARRAY_UW -> asmgen.out(" jsr prog8_lib.func_${functionName}_uw_into_AY")
|
||||||
|
DataType.ARRAY_W -> asmgen.out(" jsr prog8_lib.func_${functionName}_w_into_AY")
|
||||||
|
DataType.ARRAY_F -> TODO("min/max of floats result in float via registers")
|
||||||
|
else -> throw AssemblyError("weird type $dt")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun funcStrlen(fcall: IFunctionCall) {
|
private fun funcSum(fcall: IFunctionCall, resultToStack: Boolean) {
|
||||||
|
outputPushAddressAndLenghtOfArray(fcall.args[0])
|
||||||
|
val dt = fcall.args.single().inferType(program)
|
||||||
|
if(resultToStack) {
|
||||||
|
when (dt.typeOrElse(DataType.STRUCT)) {
|
||||||
|
DataType.ARRAY_UB, DataType.STR -> asmgen.out(" jsr prog8_lib.func_sum_ub")
|
||||||
|
DataType.ARRAY_B -> asmgen.out(" jsr prog8_lib.func_sum_b")
|
||||||
|
DataType.ARRAY_UW -> asmgen.out(" jsr prog8_lib.func_sum_uw")
|
||||||
|
DataType.ARRAY_W -> asmgen.out(" jsr prog8_lib.func_sum_w")
|
||||||
|
DataType.ARRAY_F -> asmgen.out(" jsr floats.func_sum_f")
|
||||||
|
else -> throw AssemblyError("weird type $dt")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
when (dt.typeOrElse(DataType.STRUCT)) {
|
||||||
|
DataType.ARRAY_UB, DataType.STR -> asmgen.out(" jsr prog8_lib.func_sum_ub_into_AY")
|
||||||
|
DataType.ARRAY_B -> asmgen.out(" jsr prog8_lib.func_sum_b_into_AY")
|
||||||
|
DataType.ARRAY_UW -> asmgen.out(" jsr prog8_lib.func_sum_uw_into_AY")
|
||||||
|
DataType.ARRAY_W -> asmgen.out(" jsr prog8_lib.func_sum_w_into_AY")
|
||||||
|
DataType.ARRAY_F -> TODO("sum of floats result in float via registers")
|
||||||
|
else -> throw AssemblyError("weird type $dt")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun funcStrlen(fcall: IFunctionCall, resultToStack: Boolean) {
|
||||||
val name = asmgen.asmVariableName(fcall.args[0] as IdentifierReference)
|
val name = asmgen.asmVariableName(fcall.args[0] as IdentifierReference)
|
||||||
val type = fcall.args[0].inferType(program)
|
val type = fcall.args[0].inferType(program)
|
||||||
when {
|
when {
|
||||||
type.istype(DataType.STR) -> asmgen.out("""
|
type.istype(DataType.STR) -> {
|
||||||
lda #<$name
|
asmgen.out(" lda #<$name | ldy #>$name | jsr prog8_lib.strlen")
|
||||||
ldy #>$name
|
if(resultToStack)
|
||||||
jsr prog8_lib.strlen
|
asmgen.out(" sta P8ESTACK_LO,x | dex")
|
||||||
sta P8ESTACK_LO,x
|
}
|
||||||
dex""")
|
type.istype(DataType.UWORD) -> {
|
||||||
type.istype(DataType.UWORD) -> asmgen.out("""
|
asmgen.out(" lda $name | ldy $name+1 | jsr prog8_lib.strlen")
|
||||||
lda $name
|
if(resultToStack)
|
||||||
ldy $name+1
|
asmgen.out(" sta P8ESTACK_LO,x | dex")
|
||||||
jsr prog8_lib.strlen
|
}
|
||||||
sta P8ESTACK_LO,x
|
|
||||||
dex""")
|
|
||||||
else -> throw AssemblyError("strlen requires str or uword arg")
|
else -> throw AssemblyError("strlen requires str or uword arg")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -795,11 +877,37 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun funcMkword(fcall: IFunctionCall, func: FSignature) {
|
private fun funcRnd(functionName: String, resultToStack: Boolean) {
|
||||||
// trick: push the args in reverse order (msb first, lsb second) this saves some instructions
|
when(functionName) {
|
||||||
|
"rnd" -> {
|
||||||
|
if(resultToStack)
|
||||||
|
asmgen.out(" jsr prog8_lib.func_rnd")
|
||||||
|
else
|
||||||
|
asmgen.out(" jsr math.randbyte")
|
||||||
|
}
|
||||||
|
"rndw" -> {
|
||||||
|
if(resultToStack)
|
||||||
|
asmgen.out(" jsr prog8_lib.func_rndw")
|
||||||
|
else
|
||||||
|
asmgen.out(" jsr math.randword")
|
||||||
|
}
|
||||||
|
else -> throw AssemblyError("wrong func")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun funcMkword(fcall: IFunctionCall, resultToStack: Boolean) {
|
||||||
|
if(resultToStack) {
|
||||||
|
// trick: push the args in reverse order (lsb first, msb second) this saves some instructions
|
||||||
asmgen.translateExpression(fcall.args[1])
|
asmgen.translateExpression(fcall.args[1])
|
||||||
asmgen.translateExpression(fcall.args[0])
|
asmgen.translateExpression(fcall.args[0])
|
||||||
asmgen.out(" inx | lda P8ESTACK_LO,x | sta P8ESTACK_HI+1,x")
|
asmgen.out(" inx | lda P8ESTACK_LO,x | sta P8ESTACK_HI+1,x")
|
||||||
|
} else {
|
||||||
|
// TODO some args without stack usage...
|
||||||
|
// trick: push the args in reverse order (lsb first, msb second) this saves some instructions
|
||||||
|
asmgen.translateExpression(fcall.args[1])
|
||||||
|
asmgen.translateExpression(fcall.args[0])
|
||||||
|
asmgen.out(" inx | ldy P8ESTACK_LO,x | inx | lda P8ESTACK_LO,x")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun funcMsb(fcall: IFunctionCall, resultToStack: Boolean) {
|
private fun funcMsb(fcall: IFunctionCall, resultToStack: Boolean) {
|
||||||
@ -814,9 +922,11 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
if(resultToStack)
|
if(resultToStack)
|
||||||
asmgen.out(" sta P8ESTACK_LO,x | dex")
|
asmgen.out(" sta P8ESTACK_LO,x | dex")
|
||||||
} else {
|
} else {
|
||||||
TODO("msb from non-identifier expression $arg")
|
asmgen.translateExpression(arg) // TODO this evalutes onto stack, use registers instead
|
||||||
// asmgen.translateExpression(arg)
|
if(resultToStack)
|
||||||
// asmgen.out(" lda P8ESTACK_HI+1,x | sta P8ESTACK_LO+1,x")
|
asmgen.out(" lda P8ESTACK_HI+1,x | sta P8ESTACK_LO+1,x")
|
||||||
|
else
|
||||||
|
asmgen.out(" inx | lda P8ESTACK_HI,x")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -832,9 +942,13 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
if(resultToStack)
|
if(resultToStack)
|
||||||
asmgen.out(" sta P8ESTACK_LO,x | dex")
|
asmgen.out(" sta P8ESTACK_LO,x | dex")
|
||||||
} else {
|
} else {
|
||||||
TODO("lsb from non-identifier expression $arg")
|
// TODO this evalutes onto stack, use registers instead
|
||||||
// asmgen.translateExpression(arg)
|
asmgen.translateExpression(arg)
|
||||||
// just ignore any high-byte
|
if(resultToStack) {
|
||||||
|
// simply ignore the high-byte of what's on the stack now
|
||||||
|
} else {
|
||||||
|
asmgen.out(" inx | lda P8ESTACK_LO,x")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1687,7 +1687,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun translateCompareStrings(operator: String) {
|
private fun translateCompareStrings(operator: String) {
|
||||||
asmgen.out(" jsr prog8_lib.func_strcmp | lda P8ESTACK_LO+1,x") // result of compare in A
|
asmgen.out(" jsr prog8_lib.func_strcmp") // result of compare is on stack but also in A
|
||||||
when(operator) {
|
when(operator) {
|
||||||
"==" -> asmgen.out(" and #1 | eor #1 | sta P8ESTACK_LO+1,x")
|
"==" -> asmgen.out(" and #1 | eor #1 | sta P8ESTACK_LO+1,x")
|
||||||
"!=" -> asmgen.out(" and #1 | sta P8ESTACK_LO+1,x")
|
"!=" -> asmgen.out(" and #1 | sta P8ESTACK_LO+1,x")
|
||||||
|
@ -37,7 +37,7 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
|
|||||||
val sub = stmt.target.targetSubroutine(program.namespace) ?: throw AssemblyError("undefined subroutine ${stmt.target}")
|
val sub = stmt.target.targetSubroutine(program.namespace) ?: throw AssemblyError("undefined subroutine ${stmt.target}")
|
||||||
val saveX = CpuRegister.X in sub.asmClobbers || sub.regXasResult() || sub.regXasParam()
|
val saveX = CpuRegister.X in sub.asmClobbers || sub.regXasResult() || sub.regXasParam()
|
||||||
if(saveX)
|
if(saveX)
|
||||||
asmgen.saveRegister(CpuRegister.X, preserveStatusRegisterAfterCall, (stmt as Node).definingSubroutine())
|
asmgen.saveRegister(CpuRegister.X, preserveStatusRegisterAfterCall, (stmt as Node).definingSubroutine()!!)
|
||||||
|
|
||||||
val subName = asmgen.asmSymbolName(stmt.target)
|
val subName = asmgen.asmSymbolName(stmt.target)
|
||||||
if(stmt.args.isNotEmpty()) {
|
if(stmt.args.isNotEmpty()) {
|
||||||
|
@ -97,7 +97,7 @@ internal class PostIncrDecrAsmGen(private val program: Program, private val asmg
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
asmgen.loadScaledArrayIndexIntoRegister(targetArrayIdx, elementDt, CpuRegister.A)
|
asmgen.loadScaledArrayIndexIntoRegister(targetArrayIdx, elementDt, CpuRegister.A)
|
||||||
asmgen.saveRegister(CpuRegister.X, false, scope)
|
asmgen.saveRegister(CpuRegister.X, false, scope!!)
|
||||||
asmgen.out(" tax")
|
asmgen.out(" tax")
|
||||||
when(elementDt) {
|
when(elementDt) {
|
||||||
in ByteDatatypes -> {
|
in ByteDatatypes -> {
|
||||||
|
@ -130,6 +130,9 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
is Subroutine -> {
|
is Subroutine -> {
|
||||||
val preserveStatusRegisterAfterCall = sub.asmReturnvaluesRegisters.any { it.statusflag != null }
|
val preserveStatusRegisterAfterCall = sub.asmReturnvaluesRegisters.any { it.statusflag != null }
|
||||||
asmgen.translateFunctionCall(value, preserveStatusRegisterAfterCall)
|
asmgen.translateFunctionCall(value, preserveStatusRegisterAfterCall)
|
||||||
|
if(sub.returntypes.single()==DataType.STR) {
|
||||||
|
TODO("assignment of string => copy string ${assign.position}")
|
||||||
|
} else {
|
||||||
when ((sub.asmReturnvaluesRegisters.single { it.registerOrPair != null }).registerOrPair) {
|
when ((sub.asmReturnvaluesRegisters.single { it.registerOrPair != null }).registerOrPair) {
|
||||||
RegisterOrPair.A -> assignRegisterByte(assign.target, CpuRegister.A)
|
RegisterOrPair.A -> assignRegisterByte(assign.target, CpuRegister.A)
|
||||||
RegisterOrPair.X -> assignRegisterByte(assign.target, CpuRegister.X)
|
RegisterOrPair.X -> assignRegisterByte(assign.target, CpuRegister.X)
|
||||||
@ -139,6 +142,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
RegisterOrPair.XY -> assignRegisterpairWord(assign.target, RegisterOrPair.XY)
|
RegisterOrPair.XY -> assignRegisterpairWord(assign.target, RegisterOrPair.XY)
|
||||||
else -> throw AssemblyError("should be just one register byte result value")
|
else -> throw AssemblyError("should be just one register byte result value")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (preserveStatusRegisterAfterCall)
|
if (preserveStatusRegisterAfterCall)
|
||||||
asmgen.out(" plp\t; restore status flags from call")
|
asmgen.out(" plp\t; restore status flags from call")
|
||||||
}
|
}
|
||||||
@ -151,6 +155,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
when(returntype.typeOrElse(DataType.STRUCT)) {
|
when(returntype.typeOrElse(DataType.STRUCT)) {
|
||||||
in ByteDatatypes -> assignRegisterByte(assign.target, CpuRegister.A) // function's byte result is in A
|
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
|
in WordDatatypes -> assignRegisterpairWord(assign.target, RegisterOrPair.AY) // function's word result is in AY
|
||||||
|
DataType.STR -> TODO("assign string => copy string")
|
||||||
DataType.FLOAT -> TODO("assign float result from ${sub.name}")
|
DataType.FLOAT -> TODO("assign float result from ${sub.name}")
|
||||||
else -> throw AssemblyError("weird result type")
|
else -> throw AssemblyError("weird result type")
|
||||||
}
|
}
|
||||||
@ -775,10 +780,12 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun assignRegisterpairWord(target: AsmAssignTarget, regs: RegisterOrPair) {
|
private fun assignRegisterpairWord(target: AsmAssignTarget, regs: RegisterOrPair) {
|
||||||
require(target.datatype in NumericDatatypes)
|
require(target.datatype in NumericDatatypes) {
|
||||||
|
"zzz"
|
||||||
|
}
|
||||||
if(target.datatype==DataType.FLOAT) {
|
if(target.datatype==DataType.FLOAT) {
|
||||||
if (regs == RegisterOrPair.AY) {
|
if (regs == RegisterOrPair.AY) {
|
||||||
asmgen.out(" brk ; TODO FLOAT RETURN VALUE") // TODO
|
asmgen.out(" brk ; TODO FLOAT RETURN VALUE") // TODO float value via registers
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
else throw AssemblyError("float reaturn value should be via AY return pointer")
|
else throw AssemblyError("float reaturn value should be via AY return pointer")
|
||||||
@ -793,7 +800,20 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
TargetStorageKind.ARRAY -> {
|
TargetStorageKind.ARRAY -> {
|
||||||
TODO("store register pair $regs into word-array ${target.array}")
|
// TODO can be a bit more optimized if the array indexer is a number
|
||||||
|
when(regs) {
|
||||||
|
RegisterOrPair.AX -> asmgen.out(" pha | txa | pha")
|
||||||
|
RegisterOrPair.AY -> asmgen.out(" pha | tya | pha")
|
||||||
|
RegisterOrPair.XY -> asmgen.out(" txa | pha | tya | pha")
|
||||||
|
else -> throw AssemblyError("expected reg pair")
|
||||||
|
}
|
||||||
|
asmgen.loadScaledArrayIndexIntoRegister(target.array!!, DataType.UWORD, CpuRegister.Y, true)
|
||||||
|
asmgen.out("""
|
||||||
|
pla
|
||||||
|
sta ${target.asmVarname},y
|
||||||
|
dey
|
||||||
|
pla
|
||||||
|
sta ${target.asmVarname},y""")
|
||||||
}
|
}
|
||||||
TargetStorageKind.REGISTER -> {
|
TargetStorageKind.REGISTER -> {
|
||||||
when(regs) {
|
when(regs) {
|
||||||
@ -1190,7 +1210,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
asmgen.storeByteIntoPointer(addressExpr, null)
|
asmgen.storeByteIntoPointer(addressExpr, null)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
asmgen.saveRegister(register, false, memoryAddress.definingSubroutine())
|
asmgen.saveRegister(register, false, memoryAddress.definingSubroutine()!!)
|
||||||
asmgen.translateExpression(addressExpr)
|
asmgen.translateExpression(addressExpr)
|
||||||
asmgen.restoreRegister(CpuRegister.A, false)
|
asmgen.restoreRegister(CpuRegister.A, false)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
|
@ -136,13 +136,13 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
}
|
}
|
||||||
DataType.FLOAT -> {
|
DataType.FLOAT -> {
|
||||||
when {
|
when {
|
||||||
valueLv != null -> inplaceModification_float_litval_to_variable(target.asmVarname, operator, valueLv.toDouble(), target.scope)
|
valueLv != null -> inplaceModification_float_litval_to_variable(target.asmVarname, operator, valueLv.toDouble(), target.scope!!)
|
||||||
ident != null -> inplaceModification_float_variable_to_variable(target.asmVarname, operator, ident, target.scope)
|
ident != null -> inplaceModification_float_variable_to_variable(target.asmVarname, operator, ident, target.scope!!)
|
||||||
value is TypecastExpression -> {
|
value is TypecastExpression -> {
|
||||||
if (tryRemoveRedundantCast(value, target, operator)) return
|
if (tryRemoveRedundantCast(value, target, operator)) return
|
||||||
inplaceModification_float_value_to_variable(target.asmVarname, operator, value, target.scope)
|
inplaceModification_float_value_to_variable(target.asmVarname, operator, value, target.scope!!)
|
||||||
}
|
}
|
||||||
else -> inplaceModification_float_value_to_variable(target.asmVarname, operator, value, target.scope)
|
else -> inplaceModification_float_value_to_variable(target.asmVarname, operator, value, target.scope!!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> throw AssemblyError("weird type to do in-place modification on ${target.datatype}")
|
else -> throw AssemblyError("weird type to do in-place modification on ${target.datatype}")
|
||||||
@ -1295,7 +1295,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
asmgen.out(" inx")
|
asmgen.out(" inx")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun inplaceModification_float_value_to_variable(name: String, operator: String, value: Expression, scope: Subroutine?) {
|
private fun inplaceModification_float_value_to_variable(name: String, operator: String, value: Expression, scope: Subroutine) {
|
||||||
// this should be the last resort for code generation for this,
|
// this should be the last resort for code generation for this,
|
||||||
// because the value is evaluated onto the eval stack (=slow).
|
// because the value is evaluated onto the eval stack (=slow).
|
||||||
if(asmgen.options.slowCodegenWarnings)
|
if(asmgen.options.slowCodegenWarnings)
|
||||||
@ -1350,7 +1350,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
asmgen.restoreRegister(CpuRegister.X, false)
|
asmgen.restoreRegister(CpuRegister.X, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun inplaceModification_float_variable_to_variable(name: String, operator: String, ident: IdentifierReference, scope: Subroutine?) {
|
private fun inplaceModification_float_variable_to_variable(name: String, operator: String, ident: IdentifierReference, scope: Subroutine) {
|
||||||
val valueDt = ident.targetVarDecl(program.namespace)!!.datatype
|
val valueDt = ident.targetVarDecl(program.namespace)!!.datatype
|
||||||
if(valueDt != DataType.FLOAT)
|
if(valueDt != DataType.FLOAT)
|
||||||
throw AssemblyError("float variable expected")
|
throw AssemblyError("float variable expected")
|
||||||
@ -1419,7 +1419,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
asmgen.restoreRegister(CpuRegister.X, false)
|
asmgen.restoreRegister(CpuRegister.X, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun inplaceModification_float_litval_to_variable(name: String, operator: String, value: Double, scope: Subroutine?) {
|
private fun inplaceModification_float_litval_to_variable(name: String, operator: String, value: Double, scope: Subroutine) {
|
||||||
val constValueName = asmgen.getFloatAsmConst(value)
|
val constValueName = asmgen.getFloatAsmConst(value)
|
||||||
asmgen.saveRegister(CpuRegister.X, false, scope)
|
asmgen.saveRegister(CpuRegister.X, false, scope)
|
||||||
when (operator) {
|
when (operator) {
|
||||||
|
@ -617,8 +617,7 @@ internal class ExpressionSimplifier(private val program: Program) : AstWalker()
|
|||||||
if (amount >= 16) {
|
if (amount >= 16) {
|
||||||
return NumericLiteralValue(targetDt, 0, expr.position)
|
return NumericLiteralValue(targetDt, 0, expr.position)
|
||||||
} else if (amount >= 8) {
|
} else if (amount >= 8) {
|
||||||
// TODO is this correct???
|
val lsb = FunctionCall(IdentifierReference(listOf("lsb"), expr.position), mutableListOf(expr.left), expr.position)
|
||||||
val lsb = TypecastExpression(expr.left, DataType.UBYTE, true, expr.position)
|
|
||||||
if (amount == 8) {
|
if (amount == 8) {
|
||||||
return FunctionCall(IdentifierReference(listOf("mkword"), expr.position), mutableListOf(lsb, NumericLiteralValue.optimalInteger(0, expr.position)), expr.position)
|
return FunctionCall(IdentifierReference(listOf("mkword"), expr.position), mutableListOf(lsb, NumericLiteralValue.optimalInteger(0, expr.position)), expr.position)
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ TODO
|
|||||||
- make memset(w) and memcopy able to work with >256 bytes
|
- make memset(w) and memcopy able to work with >256 bytes
|
||||||
- make memset and memcopy use the ROM routines on the CX16
|
- make memset and memcopy use the ROM routines on the CX16
|
||||||
- calling convention for builtin functions no longer via stack but via statically allocated vars inside the subroutine proc (just as normal subroutines)
|
- calling convention for builtin functions no longer via stack but via statically allocated vars inside the subroutine proc (just as normal subroutines)
|
||||||
- get rid of @stack in asmsub altogether (because all subroutines are no longer using this calling convention anymore)
|
- get rid of @stack in asmsub (syntax, ast) altogether (because all subroutines are no longer using this calling convention anymore)
|
||||||
- make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as '_'
|
- make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as '_'
|
||||||
- option to load the built-in library files from a directory instead of the embedded ones (for easier library development/debugging)
|
- option to load the built-in library files from a directory instead of the embedded ones (for easier library development/debugging)
|
||||||
- see if we can group some errors together for instance the (now single) errors about unidentified symbols
|
- see if we can group some errors together for instance the (now single) errors about unidentified symbols
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
; Converted to prog8 by Irmen de Jong.
|
; Converted to prog8 by Irmen de Jong.
|
||||||
|
|
||||||
|
|
||||||
|
; TODO why is the output of this larger with the register-eval stuff than before with the stack eval stuff?
|
||||||
|
|
||||||
main {
|
main {
|
||||||
const uword SCREEN1 = $E000
|
const uword SCREEN1 = $E000
|
||||||
const uword SCREEN2 = $E400
|
const uword SCREEN2 = $E400
|
||||||
|
@ -11,50 +11,37 @@
|
|||||||
|
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
byte bb
|
|
||||||
word ww
|
|
||||||
|
|
||||||
bb = 0
|
uword ss
|
||||||
bb = sgn(bb)
|
|
||||||
txt.print_b(bb)
|
ss = %1000000110101010
|
||||||
txt.chrout('\n')
|
ss <<= 8
|
||||||
bb = 127
|
txt.print_uwbin(ss, 1)
|
||||||
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')
|
txt.chrout('\n')
|
||||||
|
|
||||||
ww = 0
|
ss = %1000000110101111
|
||||||
ww = sgn(ww)
|
ss <<= 9
|
||||||
txt.print_w(ww)
|
txt.print_uwbin(ss, 1)
|
||||||
txt.chrout('\n')
|
txt.chrout('\n')
|
||||||
ww = 32767
|
|
||||||
ww = sgn(ww)
|
ss = %1000000110101111
|
||||||
txt.print_w(ww)
|
ss <<= 14
|
||||||
|
txt.print_uwbin(ss, 1)
|
||||||
txt.chrout('\n')
|
txt.chrout('\n')
|
||||||
ww = -1
|
|
||||||
ww = sgn(ww)
|
ss = %1000000110101111
|
||||||
txt.print_w(ww)
|
ss <<= 15
|
||||||
|
txt.print_uwbin(ss, 1)
|
||||||
txt.chrout('\n')
|
txt.chrout('\n')
|
||||||
ww = -32767
|
|
||||||
ww = sgn(ww)
|
ss = %1000000110101111
|
||||||
txt.print_w(ww)
|
ss <<= 16
|
||||||
|
txt.print_uwbin(ss, 1)
|
||||||
txt.chrout('\n')
|
txt.chrout('\n')
|
||||||
ww = -32768
|
|
||||||
ww = sgn(ww)
|
ss = %1000000110101010
|
||||||
txt.print_w(ww)
|
ss <<= 17
|
||||||
|
txt.print_uwbin(ss, 1)
|
||||||
txt.chrout('\n')
|
txt.chrout('\n')
|
||||||
|
|
||||||
main22.testX()
|
main22.testX()
|
||||||
@ -87,7 +74,7 @@ main22 {
|
|||||||
txt.chrout('\n')
|
txt.chrout('\n')
|
||||||
|
|
||||||
void getstr()
|
void getstr()
|
||||||
ssss = getstr()
|
; TODO string assign ssss = getstr()
|
||||||
|
|
||||||
txt.print_uwhex(ssss, true)
|
txt.print_uwhex(ssss, true)
|
||||||
txt.chrout('\n')
|
txt.chrout('\n')
|
||||||
|
Loading…
Reference in New Issue
Block a user