IR: fix forloop codegen for steps != 1

This commit is contained in:
Irmen de Jong 2023-07-10 19:42:55 +02:00
parent a98cb50d55
commit 6055b8c3dc
4 changed files with 50 additions and 32 deletions

View File

@ -552,22 +552,24 @@ class IRCodeGen(
addInstr(result, IRInstruction(Opcode.STOREM, loopvarDtIr, reg1=fromTr.resultReg, labelSymbol=loopvarSymbol), null)
result += labelFirstChunk(translateNode(forLoop.statements), loopLabel)
result += addConstMem(loopvarDtIr, null, loopvarSymbol, step)
addInstr(result, IRInstruction(Opcode.LOADM, loopvarDtIr, reg1 = fromTr.resultReg, labelSymbol = loopvarSymbol), null)
// if endvalue >= index, iterate loop
val branchInstr = if(loopvarDt in SignedDatatypes) {
if(step>0)
IRInstruction(Opcode.BGESR, loopvarDtIr, reg1=toTr.resultReg, reg2=fromTr.resultReg, labelSymbol=loopLabel)
else
IRInstruction(Opcode.BGESR, loopvarDtIr, reg1=fromTr.resultReg, reg2=toTr.resultReg, labelSymbol=loopLabel)
if(step==1 || step==-1) {
// if endvalue == index, stop loop, else iterate
addInstr(result, IRInstruction(Opcode.BEQR, loopvarDtIr, reg1=toTr.resultReg, reg2=fromTr.resultReg, labelSymbol = labelAfterFor), null)
result += addConstMem(loopvarDtIr, null, loopvarSymbol, step)
addInstr(result, IRInstruction(Opcode.JUMP, labelSymbol = loopLabel), null)
} else {
if(step>0)
IRInstruction(Opcode.BGER, loopvarDtIr, reg1=toTr.resultReg, reg2=fromTr.resultReg, labelSymbol=loopLabel)
// ind/dec index, then:
// ascending: if endvalue >= index, iterate
// descending: if index >= endvalue, iterate
result += addConstMem(loopvarDtIr, null, loopvarSymbol, step)
addInstr(result, IRInstruction(Opcode.LOADM, loopvarDtIr, reg1=fromTr.resultReg, labelSymbol = loopvarSymbol), null)
if(step > 0)
addInstr(result, IRInstruction(Opcode.CMP, loopvarDtIr, reg1 = toTr.resultReg, fromTr.resultReg), null)
else
IRInstruction(Opcode.BGER, loopvarDtIr, reg1=fromTr.resultReg, reg2=toTr.resultReg, labelSymbol=loopLabel)
addInstr(result, IRInstruction(Opcode.CMP, loopvarDtIr, reg1 = fromTr.resultReg, toTr.resultReg), null)
addInstr(result, IRInstruction(Opcode.BSTPOS, labelSymbol = loopLabel), null)
}
addInstr(result, branchInstr, null)
result += IRCodeChunk(labelAfterFor, null)
return result
}

View File

@ -145,12 +145,16 @@ Directives
Level: not at module scope.
This directive can only be used inside a block.
The assembler will include the file as binary bytes at this point, prog8 will not process this at all.
The optional offset and length can be used to select a particular piece of the file.
The assembler itself will include the file as binary bytes at this point, prog8 will not process this at all.
This means that the filename must be spelled exactly as it appears on your computer's file system.
Note that this filename may differ in case compared to when you chose to load the file from disk from within the
program code itself (for example on the C64 and X16 there's the PETSCII encoding difference).
The file is located relative to the current working directory!
The optional offset and length can be used to select a particular piece of the file.
To reference the contents of the included binary data, you can put a label in your prog8 code
just before the %asmbinary. An example program for this can be found below at the description of %asminclude.
.. data:: %asminclude "<filename>"
Level: not at module scope.

View File

@ -1,9 +1,13 @@
TODO
====
- VM: fix endless loop n=0 :: for i in 5 downto n (fine for n=1) (wrong for bytes and words)
- codegen: fix endless loop uword n=0 :: for uword i in 10 downto n step -3
- investigate if the hiscores issue on the forum is a compiler bug or not.
- IR: instructions that do type conversion (SZ etc, CONCAT, SGN) should put the result in a DIFFERENT register.
- IR: optimize forloop codegen to use a reg as loop variable instead of a memory variable, just store it in the mem var before entering the loop body
check repeat loop as well it shouldn't be using a tempvar just a register to count.
...

View File

@ -4,23 +4,31 @@
main {
sub start() {
byte intensity = -25
txt.print_b(intensity)
txt.nl()
txt.print_b(abs(intensity))
intensity = abs(intensity)
txt.nl()
txt.print_b(intensity)
txt.nl()
uword n=0
uword i
txt.print("ascending:\n")
n=10
for i in 0 to n step 3 {
cx16.r0++
txt.print(" i=")
txt.print_uw(i)
txt.spc()
txt.print(" n=")
txt.print_uw(n)
txt.nl()
}
txt.print_uw0(12345)
txt.nl()
word intensityw = -12345
txt.print_w(intensityw)
txt.nl()
txt.print_w(abs(intensityw))
intensityw = abs(intensityw)
txt.nl()
txt.print_w(intensityw)
txt.print("descending:\n")
n=0
for i in 10 downto n step -3 {
cx16.r0++
txt.print(" i=")
txt.print_uw(i)
txt.spc()
txt.print(" n=")
txt.print_uw(n)
txt.nl()
}
}
}