From 66a836d094cb29c02608783d54c737327ba4d232 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Tue, 16 Jan 2024 00:24:51 +0100 Subject: [PATCH] added support for reverse() on split word arrays --- .../codegen/cpu6502/BuiltinFunctionsAsmGen.kt | 19 ++- .../codegen/intermediate/BuiltinFuncGen.kt | 31 +++-- compiler/res/prog8lib/virtual/syslib.p8 | 24 ++++ docs/source/todo.rst | 2 - examples/test.p8 | 110 ++++++++++-------- 5 files changed, 124 insertions(+), 62 deletions(-) diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt index 51083d61f..75b406783 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt @@ -355,7 +355,22 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram, lda #$numElements jsr floats.func_reverse_f""") } - in SplitWordArrayTypes -> TODO("split word reverse") + in SplitWordArrayTypes -> { + // reverse the lsb and msb arrays both, independently + asmgen.out(""" + lda #<${varName}_lsb + ldy #>${varName}_lsb + sta P8ZP_SCRATCH_W1 + sty P8ZP_SCRATCH_W1+1 + lda #$numElements + jsr prog8_lib.func_reverse_b + lda #<${varName}_msb + ldy #>${varName}_msb + sta P8ZP_SCRATCH_W1 + sty P8ZP_SCRATCH_W1+1 + lda #$numElements + jsr prog8_lib.func_reverse_b""") + } else -> throw AssemblyError("weird type") } } @@ -398,7 +413,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram, jsr prog8_lib.func_sort_ub""") } DataType.ARRAY_F -> throw AssemblyError("sorting of floating point array is not supported") - in SplitWordArrayTypes -> TODO("split word sort") + in SplitWordArrayTypes -> TODO("split words sort") else -> throw AssemblyError("weird type") } } diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/BuiltinFuncGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/BuiltinFuncGen.kt index 3b205fdab..f55b6b767 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/BuiltinFuncGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/BuiltinFuncGen.kt @@ -149,10 +149,10 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe val arrayName = call.args[0] as PtIdentifier val arrayLength = codeGen.symbolTable.getLength(arrayName.name) val result = mutableListOf() + val lengthReg = codeGen.registers.nextFree() if(arrayName.type in SplitWordArrayTypes) { // any(lsb-array) or any(msb-array) - val lengthReg = codeGen.registers.nextFree() addInstr(result, IRInstruction(Opcode.PREPARECALL, immediate = 2), null) val trLsb = exprGen.translateExpression(PtIdentifier(arrayName.name+"_lsb", DataType.ARRAY_UB, call.position)) addToResult(result, trLsb, trLsb.resultReg, -1) @@ -183,9 +183,8 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe else -> throw IllegalArgumentException("weird type") } addInstr(result, IRInstruction(Opcode.PREPARECALL, immediate = 2), null) - val tr = exprGen.translateExpression(call.args[0]) + val tr = exprGen.translateExpression(arrayName) addToResult(result, tr, tr.resultReg, -1) - val lengthReg = codeGen.registers.nextFree() addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = lengthReg, immediate = arrayLength), null) result += codeGen.makeSyscall(syscall, listOf(IRDataType.WORD to tr.resultReg, IRDataType.BYTE to lengthReg), IRDataType.BYTE to tr.resultReg) return ExpressionCodeResult(result, IRDataType.BYTE, tr.resultReg, -1) @@ -211,7 +210,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe } val result = mutableListOf() addInstr(result, IRInstruction(Opcode.PREPARECALL, immediate = 2), null) - val tr = exprGen.translateExpression(call.args[0]) + val tr = exprGen.translateExpression(arrayName) addToResult(result, tr, tr.resultReg, -1) val lengthReg = codeGen.registers.nextFree() addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = lengthReg, immediate = arrayLength), null) @@ -307,19 +306,33 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe private fun funcReverse(call: PtBuiltinFunctionCall): ExpressionCodeResult { val arrayName = call.args[0] as PtIdentifier val arrayLength = codeGen.symbolTable.getLength(arrayName.name) + val lengthReg = codeGen.registers.nextFree() + val result = mutableListOf() + + if(arrayName.type in SplitWordArrayTypes) { + // reverse the lsb and msb arrays both, independently + addInstr(result, IRInstruction(Opcode.PREPARECALL, immediate = 2), null) + val trLsb = exprGen.translateExpression(PtIdentifier(arrayName.name+"_lsb", DataType.ARRAY_UB, call.position)) + addToResult(result, trLsb, trLsb.resultReg, -1) + addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = lengthReg, immediate = if(arrayName.type==DataType.STR) arrayLength!!-1 else arrayLength), null) + result += codeGen.makeSyscall(IMSyscall.REVERSE_BYTES, listOf(IRDataType.WORD to trLsb.resultReg, IRDataType.BYTE to lengthReg), null) + val trMsb = exprGen.translateExpression(PtIdentifier(arrayName.name+"_msb", DataType.ARRAY_UB, call.position)) + addToResult(result, trMsb, trMsb.resultReg, -1) + addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = lengthReg, immediate = if(arrayName.type==DataType.STR) arrayLength!!-1 else arrayLength), null) + result += codeGen.makeSyscall(IMSyscall.REVERSE_BYTES, listOf(IRDataType.WORD to trMsb.resultReg, IRDataType.BYTE to lengthReg), null) + return ExpressionCodeResult(result, IRDataType.BYTE, -1, -1) + } + val syscall = when(arrayName.type) { DataType.ARRAY_UB, DataType.ARRAY_B, DataType.STR -> IMSyscall.REVERSE_BYTES DataType.ARRAY_UW, DataType.ARRAY_W -> IMSyscall.REVERSE_WORDS DataType.ARRAY_F -> IMSyscall.REVERSE_FLOATS - in SplitWordArrayTypes -> TODO("split word reverse") else -> throw IllegalArgumentException("weird type to reverse") } - val result = mutableListOf() addInstr(result, IRInstruction(Opcode.PREPARECALL, immediate = 2), null) - val tr = exprGen.translateExpression(call.args[0]) + val tr = exprGen.translateExpression(arrayName) addToResult(result, tr, tr.resultReg, -1) - val lengthReg = codeGen.registers.nextFree() addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = lengthReg, immediate = if(arrayName.type==DataType.STR) arrayLength!!-1 else arrayLength), null) result += codeGen.makeSyscall(syscall, listOf(IRDataType.WORD to tr.resultReg, IRDataType.BYTE to lengthReg), null) return ExpressionCodeResult(result, IRDataType.BYTE, -1, -1) @@ -341,7 +354,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe } val result = mutableListOf() addInstr(result, IRInstruction(Opcode.PREPARECALL, immediate = 2), null) - val tr = exprGen.translateExpression(call.args[0]) + val tr = exprGen.translateExpression(arrayName) addToResult(result, tr, tr.resultReg, -1) val lengthReg = codeGen.registers.nextFree() addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = lengthReg, immediate = if(arrayName.type==DataType.STR) arrayLength!!-1 else arrayLength), null) diff --git a/compiler/res/prog8lib/virtual/syslib.p8 b/compiler/res/prog8lib/virtual/syslib.p8 index 17df1b6ab..c197042d2 100644 --- a/compiler/res/prog8lib/virtual/syslib.p8 +++ b/compiler/res/prog8lib/virtual/syslib.p8 @@ -160,6 +160,30 @@ sys { returnr.w r65535 }} } + + sub read_flags() -> ubyte { + ; "simulate" the 6502 status register a little bit + if_neg { + if_z + cx16.r0L = %10000010 + else + cx16.r0L = %10000000 + } + else { + if_z + cx16.r0L = %00000010 + else + cx16.r0L = %00000000 + } + + if_cs + cx16.r0L |= 1 +; TODO: overflow flag not yet supported +; if_vs +; cx16.r0L |= %01000000 + + return cx16.r0L + } } cx16 { diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 38025f756..7f8e58873 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,8 +3,6 @@ TODO funcRor()/funcRol(): save carry flag before calculating array index otherwise it gets clobbered -- split words arrays reverse() - Mark had a compiler crash FatalAstException: invalid dt ... diff --git a/examples/test.p8 b/examples/test.p8 index 875f53900..3d2dbf037 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -59,61 +59,73 @@ main { uword[] @split swaone = [$0000, $3300, $0000] uword[] @split swazero = [$0000, $0000, $0000] -; txt.print_ub(all(wa)) ; 1 + reverse(wa) + for cx16.r9 in wa { + txt.print_uwhex(cx16.r9, true) + txt.nl() + } + txt.nl() + reverse(swa) + for cx16.r9 in swa { + txt.print_uwhex(cx16.r9, true) + txt.nl() + } + + txt.print_ub(all(wa)) ; 1 + txt.spc() + txt.print_ub(any(wa)) ; 1 + txt.nl() + txt.print_ub(all(waone)) ; 0 + txt.spc() + txt.print_ub(any(waone)) ; 1 + txt.nl() +; txt.print_ub(all(swaone)) ; 0 ; txt.spc() -; txt.print_ub(any(wa)) ; 1 -; txt.nl() -; txt.print_ub(all(waone)) ; 0 -; txt.spc() -; txt.print_ub(any(waone)) ; 1 -; txt.nl() -;; txt.print_ub(all(swaone)) ; 0 -;; txt.spc() txt.print_ub(any(swaone)) ; 1 txt.nl() -;; txt.print_ub(all(swa)) ; 1 -;; txt.spc() -; txt.print_ub(any(swa)) ; 1 -; txt.nl() -; txt.print_ub(all(wazero)) ; 0 +; txt.print_ub(all(swa)) ; 1 +; txt.spc() + txt.print_ub(any(swa)) ; 1 + txt.nl() + txt.print_ub(all(wazero)) ; 0 + txt.spc() + txt.print_ub(any(wazero)) ; 0 + txt.nl() +; txt.print_ub(all(swazero)) ; 0 ; txt.spc() -; txt.print_ub(any(wazero)) ; 0 -; txt.nl() -;; txt.print_ub(all(swazero)) ; 0 -;; txt.spc() txt.print_ub(any(swazero)) ; 0 txt.nl() -; txt.print_uwbin(wa[2], true) -; txt.nl() -; rol(wa[2]) -; txt.print_uwbin(wa[2], true) -; txt.nl() -; rol2(wa[2]) -; txt.print_uwbin(wa[2], true) -; txt.nl() -; ror(wa[2]) -; txt.print_uwbin(wa[2], true) -; txt.nl() -; ror2(wa[2]) -; txt.print_uwbin(wa[2], true) -; txt.nl() -; txt.nl() -; -; txt.print_uwbin(swa[2], true) -; txt.nl() -; rol(swa[2]) -; txt.print_uwbin(swa[2], true) -; txt.nl() -; rol2(swa[2]) -; txt.print_uwbin(swa[2], true) -; txt.nl() -; ror(swa[2]) -; txt.print_uwbin(swa[2], true) -; txt.nl() -; ror2(swa[2]) -; txt.print_uwbin(swa[2], true) -; txt.nl() -; txt.nl() + txt.print_uwbin(wa[2], true) + txt.nl() + rol(wa[2]) + txt.print_uwbin(wa[2], true) + txt.nl() + rol2(wa[2]) + txt.print_uwbin(wa[2], true) + txt.nl() + ror(wa[2]) + txt.print_uwbin(wa[2], true) + txt.nl() + ror2(wa[2]) + txt.print_uwbin(wa[2], true) + txt.nl() + txt.nl() + + txt.print_uwbin(swa[2], true) + txt.nl() + rol(swa[2]) + txt.print_uwbin(swa[2], true) + txt.nl() + rol2(swa[2]) + txt.print_uwbin(swa[2], true) + txt.nl() + ror(swa[2]) + txt.print_uwbin(swa[2], true) + txt.nl() + ror2(swa[2]) + txt.print_uwbin(swa[2], true) + txt.nl() + txt.nl() } }