mirror of
https://github.com/irmen/prog8.git
synced 2025-01-10 20:30:23 +00:00
tweak vm codegen
This commit is contained in:
parent
93ce74eeb1
commit
1e441c2ddf
@ -1,9 +1,7 @@
|
||||
package prog8.codegen.virtual
|
||||
|
||||
import prog8.code.ast.*
|
||||
import prog8.code.core.AssemblyError
|
||||
import prog8.code.core.DataType
|
||||
import prog8.code.core.SignedDatatypes
|
||||
import prog8.code.core.*
|
||||
import prog8.vm.Opcode
|
||||
import prog8.vm.VmDataType
|
||||
|
||||
@ -33,7 +31,9 @@ internal class AssignmentGen(private val codeGen: CodeGen, private val expressio
|
||||
else
|
||||
fallbackAssign(assignment)
|
||||
} else if(array!=null) {
|
||||
// TODO in-place array element assignment?
|
||||
// NOTE: naive fallback assignment here will sometimes generate code that loads the index value multiple times
|
||||
// in a register. It's way too much work to optimize that here - instead, we trust that the generated IL assembly
|
||||
// will be optimized later and have the double assignments removed.
|
||||
fallbackAssign(assignment)
|
||||
} else {
|
||||
fallbackAssign(assignment)
|
||||
|
@ -275,15 +275,8 @@ class CodeGen(internal val program: PtProgram,
|
||||
code += VmCodeInstruction(Opcode.STOREM, loopvarDt, reg1=indexReg, value=loopvarAddress)
|
||||
code += VmCodeLabel(loopLabel)
|
||||
code += translateNode(forLoop.statements)
|
||||
if(step<3) {
|
||||
code += addConstMem(loopvarDt, loopvarAddress.toUInt(), step)
|
||||
code += VmCodeInstruction(Opcode.LOADM, loopvarDt, reg1 = indexReg, value = loopvarAddress)
|
||||
} else {
|
||||
// TODO WHY THIS DISTINCTION?
|
||||
code += VmCodeInstruction(Opcode.LOADM, loopvarDt, reg1 = indexReg, value = loopvarAddress)
|
||||
code += addConstReg(loopvarDt, indexReg, step)
|
||||
code += VmCodeInstruction(Opcode.STOREM, loopvarDt, reg1 = indexReg, value = loopvarAddress)
|
||||
}
|
||||
code += addConstMem(loopvarDt, loopvarAddress.toUInt(), step)
|
||||
code += VmCodeInstruction(Opcode.LOADM, loopvarDt, reg1 = indexReg, value = loopvarAddress)
|
||||
val branchOpcode = if(loopvar.dt in SignedDatatypes) Opcode.BLES else Opcode.BLE
|
||||
code += VmCodeInstruction(branchOpcode, loopvarDt, reg1=indexReg, reg2=endvalueReg, labelSymbol=loopLabel)
|
||||
return code
|
||||
@ -315,15 +308,8 @@ class CodeGen(internal val program: PtProgram,
|
||||
code += VmCodeInstruction(Opcode.STOREM, loopvarDt, reg1=indexReg, value=loopvarAddress)
|
||||
code += VmCodeLabel(loopLabel)
|
||||
code += translateNode(forLoop.statements)
|
||||
if(step<3) {
|
||||
code += addConstMem(loopvarDt, loopvarAddress.toUInt(), step)
|
||||
code += VmCodeInstruction(Opcode.LOADM, loopvarDt, reg1 = indexReg, value = loopvarAddress)
|
||||
} else {
|
||||
// TODO WHY THIS DISTICTION ?
|
||||
code += VmCodeInstruction(Opcode.LOADM, loopvarDt, reg1 = indexReg, value = loopvarAddress)
|
||||
code += addConstReg(loopvarDt, indexReg, step)
|
||||
code += VmCodeInstruction(Opcode.STOREM, loopvarDt, reg1 = indexReg, value = loopvarAddress)
|
||||
}
|
||||
code += addConstMem(loopvarDt, loopvarAddress.toUInt(), step)
|
||||
code += VmCodeInstruction(Opcode.LOADM, loopvarDt, reg1 = indexReg, value = loopvarAddress)
|
||||
code += if(rangeEndWrapped==0) {
|
||||
VmCodeInstruction(Opcode.BNZ, loopvarDt, reg1 = indexReg, labelSymbol = loopLabel)
|
||||
} else {
|
||||
@ -381,18 +367,13 @@ class CodeGen(internal val program: PtProgram,
|
||||
}
|
||||
else -> {
|
||||
val valueReg = vmRegisters.nextFree()
|
||||
val operandReg = vmRegisters.nextFree()
|
||||
if(value>0) {
|
||||
code += VmCodeInstruction(Opcode.LOADM, dt, reg1=valueReg, value=address.toInt())
|
||||
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=operandReg, value=value)
|
||||
code += VmCodeInstruction(Opcode.ADDR, dt, reg1 = valueReg, reg2 = operandReg) // TODO USE ADDM?
|
||||
code += VmCodeInstruction(Opcode.STOREM, dt, reg1=valueReg, value=address.toInt())
|
||||
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=valueReg, value=value)
|
||||
code += VmCodeInstruction(Opcode.ADDM, dt, reg1=valueReg, value=address.toInt())
|
||||
}
|
||||
else {
|
||||
code += VmCodeInstruction(Opcode.LOADM, dt, reg1=valueReg, value=address.toInt())
|
||||
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=operandReg, value=-value)
|
||||
code += VmCodeInstruction(Opcode.SUBR, dt, reg1 = valueReg, reg2 = operandReg) // TODO USE ADDM?
|
||||
code += VmCodeInstruction(Opcode.STOREM, dt, reg1=valueReg, value=address.toInt())
|
||||
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=valueReg, value=-value)
|
||||
code += VmCodeInstruction(Opcode.SUBM, dt, reg1=valueReg, value=address.toInt())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -172,6 +172,7 @@ class VmPeepholeOptimizer(private val vmprog: AssemblyProgram, private val alloc
|
||||
// TODO: detect multiple sequential rnd with same reg1, only keep one
|
||||
// TODO: detect subsequent same xors/nots/negs, remove the pairs completely as they cancel out
|
||||
// TODO: detect multiple same ands, ors; only keep first
|
||||
// TODO: (hard) detect multiple registers being assigned the same value (and not changed) - use only 1 of them
|
||||
// ...
|
||||
}
|
||||
return changed
|
||||
|
@ -3,9 +3,6 @@ TODO
|
||||
|
||||
For next release
|
||||
^^^^^^^^^^^^^^^^
|
||||
- fix the obvious TODOs in CodeGen (vm)
|
||||
- vm: AssignmentGen - fix in-place array assign TODO
|
||||
|
||||
...
|
||||
|
||||
|
||||
|
@ -2,27 +2,16 @@
|
||||
%zeropage basicsafe
|
||||
|
||||
main {
|
||||
romsub $ea31 = foobar(uword derp @AY) -> ubyte @A
|
||||
romsub $ea33 = foobar2() -> ubyte @A
|
||||
romsub $ea33 = foobar3()
|
||||
|
||||
sub subroutine(ubyte subroutineArg) -> ubyte {
|
||||
return subroutineArg+22
|
||||
}
|
||||
|
||||
asmsub asmsubje(uword arg @AY) -> ubyte @A {
|
||||
%asm {{
|
||||
rts
|
||||
return
|
||||
}}
|
||||
}
|
||||
|
||||
sub start() {
|
||||
ubyte @shared qq0 = subroutine(11)
|
||||
ubyte @shared qq1 = foobar(12345)
|
||||
ubyte @shared qq2 = foobar2()
|
||||
foobar3()
|
||||
ubyte[] arr = [1,2,3,4]
|
||||
uword pointer
|
||||
ubyte ix
|
||||
|
||||
txt.print_ub(qq0)
|
||||
arr[ix] = arr[ix]+1
|
||||
|
||||
; arr[3] = arr[3]+1
|
||||
; pointer[3] = pointer[3]+1
|
||||
|
||||
txt.print_ub(arr[3])
|
||||
}
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ add reg1, value - reg1 += value (unsigned + signed)
|
||||
addm reg1, address - memory at address += reg1 (unsigned + signed)
|
||||
subr reg1, reg2 - reg1 -= reg2 (unsigned + signed)
|
||||
sub reg1, value - reg1 -= value (unsigned + signed)
|
||||
subm reg1, address - memory at address -= reg2 (unsigned + signed)
|
||||
subm reg1, address - memory at address -= reg1 (unsigned + signed)
|
||||
mulr reg1, reg2 - unsigned multiply reg1 *= reg2 note: byte*byte->byte, no type extension to word!
|
||||
mul reg1, value - unsigned multiply reg1 *= value note: byte*byte->byte, no type extension to word!
|
||||
mulm reg1, address - memory at address *= reg2 note: byte*byte->byte, no type extension to word!
|
||||
|
Loading…
x
Reference in New Issue
Block a user