vm: add abs() and fix 6502 abs() code.

This commit is contained in:
Irmen de Jong 2022-04-18 21:20:01 +02:00
parent ee36d47c27
commit 88b55ab93e
5 changed files with 79 additions and 29 deletions

View File

@ -1144,22 +1144,21 @@ internal class BuiltinFunctionsAsmGen(private val program: Program,
val dt = fcall.args.single().inferType(program).getOr(DataType.UNDEFINED) val dt = fcall.args.single().inferType(program).getOr(DataType.UNDEFINED)
if(resultToStack) { if(resultToStack) {
when (dt) { when (dt) {
in ByteDatatypes -> asmgen.out(" jsr prog8_lib.abs_b_stack") DataType.UBYTE -> asmgen.out(" ldy #0")
in WordDatatypes -> asmgen.out(" jsr prog8_lib.abs_w_stack") DataType.BYTE -> asmgen.out(" jsr prog8_lib.abs_b_stack")
DataType.UWORD -> {}
DataType.WORD -> asmgen.out(" jsr prog8_lib.abs_w_stack")
else -> throw AssemblyError("weird type") else -> throw AssemblyError("weird type")
} }
} else { } else {
when (dt) { when (dt) {
in ByteDatatypes -> { DataType.UBYTE -> asmgen.out(" ldy #0")
asmgen.out(" jsr prog8_lib.abs_b_into_A") DataType.BYTE -> asmgen.out(" jsr prog8_lib.abs_b_into_AY")
assignAsmGen.assignRegisterByte(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, false, scope, program, asmgen), CpuRegister.A) DataType.UWORD -> {}
} DataType.WORD -> asmgen.out(" jsr prog8_lib.abs_w_into_AY")
in WordDatatypes -> {
asmgen.out(" jsr prog8_lib.abs_w_into_AY")
assignAsmGen.assignRegisterpairWord(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.AY, false, scope, program, asmgen), RegisterOrPair.AY)
}
else -> throw AssemblyError("weird type") else -> throw AssemblyError("weird type")
} }
assignAsmGen.assignRegisterpairWord(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.AY, false, scope, program, asmgen), RegisterOrPair.AY)
} }
} }

View File

@ -15,7 +15,7 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen:
return when(call.name) { return when(call.name) {
"any" -> funcAny(call, resultRegister) "any" -> funcAny(call, resultRegister)
"all" -> funcAll(call, resultRegister) "all" -> funcAll(call, resultRegister)
"abs" -> TODO("abs once we can compare plus minus") "abs" -> funcAbs(call, resultRegister)
"cmp" -> funcCmp(call) "cmp" -> funcCmp(call)
"sgn" -> funcSgn(call, resultRegister) "sgn" -> funcSgn(call, resultRegister)
"sin" -> TODO("floats not yet implemented") "sin" -> TODO("floats not yet implemented")
@ -122,6 +122,40 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen:
return code return code
} }
private fun funcAbs(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
val code = VmCodeChunk()
val sourceDt = call.args.single().type
if(sourceDt!=DataType.UWORD) {
code += exprGen.translateExpression(call.args[0], resultRegister)
when (sourceDt) {
DataType.UBYTE -> {
code += VmCodeInstruction(Opcode.EXT, VmDataType.BYTE, reg1=resultRegister)
}
DataType.BYTE -> {
val andReg = codeGen.vmRegisters.nextFree()
val notNegativeLabel = codeGen.createLabelName()
code += VmCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=andReg, value=0x80)
code += VmCodeInstruction(Opcode.AND, VmDataType.BYTE, reg1=andReg, reg2=resultRegister, reg3=andReg)
code += VmCodeInstruction(Opcode.BZ, VmDataType.BYTE, reg1=andReg, symbol = notNegativeLabel)
code += VmCodeInstruction(Opcode.NEG, VmDataType.BYTE, reg1=resultRegister)
code += VmCodeInstruction(Opcode.EXT, VmDataType.BYTE, reg1=resultRegister)
code += VmCodeLabel(notNegativeLabel)
}
DataType.WORD -> {
val andReg = codeGen.vmRegisters.nextFree()
val notNegativeLabel = codeGen.createLabelName()
code += VmCodeInstruction(Opcode.LOAD, VmDataType.WORD, reg1=andReg, value=0x8000)
code += VmCodeInstruction(Opcode.AND, VmDataType.WORD, reg1=andReg, reg2=resultRegister, reg3=andReg)
code += VmCodeInstruction(Opcode.BZ, VmDataType.WORD, reg1=andReg, symbol = notNegativeLabel)
code += VmCodeInstruction(Opcode.NEG, VmDataType.WORD, reg1=resultRegister)
code += VmCodeLabel(notNegativeLabel)
}
else -> throw AssemblyError("weird type")
}
}
return code
}
private fun funcSgn(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk { private fun funcSgn(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
val code = VmCodeChunk() val code = VmCodeChunk()
code += exprGen.translateExpression(call.args.single(), 0) code += exprGen.translateExpression(call.args.single(), 0)

View File

@ -85,15 +85,17 @@ func_all_w_stack .proc
.pend .pend
abs_b_stack .proc abs_b_stack .proc
; -- push abs(A) on stack (as byte) ; -- push abs(A) on stack (as unsigned word)
jsr abs_b_into_A jsr abs_b_into_A
sta P8ESTACK_LO,x sta P8ESTACK_LO,x
stz p8ESTACK_HI,x
dex dex
rts rts
.pend .pend
abs_b_into_A .proc abs_b_into_AY .proc
; -- A = abs(A) ; -- AY = abs(A) (abs always returns unsigned word)
ldy #0
cmp #0 cmp #0
bmi + bmi +
rts rts

View File

@ -3,7 +3,6 @@ TODO
For next release For next release
^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^
- vm: add abs().
- pipe operator: allow non-unary function calls in the pipe that specify the other argument(s) in the calls. - pipe operator: allow non-unary function calls in the pipe that specify the other argument(s) in the calls.
- createAssemblyAndAssemble(): make it possible to actually get rid of the VarDecl nodes by fixing the rest of the code mentioned there. - createAssemblyAndAssemble(): make it possible to actually get rid of the VarDecl nodes by fixing the rest of the code mentioned there.
- allow "xxx" * constexpr (where constexpr is not a number literal), now gives expression error not same type - allow "xxx" * constexpr (where constexpr is not a number literal), now gives expression error not same type

View File

@ -7,24 +7,40 @@
main { main {
sub start() { sub start() {
ubyte ub = 234
byte v1 = -10 byte v1 = -10
byte v2 = 20 byte v2 = 20
uword w3
cmp(v1,v2) byte v3 = abs(v1) as byte
;sys.clear_carry() txt.print_b(v3)
if_cc txt.spc()
txt.print("cc\n") v3 = abs(v2) as byte
if_cs txt.print_b(v3)
txt.print("cs\n") txt.spc()
w3 = abs(v1)
txt.print_uw(w3)
txt.spc()
w3 = abs(v2)
txt.print_uw(w3)
txt.spc()
w3 = abs(ub)
txt.print_uw(w3)
txt.nl()
; uword ww = 100 txt.print_uw(abs(v1))
; uword vv txt.spc()
; vv = ww+1 txt.print_uw(abs(v2))
; txt.print_uw(vv) txt.spc()
; txt.nl() txt.print_uw(abs(ub))
; vv = ww * 8 txt.nl()
; txt.print_uw(vv)
; txt.nl() word sw1 = -12345
w3 = abs(sw1)
txt.print_uw(w3)
txt.spc()
txt.print_uw(abs(sw1))
txt.nl()
; ; a "pixelshader": ; ; a "pixelshader":
; void syscall1(8, 0) ; enable lo res creen ; void syscall1(8, 0) ; enable lo res creen