mirror of
https://github.com/irmen/prog8.git
synced 2025-02-25 20:29:04 +00:00
vm: add abs() and fix 6502 abs() code.
This commit is contained in:
parent
ee36d47c27
commit
88b55ab93e
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user