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
|
package prog8.codegen.virtual
|
||||||
|
|
||||||
import prog8.code.ast.*
|
import prog8.code.ast.*
|
||||||
import prog8.code.core.AssemblyError
|
import prog8.code.core.*
|
||||||
import prog8.code.core.DataType
|
|
||||||
import prog8.code.core.SignedDatatypes
|
|
||||||
import prog8.vm.Opcode
|
import prog8.vm.Opcode
|
||||||
import prog8.vm.VmDataType
|
import prog8.vm.VmDataType
|
||||||
|
|
||||||
@ -33,7 +31,9 @@ internal class AssignmentGen(private val codeGen: CodeGen, private val expressio
|
|||||||
else
|
else
|
||||||
fallbackAssign(assignment)
|
fallbackAssign(assignment)
|
||||||
} else if(array!=null) {
|
} 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)
|
fallbackAssign(assignment)
|
||||||
} else {
|
} else {
|
||||||
fallbackAssign(assignment)
|
fallbackAssign(assignment)
|
||||||
|
@ -275,15 +275,8 @@ class CodeGen(internal val program: PtProgram,
|
|||||||
code += VmCodeInstruction(Opcode.STOREM, loopvarDt, reg1=indexReg, value=loopvarAddress)
|
code += VmCodeInstruction(Opcode.STOREM, loopvarDt, reg1=indexReg, value=loopvarAddress)
|
||||||
code += VmCodeLabel(loopLabel)
|
code += VmCodeLabel(loopLabel)
|
||||||
code += translateNode(forLoop.statements)
|
code += translateNode(forLoop.statements)
|
||||||
if(step<3) {
|
|
||||||
code += addConstMem(loopvarDt, loopvarAddress.toUInt(), step)
|
code += addConstMem(loopvarDt, loopvarAddress.toUInt(), step)
|
||||||
code += VmCodeInstruction(Opcode.LOADM, loopvarDt, reg1 = indexReg, value = loopvarAddress)
|
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)
|
|
||||||
}
|
|
||||||
val branchOpcode = if(loopvar.dt in SignedDatatypes) Opcode.BLES else Opcode.BLE
|
val branchOpcode = if(loopvar.dt in SignedDatatypes) Opcode.BLES else Opcode.BLE
|
||||||
code += VmCodeInstruction(branchOpcode, loopvarDt, reg1=indexReg, reg2=endvalueReg, labelSymbol=loopLabel)
|
code += VmCodeInstruction(branchOpcode, loopvarDt, reg1=indexReg, reg2=endvalueReg, labelSymbol=loopLabel)
|
||||||
return code
|
return code
|
||||||
@ -315,15 +308,8 @@ class CodeGen(internal val program: PtProgram,
|
|||||||
code += VmCodeInstruction(Opcode.STOREM, loopvarDt, reg1=indexReg, value=loopvarAddress)
|
code += VmCodeInstruction(Opcode.STOREM, loopvarDt, reg1=indexReg, value=loopvarAddress)
|
||||||
code += VmCodeLabel(loopLabel)
|
code += VmCodeLabel(loopLabel)
|
||||||
code += translateNode(forLoop.statements)
|
code += translateNode(forLoop.statements)
|
||||||
if(step<3) {
|
|
||||||
code += addConstMem(loopvarDt, loopvarAddress.toUInt(), step)
|
code += addConstMem(loopvarDt, loopvarAddress.toUInt(), step)
|
||||||
code += VmCodeInstruction(Opcode.LOADM, loopvarDt, reg1 = indexReg, value = loopvarAddress)
|
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 += if(rangeEndWrapped==0) {
|
code += if(rangeEndWrapped==0) {
|
||||||
VmCodeInstruction(Opcode.BNZ, loopvarDt, reg1 = indexReg, labelSymbol = loopLabel)
|
VmCodeInstruction(Opcode.BNZ, loopvarDt, reg1 = indexReg, labelSymbol = loopLabel)
|
||||||
} else {
|
} else {
|
||||||
@ -381,18 +367,13 @@ class CodeGen(internal val program: PtProgram,
|
|||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
val valueReg = vmRegisters.nextFree()
|
val valueReg = vmRegisters.nextFree()
|
||||||
val operandReg = vmRegisters.nextFree()
|
|
||||||
if(value>0) {
|
if(value>0) {
|
||||||
code += VmCodeInstruction(Opcode.LOADM, dt, reg1=valueReg, value=address.toInt())
|
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=valueReg, value=value)
|
||||||
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=operandReg, value=value)
|
code += VmCodeInstruction(Opcode.ADDM, dt, reg1=valueReg, value=address.toInt())
|
||||||
code += VmCodeInstruction(Opcode.ADDR, dt, reg1 = valueReg, reg2 = operandReg) // TODO USE ADDM?
|
|
||||||
code += VmCodeInstruction(Opcode.STOREM, dt, reg1=valueReg, value=address.toInt())
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
code += VmCodeInstruction(Opcode.LOADM, dt, reg1=valueReg, value=address.toInt())
|
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=valueReg, value=-value)
|
||||||
code += VmCodeInstruction(Opcode.LOAD, dt, reg1=operandReg, value=-value)
|
code += VmCodeInstruction(Opcode.SUBM, dt, reg1=valueReg, value=address.toInt())
|
||||||
code += VmCodeInstruction(Opcode.SUBR, dt, reg1 = valueReg, reg2 = operandReg) // TODO USE ADDM?
|
|
||||||
code += VmCodeInstruction(Opcode.STOREM, 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 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 subsequent same xors/nots/negs, remove the pairs completely as they cancel out
|
||||||
// TODO: detect multiple same ands, ors; only keep first
|
// 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
|
return changed
|
||||||
|
@ -3,9 +3,6 @@ TODO
|
|||||||
|
|
||||||
For next release
|
For next release
|
||||||
^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^
|
||||||
- fix the obvious TODOs in CodeGen (vm)
|
|
||||||
- vm: AssignmentGen - fix in-place array assign TODO
|
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,27 +2,16 @@
|
|||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
|
|
||||||
main {
|
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() {
|
sub start() {
|
||||||
ubyte @shared qq0 = subroutine(11)
|
ubyte[] arr = [1,2,3,4]
|
||||||
ubyte @shared qq1 = foobar(12345)
|
uword pointer
|
||||||
ubyte @shared qq2 = foobar2()
|
ubyte ix
|
||||||
foobar3()
|
|
||||||
|
|
||||||
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)
|
addm reg1, address - memory at address += reg1 (unsigned + signed)
|
||||||
subr reg1, reg2 - reg1 -= reg2 (unsigned + signed)
|
subr reg1, reg2 - reg1 -= reg2 (unsigned + signed)
|
||||||
sub reg1, value - reg1 -= value (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!
|
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!
|
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!
|
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