added support for reverse() on split word arrays

This commit is contained in:
Irmen de Jong 2024-01-16 00:24:51 +01:00
parent 80095f4962
commit 66a836d094
5 changed files with 124 additions and 62 deletions

View File

@ -355,7 +355,22 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
lda #$numElements lda #$numElements
jsr floats.func_reverse_f""") 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") else -> throw AssemblyError("weird type")
} }
} }
@ -398,7 +413,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
jsr prog8_lib.func_sort_ub""") jsr prog8_lib.func_sort_ub""")
} }
DataType.ARRAY_F -> throw AssemblyError("sorting of floating point array is not supported") 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") else -> throw AssemblyError("weird type")
} }
} }

View File

@ -149,10 +149,10 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
val arrayName = call.args[0] as PtIdentifier val arrayName = call.args[0] as PtIdentifier
val arrayLength = codeGen.symbolTable.getLength(arrayName.name) val arrayLength = codeGen.symbolTable.getLength(arrayName.name)
val result = mutableListOf<IRCodeChunkBase>() val result = mutableListOf<IRCodeChunkBase>()
val lengthReg = codeGen.registers.nextFree()
if(arrayName.type in SplitWordArrayTypes) { if(arrayName.type in SplitWordArrayTypes) {
// any(lsb-array) or any(msb-array) // any(lsb-array) or any(msb-array)
val lengthReg = codeGen.registers.nextFree()
addInstr(result, IRInstruction(Opcode.PREPARECALL, immediate = 2), null) addInstr(result, IRInstruction(Opcode.PREPARECALL, immediate = 2), null)
val trLsb = exprGen.translateExpression(PtIdentifier(arrayName.name+"_lsb", DataType.ARRAY_UB, call.position)) val trLsb = exprGen.translateExpression(PtIdentifier(arrayName.name+"_lsb", DataType.ARRAY_UB, call.position))
addToResult(result, trLsb, trLsb.resultReg, -1) 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") else -> throw IllegalArgumentException("weird type")
} }
addInstr(result, IRInstruction(Opcode.PREPARECALL, immediate = 2), null) 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) addToResult(result, tr, tr.resultReg, -1)
val lengthReg = codeGen.registers.nextFree()
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = lengthReg, immediate = arrayLength), null) 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) 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) 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<IRCodeChunkBase>() val result = mutableListOf<IRCodeChunkBase>()
addInstr(result, IRInstruction(Opcode.PREPARECALL, immediate = 2), null) 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) addToResult(result, tr, tr.resultReg, -1)
val lengthReg = codeGen.registers.nextFree() val lengthReg = codeGen.registers.nextFree()
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = lengthReg, immediate = arrayLength), null) 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 { private fun funcReverse(call: PtBuiltinFunctionCall): ExpressionCodeResult {
val arrayName = call.args[0] as PtIdentifier val arrayName = call.args[0] as PtIdentifier
val arrayLength = codeGen.symbolTable.getLength(arrayName.name) val arrayLength = codeGen.symbolTable.getLength(arrayName.name)
val lengthReg = codeGen.registers.nextFree()
val result = mutableListOf<IRCodeChunkBase>()
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 = val syscall =
when(arrayName.type) { when(arrayName.type) {
DataType.ARRAY_UB, DataType.ARRAY_B, DataType.STR -> IMSyscall.REVERSE_BYTES DataType.ARRAY_UB, DataType.ARRAY_B, DataType.STR -> IMSyscall.REVERSE_BYTES
DataType.ARRAY_UW, DataType.ARRAY_W -> IMSyscall.REVERSE_WORDS DataType.ARRAY_UW, DataType.ARRAY_W -> IMSyscall.REVERSE_WORDS
DataType.ARRAY_F -> IMSyscall.REVERSE_FLOATS DataType.ARRAY_F -> IMSyscall.REVERSE_FLOATS
in SplitWordArrayTypes -> TODO("split word reverse")
else -> throw IllegalArgumentException("weird type to reverse") else -> throw IllegalArgumentException("weird type to reverse")
} }
val result = mutableListOf<IRCodeChunkBase>()
addInstr(result, IRInstruction(Opcode.PREPARECALL, immediate = 2), null) 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) 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) 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) result += codeGen.makeSyscall(syscall, listOf(IRDataType.WORD to tr.resultReg, IRDataType.BYTE to lengthReg), null)
return ExpressionCodeResult(result, IRDataType.BYTE, -1, -1) return ExpressionCodeResult(result, IRDataType.BYTE, -1, -1)
@ -341,7 +354,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
} }
val result = mutableListOf<IRCodeChunkBase>() val result = mutableListOf<IRCodeChunkBase>()
addInstr(result, IRInstruction(Opcode.PREPARECALL, immediate = 2), null) 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) addToResult(result, tr, tr.resultReg, -1)
val lengthReg = codeGen.registers.nextFree() 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) addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = lengthReg, immediate = if(arrayName.type==DataType.STR) arrayLength!!-1 else arrayLength), null)

View File

@ -160,6 +160,30 @@ sys {
returnr.w r65535 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 { cx16 {

View File

@ -3,8 +3,6 @@ TODO
funcRor()/funcRol(): save carry flag before calculating array index otherwise it gets clobbered 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 Mark had a compiler crash FatalAstException: invalid dt
... ...

View File

@ -59,61 +59,73 @@ main {
uword[] @split swaone = [$0000, $3300, $0000] uword[] @split swaone = [$0000, $3300, $0000]
uword[] @split swazero = [$0000, $0000, $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.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.print_ub(any(swaone)) ; 1
txt.nl() txt.nl()
;; txt.print_ub(all(swa)) ; 1 ; txt.print_ub(all(swa)) ; 1
;; txt.spc() ; txt.spc()
; txt.print_ub(any(swa)) ; 1 txt.print_ub(any(swa)) ; 1
; txt.nl() txt.nl()
; txt.print_ub(all(wazero)) ; 0 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.spc()
; txt.print_ub(any(wazero)) ; 0
; txt.nl()
;; txt.print_ub(all(swazero)) ; 0
;; txt.spc()
txt.print_ub(any(swazero)) ; 0 txt.print_ub(any(swazero)) ; 0
txt.nl() txt.nl()
; txt.print_uwbin(wa[2], true) txt.print_uwbin(wa[2], true)
; txt.nl() txt.nl()
; rol(wa[2]) rol(wa[2])
; txt.print_uwbin(wa[2], true) txt.print_uwbin(wa[2], true)
; txt.nl() txt.nl()
; rol2(wa[2]) rol2(wa[2])
; txt.print_uwbin(wa[2], true) txt.print_uwbin(wa[2], true)
; txt.nl() txt.nl()
; ror(wa[2]) ror(wa[2])
; txt.print_uwbin(wa[2], true) txt.print_uwbin(wa[2], true)
; txt.nl() txt.nl()
; ror2(wa[2]) ror2(wa[2])
; txt.print_uwbin(wa[2], true) txt.print_uwbin(wa[2], true)
; txt.nl() txt.nl()
; txt.nl() txt.nl()
;
; txt.print_uwbin(swa[2], true) txt.print_uwbin(swa[2], true)
; txt.nl() txt.nl()
; rol(swa[2]) rol(swa[2])
; txt.print_uwbin(swa[2], true) txt.print_uwbin(swa[2], true)
; txt.nl() txt.nl()
; rol2(swa[2]) rol2(swa[2])
; txt.print_uwbin(swa[2], true) txt.print_uwbin(swa[2], true)
; txt.nl() txt.nl()
; ror(swa[2]) ror(swa[2])
; txt.print_uwbin(swa[2], true) txt.print_uwbin(swa[2], true)
; txt.nl() txt.nl()
; ror2(swa[2]) ror2(swa[2])
; txt.print_uwbin(swa[2], true) txt.print_uwbin(swa[2], true)
; txt.nl() txt.nl()
; txt.nl() txt.nl()
} }
} }