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.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)
|
||||
result += labelFirstChunk(translateNode(forLoop.statements), loopLabel)
|
||||
result += addConstMem(loopvarDtIr, null, loopvarSymbol, step)
|
||||
addInstr(result, IRInstruction(Opcode.LOADM, loopvarDtIr, reg1 = indexReg, labelSymbol = loopvarSymbol), null)
|
||||
val branchOpcode = if(loopvarDt in SignedDatatypes) Opcode.BLES else Opcode.BLE
|
||||
addInstr(result, IRInstruction(branchOpcode, loopvarDtIr, reg1=indexReg, reg2=endvalueReg, labelSymbol=loopLabel), null)
|
||||
|
||||
result += IRCodeChunk(labelAfterFor, null)
|
||||
return result
|
||||
}
|
||||
|
||||
|
@ -1 +1 @@
|
||||
8.8.1
|
||||
8.9-dev
|
||||
|
@ -3,6 +3,7 @@ TODO
|
||||
|
||||
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:
|
||||
- rewrite bool=bool^1 into bool=not bool
|
||||
- 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: add more optimizations in IRPeepholeOptimizer
|
||||
- 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.
|
||||
this is documented behavior to now loop around but it's too easy to forget about!
|
||||
Lot of work because of so many special cases in ForLoopsAsmgen.....
|
||||
How is it for the vm target? -> just 2 special cases in CodeGen.
|
||||
- 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.
|
||||
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..... (vm codegen already behaves like this)
|
||||
- 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.
|
||||
but probably better to rewrite the 6502 codegen on top of the new Ast.
|
||||
- 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
|
||||
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
|
||||
blt reg1, reg2, address - jump to location in program given by location, if reg1 < reg2 (unsigned)
|
||||
blts reg1, reg2, address - jump to location in program given by location, if reg1 < reg2 (signed)
|
||||
ble reg1, reg2, address - jump to location in program given by location, if reg1 <= reg2 (unsigned)
|
||||
bles reg1, reg2, address - jump to location in program given by location, if reg1 <= reg2 (signed)
|
||||
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) TODO REMOVE
|
||||
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) TODO REMOVE
|
||||
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)
|
||||
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)
|
||||
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
|
||||
slt reg1, reg2 - set reg=1 if reg1 < reg2 (unsigned), otherwise set reg1=0
|
||||
slts reg1, reg2 - set reg=1 if reg1 < reg2 (signed), otherwise set reg1=0
|
||||
sle reg1, reg2 - set reg=1 if reg1 <= reg2 (unsigned), otherwise set reg1=0
|
||||
sles reg1, reg2 - set reg=1 if reg1 <= reg2 (signed), 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 TODO REMOVE
|
||||
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 TODO REMOVE
|
||||
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
|
||||
sge reg1, reg2 - set reg=1 if reg1 >= reg2 (unsigned), otherwise set reg1=0
|
||||
@ -244,22 +244,22 @@ enum class Opcode {
|
||||
BNZ,
|
||||
BEQ,
|
||||
BNE,
|
||||
BLT,
|
||||
BLTS,
|
||||
BLT, // TODO REMOVE
|
||||
BLTS, // TODO REMOVE
|
||||
BGT,
|
||||
BGTS,
|
||||
BLE,
|
||||
BLES,
|
||||
BLE, // TODO REMOVE
|
||||
BLES, // TODO REMOVE
|
||||
BGE,
|
||||
BGES,
|
||||
SEQ,
|
||||
SNE,
|
||||
SLT,
|
||||
SLTS,
|
||||
SLT, // TODO REMOVE ?
|
||||
SLTS, // TODO REMOVE ?
|
||||
SGT,
|
||||
SGTS,
|
||||
SLE,
|
||||
SLES,
|
||||
SLE, // TODO REMOVE ?
|
||||
SLES, // TODO REMOVE ?
|
||||
SGE,
|
||||
SGES,
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user