From 3fc49c001e68c7a6029c7b2dae60fcd8d02f61b5 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Tue, 2 May 2023 23:09:42 +0200 Subject: [PATCH] IR: fix for-loop codegen when step<0 --- .../prog8/codegen/intermediate/IRCodeGen.kt | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt index 529e8121d..408bcc544 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt @@ -520,16 +520,36 @@ class IRCodeGen( addToResult(result, fromTr, fromTr.resultReg, -1) val labelAfterFor = createLabelName() - val greaterOpcode = if(loopvarDt in SignedDatatypes) Opcode.BGTSR else Opcode.BGTR - addInstr(result, IRInstruction(greaterOpcode, loopvarDtIr, fromTr.resultReg, toTr.resultReg, labelSymbol=labelAfterFor), null) + val precheckInstruction = if(loopvarDt in SignedDatatypes) { + 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) 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 branchOpcode = if(loopvarDt in SignedDatatypes) Opcode.BGESR else Opcode.BGER - addInstr(result, IRInstruction(branchOpcode, loopvarDtIr, reg1=toTr.resultReg, reg2=fromTr.resultReg, labelSymbol=loopLabel), null) + 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) + } 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) return result