IR: fix for loop over range with step

This commit is contained in:
Irmen de Jong 2023-08-11 03:04:08 +02:00
parent 3e6d16a7a8
commit b92e22e4a6
4 changed files with 19 additions and 14 deletions

View File

@ -586,23 +586,22 @@ class IRCodeGen(
else -> throw AssemblyError("invalid loopvar node type") else -> throw AssemblyError("invalid loopvar node type")
} }
val loopvarDtIr = irType(loopvarDt) val loopvarDtIr = irType(loopvarDt)
val iterable = forLoop.iterable as PtRange val iterable = (forLoop.iterable as PtRange).toConstantIntegerRange()!!
val step = iterable.step.number.toInt() if(iterable.isEmpty())
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 && rangeEndExclusiveUntyped<rangeStart || step<0 && rangeEndExclusiveUntyped>rangeStart)
throw AssemblyError("empty range") 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 rangeEndExclusiveWrapped = if(loopvarDtIr==IRDataType.BYTE) rangeEndExclusiveUntyped and 255 else rangeEndExclusiveUntyped and 65535
val result = mutableListOf<IRCodeChunkBase>() val result = mutableListOf<IRCodeChunkBase>()
val chunk = IRCodeChunk(null, null) 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) chunk += IRInstruction(Opcode.STOREM, loopvarDtIr, reg1=indexReg, labelSymbol=loopvarSymbol)
result += chunk result += chunk
result += labelFirstChunk(translateNode(forLoop.statements), loopLabel) 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.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) chunk2 += IRInstruction(Opcode.BNE, loopvarDtIr, reg1 = indexReg, immediate = rangeEndExclusiveWrapped, labelSymbol = loopLabel)
result += chunk2 result += chunk2
return result return result

View File

@ -210,13 +210,13 @@ main {
var result = compileText(target, true, src, writeAssembly = true)!! var result = compileText(target, true, src, writeAssembly = true)!!
var virtfile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".p8ir") var virtfile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".p8ir")
VmRunner().runAndTestProgram(virtfile.readText()) { vm -> VmRunner().runAndTestProgram(virtfile.readText()) { vm ->
vm.stepCount shouldBe 48 vm.stepCount shouldBe 59
} }
result = compileText(target, false, src, writeAssembly = true)!! result = compileText(target, false, src, writeAssembly = true)!!
virtfile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".p8ir") virtfile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".p8ir")
VmRunner().runAndTestProgram(virtfile.readText()) { vm -> VmRunner().runAndTestProgram(virtfile.readText()) { vm ->
vm.stepCount shouldBe 48 vm.stepCount shouldBe 59
} }
} }

View File

@ -1,9 +1,7 @@
TODO TODO
==== ====
- fix range expression problems in VM/IR (see test.p8) - [on branch:] investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 ....
- 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 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! - 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!

View File

@ -10,6 +10,14 @@ main {
ubyte xx ubyte xx
byte bb 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 { for xx in array {
txt.print_ub(xx) txt.print_ub(xx)
txt.spc() txt.spc()