mirror of
https://github.com/irmen/prog8.git
synced 2025-01-26 19:30:59 +00:00
IR: fix forloop codegen for steps != 1
This commit is contained in:
parent
a98cb50d55
commit
6055b8c3dc
@ -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
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
||||
...
|
||||
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user