diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt index 7e2c99393..32609ee3a 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt @@ -119,7 +119,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express origAssign.operator.dropLast(1) } } - value = PtBinaryExpression(operator, origAssign.value.type, origAssign.value.position) + value = PtBinaryExpression(operator, origAssign.target.type, origAssign.value.position) val left: PtExpression = origAssign.target.children.single() as PtExpression value.add(left) value.add(origAssign.value) @@ -997,10 +997,14 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express private fun operatorShiftRightInplace(symbol: String?, array: PtArrayIndexer?, constAddress: Int?, memory: PtMemoryByte?, vmDt: IRDataType, operand: PtExpression, signed: Boolean): IRCodeChunks? { if(array!=null) { - TODO(">> in array") + if(array.splitWords) + return null // TODO("optimized >> in split word array") + else { + return null // TODO("optimized >> in array") + } } if(constAddress==null && memory!=null) - return null // TODO("optimized memory in-place >>"") + return null // TODO("optimized memory in-place >>"") val result = mutableListOf<IRCodeChunkBase>() if(codeGen.isOne(operand)) { @@ -1025,7 +1029,11 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express private fun operatorShiftLeftInplace(symbol: String?, array: PtArrayIndexer?, constAddress: Int?, memory: PtMemoryByte?, vmDt: IRDataType, operand: PtExpression): IRCodeChunks? { if(array!=null) { - TODO("<< in array") + if(array.splitWords) + return null // TODO("optimized << in split word array") + else { + return null // TODO("optimized << in array") + } } if(constAddress==null && memory!=null) return null // TODO("optimized memory in-place <<"") diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/BuiltinFuncGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/BuiltinFuncGen.kt index 454684d3c..82eff60cc 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/BuiltinFuncGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/BuiltinFuncGen.kt @@ -549,10 +549,24 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe val index = arr?.index?.asConstInteger() if(arr!=null && index!=null) { val variable = arr.variable.name - if(arr.splitWords) - TODO("IR rol/ror on split words array") - val offset = codeGen.program.memsizer.memorySize(arr.type, index) - addInstr(result, IRInstruction(opcodeMemAndReg.first, vmDt, labelSymbol = variable, symbolOffset = offset), null) + if(arr.splitWords) { + result += IRCodeChunk(null, null).also { + when(opcodeMemAndReg.first) { + Opcode.ROXRM, Opcode.RORM -> { + it += IRInstruction(opcodeMemAndReg.first, IRDataType.BYTE, labelSymbol = "${variable}_msb", symbolOffset = index) + it += IRInstruction(opcodeMemAndReg.first, IRDataType.BYTE, labelSymbol = "${variable}_lsb", symbolOffset = index) + } + Opcode.ROXLM, Opcode.ROLM -> { + it += IRInstruction(opcodeMemAndReg.first, IRDataType.BYTE, labelSymbol = "${variable}_lsb", symbolOffset = index) + it += IRInstruction(opcodeMemAndReg.first, IRDataType.BYTE, labelSymbol = "${variable}_msb", symbolOffset = index) + } + else -> throw AssemblyError("wrong rol/ror opcode") + } + } + } else { + val offset = codeGen.program.memsizer.memorySize(arr.type, index) + addInstr(result, IRInstruction(opcodeMemAndReg.first, vmDt, labelSymbol = variable, symbolOffset = offset), null) + } return ExpressionCodeResult(result, vmDt, -1, -1) } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 5c16d7e1a..7c9d1b6f3 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -1,6 +1,9 @@ TODO ==== +- IR: implement "optimized << in array" / "optimized >> in array" +- IR: implement "optimized << in split word array" / "optimized >> in split word array" + - add paypal donation button as well? - announce prog8 on the 6502.org site? @@ -47,8 +50,6 @@ IR/VM ----- - getting it in shape for code generation...: the IR file should be able to encode every detail about a prog8 program (the VM doesn't have to actually be able to run all of it though!) - add BZ and BNZ instructions? To replace CMPI #0 + Branch? -- fix TODO("IR rol/ror on split words array") -- fix "<< in array" / ">> in array" - implement fast code paths for TODO("inplace split.... - sometimes source lines end up missing in the output p8ir, for example the first assignment is gone in: sub start() { diff --git a/examples/test.p8 b/examples/test.p8 index 7751e737c..6bb2ced35 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -4,7 +4,72 @@ main { sub start() { - txt.print_uw(cx16.r0) + uword wv = %01000010_01000010 + + ; expected: $8484 $4242 + sys.set_carry() + rol(wv) + txt.print_uwhex(wv, true) + sys.set_carry() + ror(wv) + txt.print_uwhex(wv, true) + txt.nl() + + wv = %01000010_01000010 + sys.set_carry() + rol2(wv) + txt.print_uwhex(wv, true) + sys.set_carry() + ror2(wv) + txt.print_uwhex(wv, true) + txt.nl() + + uword[] @nosplit arr = [ %01000010_01000010 , %01000010_01000010, %01000010_01000010 ] + uword[] @split arrsplit = [ %01000010_01000010 , %01000010_01000010, %01000010_01000010 ] + + sys.set_carry() + rol(arr[2]) + txt.print_uwhex(arr[2], true) + sys.set_carry() + ror(arr[2]) + txt.print_uwhex(arr[2], true) + txt.nl() + sys.set_carry() + rol2(arr[1]) + txt.print_uwhex(arr[1], true) + sys.set_carry() + ror2(arr[1]) + txt.print_uwhex(arr[1], true) + txt.nl() + + sys.set_carry() + rol(arrsplit[2]) + txt.print_uwhex(arrsplit[2], true) + sys.set_carry() + ror(arrsplit[2]) + txt.print_uwhex(arrsplit[2], true) + txt.nl() + sys.set_carry() + rol2(arrsplit[1]) + txt.print_uwhex(arrsplit[1], true) + sys.set_carry() + ror2(arrsplit[1]) + txt.print_uwhex(arrsplit[1], true) + txt.nl() + + + ; expected $2468 $1234 + arr[2] = $1234 + arr[2] <<= 1 + txt.print_uwhex(arr[2], true) + arr[2] >>= 1 + txt.print_uwhex(arr[2], true) + txt.nl() + arrsplit[2] = $1234 + arrsplit[2] <<= 1 + txt.print_uwhex(arrsplit[2], true) + arrsplit[2] >>= 1 + txt.print_uwhex(arrsplit[2], true) txt.nl() } }