mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
IR: fix for loop over range with step
This commit is contained in:
parent
3e6d16a7a8
commit
b92e22e4a6
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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!
|
||||||
|
|
||||||
|
@ -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()
|
||||||
|
Loading…
Reference in New Issue
Block a user