mirror of
https://github.com/irmen/prog8.git
synced 2024-11-29 17:50:35 +00:00
IR: fix for-loop codegen when step<0
This commit is contained in:
parent
24f37e2062
commit
3fc49c001e
@ -520,16 +520,36 @@ class IRCodeGen(
|
|||||||
addToResult(result, fromTr, fromTr.resultReg, -1)
|
addToResult(result, fromTr, fromTr.resultReg, -1)
|
||||||
|
|
||||||
val labelAfterFor = createLabelName()
|
val labelAfterFor = createLabelName()
|
||||||
val greaterOpcode = if(loopvarDt in SignedDatatypes) Opcode.BGTSR else Opcode.BGTR
|
val precheckInstruction = if(loopvarDt in SignedDatatypes) {
|
||||||
addInstr(result, IRInstruction(greaterOpcode, loopvarDtIr, fromTr.resultReg, toTr.resultReg, labelSymbol=labelAfterFor), null)
|
if(step>0)
|
||||||
|
IRInstruction(Opcode.BGTSR, loopvarDtIr, fromTr.resultReg, toTr.resultReg, labelSymbol=labelAfterFor)
|
||||||
|
else
|
||||||
|
IRInstruction(Opcode.BGTSR, loopvarDtIr, toTr.resultReg, fromTr.resultReg, labelSymbol=labelAfterFor)
|
||||||
|
} else {
|
||||||
|
if(step>0)
|
||||||
|
IRInstruction(Opcode.BGTR, loopvarDtIr, fromTr.resultReg, toTr.resultReg, labelSymbol=labelAfterFor)
|
||||||
|
else
|
||||||
|
IRInstruction(Opcode.BGTR, loopvarDtIr, toTr.resultReg, fromTr.resultReg, labelSymbol=labelAfterFor)
|
||||||
|
}
|
||||||
|
addInstr(result, precheckInstruction, null)
|
||||||
|
|
||||||
addInstr(result, IRInstruction(Opcode.STOREM, loopvarDtIr, reg1=fromTr.resultReg, labelSymbol=loopvarSymbol), null)
|
addInstr(result, IRInstruction(Opcode.STOREM, loopvarDtIr, reg1=fromTr.resultReg, labelSymbol=loopvarSymbol), null)
|
||||||
result += labelFirstChunk(translateNode(forLoop.statements), loopLabel)
|
result += labelFirstChunk(translateNode(forLoop.statements), loopLabel)
|
||||||
result += addConstMem(loopvarDtIr, null, loopvarSymbol, step)
|
result += addConstMem(loopvarDtIr, null, loopvarSymbol, step)
|
||||||
addInstr(result, IRInstruction(Opcode.LOADM, loopvarDtIr, reg1 = fromTr.resultReg, labelSymbol = loopvarSymbol), null)
|
addInstr(result, IRInstruction(Opcode.LOADM, loopvarDtIr, reg1 = fromTr.resultReg, labelSymbol = loopvarSymbol), null)
|
||||||
// if endvalue >= index, iterate loop
|
// if endvalue >= index, iterate loop
|
||||||
val branchOpcode = if(loopvarDt in SignedDatatypes) Opcode.BGESR else Opcode.BGER
|
val branchInstr = if(loopvarDt in SignedDatatypes) {
|
||||||
addInstr(result, IRInstruction(branchOpcode, loopvarDtIr, reg1=toTr.resultReg, reg2=fromTr.resultReg, labelSymbol=loopLabel), null)
|
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)
|
||||||
|
} else {
|
||||||
|
if(step>0)
|
||||||
|
IRInstruction(Opcode.BGER, loopvarDtIr, reg1=toTr.resultReg, reg2=fromTr.resultReg, labelSymbol=loopLabel)
|
||||||
|
else
|
||||||
|
IRInstruction(Opcode.BGER, loopvarDtIr, reg1=fromTr.resultReg, reg2=toTr.resultReg, labelSymbol=loopLabel)
|
||||||
|
}
|
||||||
|
addInstr(result, branchInstr, null)
|
||||||
|
|
||||||
result += IRCodeChunk(labelAfterFor, null)
|
result += IRCodeChunk(labelAfterFor, null)
|
||||||
return result
|
return result
|
||||||
|
Loading…
Reference in New Issue
Block a user