mirror of
https://github.com/irmen/prog8.git
synced 2025-01-11 13:29:45 +00:00
vm/ir: for loop is now correctly skipped if loopvar>endvar
this is different still in the 6502 codegen, where it wraps around $00!
This commit is contained in:
parent
81bd5c784e
commit
7ee777f405
@ -542,12 +542,19 @@ class IRCodeGen(
|
|||||||
|
|
||||||
result += expressionEval.translateExpression(iterable.to, endvalueReg, -1)
|
result += expressionEval.translateExpression(iterable.to, endvalueReg, -1)
|
||||||
result += expressionEval.translateExpression(iterable.from, indexReg, -1)
|
result += expressionEval.translateExpression(iterable.from, indexReg, -1)
|
||||||
|
|
||||||
|
val labelAfterFor = createLabelName()
|
||||||
|
val greaterOpcode = if(loopvarDt in SignedDatatypes) Opcode.BGTS else Opcode.BGT
|
||||||
|
addInstr(result, IRInstruction(greaterOpcode, loopvarDtIr, indexReg, endvalueReg, labelSymbol=labelAfterFor), null)
|
||||||
|
|
||||||
addInstr(result, IRInstruction(Opcode.STOREM, loopvarDtIr, reg1=indexReg, labelSymbol=loopvarSymbol), null)
|
addInstr(result, IRInstruction(Opcode.STOREM, loopvarDtIr, reg1=indexReg, 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 = indexReg, labelSymbol = loopvarSymbol), null)
|
addInstr(result, IRInstruction(Opcode.LOADM, loopvarDtIr, reg1 = indexReg, labelSymbol = loopvarSymbol), null)
|
||||||
val branchOpcode = if(loopvarDt in SignedDatatypes) Opcode.BLES else Opcode.BLE
|
val branchOpcode = if(loopvarDt in SignedDatatypes) Opcode.BLES else Opcode.BLE
|
||||||
addInstr(result, IRInstruction(branchOpcode, loopvarDtIr, reg1=indexReg, reg2=endvalueReg, labelSymbol=loopLabel), null)
|
addInstr(result, IRInstruction(branchOpcode, loopvarDtIr, reg1=indexReg, reg2=endvalueReg, labelSymbol=loopLabel), null)
|
||||||
|
|
||||||
|
result += IRCodeChunk(labelAfterFor, null)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
8.8.1
|
8.9-dev
|
||||||
|
@ -3,6 +3,7 @@ TODO
|
|||||||
|
|
||||||
For next release
|
For next release
|
||||||
^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^
|
||||||
|
- remove redundant branch opcodes in IR: BLT(S), BLE(S). Replace by swapped BGT(S), BGE(S).
|
||||||
- make sure bool value is always 0 or 1 (all casts should convert), then:
|
- make sure bool value is always 0 or 1 (all casts should convert), then:
|
||||||
- rewrite bool=bool^1 into bool=not bool
|
- rewrite bool=bool^1 into bool=not bool
|
||||||
- should solve: bool bb = not bb -> larger code than bool bb ^= 1
|
- should solve: bool bb = not bb -> larger code than bool bb ^= 1
|
||||||
@ -33,10 +34,10 @@ Compiler:
|
|||||||
- ir peephole opt: reuse registers in chunks (but keep result registers in mind that pass values out!)
|
- ir peephole opt: reuse registers in chunks (but keep result registers in mind that pass values out!)
|
||||||
- ir: add more optimizations in IRPeepholeOptimizer
|
- ir: add more optimizations in IRPeepholeOptimizer
|
||||||
- vm: somehow be able to load a label address as value? (VmProgramLoader)
|
- vm: somehow be able to load a label address as value? (VmProgramLoader)
|
||||||
- see if we can let for loops skip the loop if end<start, like other programming languages. Without adding a lot of code size/duplicating the loop condition.
|
- 6502 codegen: see if we can let for loops skip the loop if startvar>endvar, without adding a lot of code size/duplicating the loop condition.
|
||||||
this is documented behavior to now loop around but it's too easy to forget about!
|
It is documented behavior to now loop 'around' $00 but it's too easy to forget about!
|
||||||
Lot of work because of so many special cases in ForLoopsAsmgen.....
|
Lot of work because of so many special cases in ForLoopsAsmgen..... (vm codegen already behaves like this)
|
||||||
How is it for the vm target? -> just 2 special cases in CodeGen.
|
- ir: can we determine for the loop variable in forloops if it could be kept in a (virtual) register instead of a real variable? Need to be able to check if the variable is used by another statement beside just the for loop.
|
||||||
- createAssemblyAndAssemble(): make it possible to actually get rid of the VarDecl nodes by fixing the rest of the code mentioned there.
|
- createAssemblyAndAssemble(): make it possible to actually get rid of the VarDecl nodes by fixing the rest of the code mentioned there.
|
||||||
but probably better to rewrite the 6502 codegen on top of the new Ast.
|
but probably better to rewrite the 6502 codegen on top of the new Ast.
|
||||||
- generate WASM to eventually run prog8 on a browser canvas?
|
- generate WASM to eventually run prog8 on a browser canvas?
|
||||||
|
@ -76,20 +76,20 @@ bz reg1, address - branch to location if reg1 is zero
|
|||||||
bnz reg1, address - branch to location if reg1 is not zero
|
bnz reg1, address - branch to location if reg1 is not zero
|
||||||
beq reg1, reg2, address - jump to location in program given by location, if reg1 == reg2
|
beq reg1, reg2, address - jump to location in program given by location, if reg1 == reg2
|
||||||
bne reg1, reg2, address - jump to location in program given by location, if reg1 != reg2
|
bne reg1, reg2, address - jump to location in program given by location, if reg1 != reg2
|
||||||
blt reg1, reg2, address - jump to location in program given by location, if reg1 < reg2 (unsigned)
|
blt reg1, reg2, address - jump to location in program given by location, if reg1 < reg2 (unsigned) TODO REMOVE
|
||||||
blts reg1, reg2, address - jump to location in program given by location, if reg1 < reg2 (signed)
|
blts reg1, reg2, address - jump to location in program given by location, if reg1 < reg2 (signed) TODO REMOVE
|
||||||
ble reg1, reg2, address - jump to location in program given by location, if reg1 <= reg2 (unsigned)
|
ble reg1, reg2, address - jump to location in program given by location, if reg1 <= reg2 (unsigned) TODO REMOVE
|
||||||
bles reg1, reg2, address - jump to location in program given by location, if reg1 <= reg2 (signed)
|
bles reg1, reg2, address - jump to location in program given by location, if reg1 <= reg2 (signed) TODO REMOVE
|
||||||
bgt reg1, reg2, address - jump to location in program given by location, if reg1 > reg2 (unsigned)
|
bgt reg1, reg2, address - jump to location in program given by location, if reg1 > reg2 (unsigned)
|
||||||
bgts reg1, reg2, address - jump to location in program given by location, if reg1 > reg2 (signed)
|
bgts reg1, reg2, address - jump to location in program given by location, if reg1 > reg2 (signed)
|
||||||
bge reg1, reg2, address - jump to location in program given by location, if reg1 >= reg2 (unsigned)
|
bge reg1, reg2, address - jump to location in program given by location, if reg1 >= reg2 (unsigned)
|
||||||
bges reg1, reg2, address - jump to location in program given by location, if reg1 >= reg2 (signed)
|
bges reg1, reg2, address - jump to location in program given by location, if reg1 >= reg2 (signed)
|
||||||
seq reg1, reg2 - set reg=1 if reg1 == reg2, otherwise set reg1=0
|
seq reg1, reg2 - set reg=1 if reg1 == reg2, otherwise set reg1=0
|
||||||
sne reg1, reg2 - set reg=1 if reg1 != reg2, otherwise set reg1=0
|
sne reg1, reg2 - set reg=1 if reg1 != reg2, otherwise set reg1=0
|
||||||
slt reg1, reg2 - set reg=1 if reg1 < reg2 (unsigned), otherwise set reg1=0
|
slt reg1, reg2 - set reg=1 if reg1 < reg2 (unsigned), otherwise set reg1=0 TODO REMOVE
|
||||||
slts reg1, reg2 - set reg=1 if reg1 < reg2 (signed), otherwise set reg1=0
|
slts reg1, reg2 - set reg=1 if reg1 < reg2 (signed), otherwise set reg1=0 TODO REMOVE
|
||||||
sle reg1, reg2 - set reg=1 if reg1 <= reg2 (unsigned), otherwise set reg1=0
|
sle reg1, reg2 - set reg=1 if reg1 <= reg2 (unsigned), otherwise set reg1=0 TODO REMOVE
|
||||||
sles reg1, reg2 - set reg=1 if reg1 <= reg2 (signed), otherwise set reg1=0
|
sles reg1, reg2 - set reg=1 if reg1 <= reg2 (signed), otherwise set reg1=0 TODO REMOVE
|
||||||
sgt reg1, reg2 - set reg=1 if reg1 > reg2 (unsigned), otherwise set reg1=0
|
sgt reg1, reg2 - set reg=1 if reg1 > reg2 (unsigned), otherwise set reg1=0
|
||||||
sgts reg1, reg2 - set reg=1 if reg1 > reg2 (signed), otherwise set reg1=0
|
sgts reg1, reg2 - set reg=1 if reg1 > reg2 (signed), otherwise set reg1=0
|
||||||
sge reg1, reg2 - set reg=1 if reg1 >= reg2 (unsigned), otherwise set reg1=0
|
sge reg1, reg2 - set reg=1 if reg1 >= reg2 (unsigned), otherwise set reg1=0
|
||||||
@ -244,22 +244,22 @@ enum class Opcode {
|
|||||||
BNZ,
|
BNZ,
|
||||||
BEQ,
|
BEQ,
|
||||||
BNE,
|
BNE,
|
||||||
BLT,
|
BLT, // TODO REMOVE
|
||||||
BLTS,
|
BLTS, // TODO REMOVE
|
||||||
BGT,
|
BGT,
|
||||||
BGTS,
|
BGTS,
|
||||||
BLE,
|
BLE, // TODO REMOVE
|
||||||
BLES,
|
BLES, // TODO REMOVE
|
||||||
BGE,
|
BGE,
|
||||||
BGES,
|
BGES,
|
||||||
SEQ,
|
SEQ,
|
||||||
SNE,
|
SNE,
|
||||||
SLT,
|
SLT, // TODO REMOVE ?
|
||||||
SLTS,
|
SLTS, // TODO REMOVE ?
|
||||||
SGT,
|
SGT,
|
||||||
SGTS,
|
SGTS,
|
||||||
SLE,
|
SLE, // TODO REMOVE ?
|
||||||
SLES,
|
SLES, // TODO REMOVE ?
|
||||||
SGE,
|
SGE,
|
||||||
SGES,
|
SGES,
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user