diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt index 21030ce2a..37cc1985e 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt @@ -586,23 +586,22 @@ class IRCodeGen( else -> throw AssemblyError("invalid loopvar node type") } val loopvarDtIr = irType(loopvarDt) - val iterable = forLoop.iterable as PtRange - val step = iterable.step.number.toInt() - val rangeStart = (iterable.from as PtNumber).number.toInt() - val rangeEndExclusiveUntyped = (iterable.to as PtNumber).number.toInt() + step - if(step==0) - throw AssemblyError("step 0") - if(step>0 && rangeEndExclusiveUntypedrangeStart) + val iterable = (forLoop.iterable as PtRange).toConstantIntegerRange()!! + if(iterable.isEmpty()) throw AssemblyError("empty range") + if(iterable.step==0) + throw AssemblyError("step 0") + val rangeEndExclusiveUntyped = iterable.last + iterable.step val rangeEndExclusiveWrapped = if(loopvarDtIr==IRDataType.BYTE) rangeEndExclusiveUntyped and 255 else rangeEndExclusiveUntyped and 65535 val result = mutableListOf() val chunk = IRCodeChunk(null, null) - chunk += IRInstruction(Opcode.LOAD, loopvarDtIr, reg1=indexReg, immediate = rangeStart) + chunk += IRInstruction(Opcode.LOAD, loopvarDtIr, reg1=indexReg, immediate = iterable.first) chunk += IRInstruction(Opcode.STOREM, loopvarDtIr, reg1=indexReg, labelSymbol=loopvarSymbol) result += chunk result += labelFirstChunk(translateNode(forLoop.statements), loopLabel) - val chunk2 = addConstMem(loopvarDtIr, null, loopvarSymbol, step) + val chunk2 = addConstMem(loopvarDtIr, null, loopvarSymbol, iterable.step) chunk2 += IRInstruction(Opcode.LOADM, loopvarDtIr, reg1 = indexReg, labelSymbol = loopvarSymbol) + chunk2 += IRInstruction(Opcode.XOR, loopvarDtIr, reg1 = 999, immediate = 111) chunk2 += IRInstruction(Opcode.BNE, loopvarDtIr, reg1 = indexReg, immediate = rangeEndExclusiveWrapped, labelSymbol = loopLabel) result += chunk2 return result diff --git a/compiler/test/vm/TestCompilerVirtual.kt b/compiler/test/vm/TestCompilerVirtual.kt index b958b0c13..4b6834a0f 100644 --- a/compiler/test/vm/TestCompilerVirtual.kt +++ b/compiler/test/vm/TestCompilerVirtual.kt @@ -210,13 +210,13 @@ main { var result = compileText(target, true, src, writeAssembly = true)!! var virtfile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".p8ir") VmRunner().runAndTestProgram(virtfile.readText()) { vm -> - vm.stepCount shouldBe 48 + vm.stepCount shouldBe 59 } result = compileText(target, false, src, writeAssembly = true)!! virtfile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".p8ir") VmRunner().runAndTestProgram(virtfile.readText()) { vm -> - vm.stepCount shouldBe 48 + vm.stepCount shouldBe 59 } } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 3f9f343f5..65eec751a 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -1,9 +1,7 @@ TODO ==== -- fix range expression problems in VM/IR (see test.p8) - -- investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 .... +- [on branch:] investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 .... - IR: reduce the number of branch instructions such as BEQ, BEQR, etc (gradually), replace with CMP(I) + status branch instruction - IR: reduce amount of CMP/CMPI after instructions that set the status bits correctly (LOADs? INC? etc), but only after setting the status bits is verified! diff --git a/examples/test.p8 b/examples/test.p8 index 84d35578d..ac7cec699 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -10,6 +10,14 @@ main { ubyte xx byte bb + cx16.r1=0 + for cx16.r0 in 0 to 10 { + cx16.r1++ + } + txt.print_uw(cx16.r1) + txt.nl() + txt.nl() + for xx in array { txt.print_ub(xx) txt.spc()