mirror of
https://github.com/irmen/prog8.git
synced 2025-01-14 01:29:55 +00:00
vm: fix codegen for storing to pointer indexed
This commit is contained in:
parent
f70b914779
commit
0a3cd652b0
codeGenVirtual/src/prog8/codegen/virtual
compiler/src/prog8/compiler/astprocessing
docs/source
examples
virtualmachine/src/prog8/vm
@ -168,7 +168,7 @@ internal class AssignmentGen(private val codeGen: CodeGen, private val expressio
|
||||
throw AssemblyError("non-array var indexing requires bytes index")
|
||||
val idxReg = codeGen.vmRegisters.nextFree()
|
||||
code += expressionEval.translateExpression(array.index, idxReg, -1)
|
||||
code += VmCodeInstruction(Opcode.LOADIX, vmDt, reg1=resultRegister, reg2=idxReg, value = variableAddr)
|
||||
code += VmCodeInstruction(Opcode.STOREIX, vmDt, reg1=resultRegister, reg2=idxReg, value = variableAddr)
|
||||
return code
|
||||
}
|
||||
|
||||
|
@ -42,10 +42,10 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen:
|
||||
"sort" -> funcSort(call)
|
||||
"reverse" -> funcReverse(call)
|
||||
"swap" -> funcSwap(call)
|
||||
"rol" -> funcRolRor2(Opcode.ROXL, call, resultRegister)
|
||||
"ror" -> funcRolRor2(Opcode.ROXR, call, resultRegister)
|
||||
"rol2" -> funcRolRor2(Opcode.ROL, call, resultRegister)
|
||||
"ror2" -> funcRolRor2(Opcode.ROR, call, resultRegister)
|
||||
"rol" -> funcRolRor(Opcode.ROXL, call, resultRegister)
|
||||
"ror" -> funcRolRor(Opcode.ROXR, call, resultRegister)
|
||||
"rol2" -> funcRolRor(Opcode.ROL, call, resultRegister)
|
||||
"ror2" -> funcRolRor(Opcode.ROR, call, resultRegister)
|
||||
else -> TODO("builtinfunc ${call.name}")
|
||||
}
|
||||
}
|
||||
@ -368,7 +368,7 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen:
|
||||
return code
|
||||
}
|
||||
|
||||
private fun funcRolRor2(opcode: Opcode, call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
|
||||
private fun funcRolRor(opcode: Opcode, call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
|
||||
val vmDt = codeGen.vmType(call.args[0].type)
|
||||
val code = VmCodeChunk()
|
||||
code += exprGen.translateExpression(call.args[0], resultRegister, -1)
|
||||
|
@ -50,17 +50,14 @@ internal class AstOnetimeTransforms(private val program: Program, private val op
|
||||
} else {
|
||||
val fcall = parent as? IFunctionCall
|
||||
if(fcall!=null) {
|
||||
// TODO for now, codegen seems wrong when using pointer indexed args to an in-place modifying function.
|
||||
if(fcall.target.nameInSource.size==1 && fcall.target.nameInSource[0] in InplaceModifyingBuiltinFunctions) {
|
||||
// TODO currently, 6502 codegen is wrong when using pointer indexed args to an in-place modifying function.
|
||||
if(options.compTarget.name!=VMTarget.NAME
|
||||
&& fcall.target.nameInSource.size==1
|
||||
&& fcall.target.nameInSource[0] in InplaceModifyingBuiltinFunctions) {
|
||||
val memread = DirectMemoryRead(add, arrayIndexedExpression.position)
|
||||
return listOf(IAstModification.ReplaceNode(arrayIndexedExpression, memread, parent))
|
||||
} else {
|
||||
return noModifications
|
||||
}
|
||||
}
|
||||
else {
|
||||
return noModifications
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@ TODO
|
||||
|
||||
For next release
|
||||
^^^^^^^^^^^^^^^^
|
||||
- optimize pointervar indexing codegen: make them work as params to in-place modifying functions (rol, swap, ...)
|
||||
- optimize pointervar indexing codegen: fix 6502 codegen for params to in-place modifying functions (rol, swap, ...)
|
||||
- optimize pointervar indexing codegen: writing (all sorts of things)
|
||||
- pipe operator: (targets other than 'Virtual'): allow non-unary function calls in the pipe that specify the other argument(s) in the calls. Already working for VM target.
|
||||
- add McCarthy evaluation to shortcircuit and/or expressions. First do ifs by splitting them up? Then do expressions that compute a value?
|
||||
|
123
examples/test.p8
123
examples/test.p8
@ -29,22 +29,6 @@ main {
|
||||
; txt.spc()
|
||||
; }
|
||||
|
||||
; sub derp(ubyte u1, ubyte u2, ubyte u3) {
|
||||
; txt.print_ub(u1)
|
||||
; txt.spc()
|
||||
; txt.print_ub(u2)
|
||||
; txt.spc()
|
||||
; txt.print_ub(u3)
|
||||
; txt.nl()
|
||||
; }
|
||||
|
||||
sub derp2(ubyte u1, ubyte u2) {
|
||||
txt.print_ub(u1)
|
||||
txt.spc()
|
||||
txt.print_ub(u2)
|
||||
txt.nl()
|
||||
}
|
||||
|
||||
sub start() {
|
||||
; mcCarthy()
|
||||
;test_stack.test()
|
||||
@ -55,66 +39,55 @@ main {
|
||||
ubyte[10] data = [11,22,33,4,5,6,7,8,9,10]
|
||||
uword bitmapbuf = &data
|
||||
|
||||
;derp(data[0],data[1],data[2])
|
||||
;derp(bitmapbuf[0], bitmapbuf[1], bitmapbuf[2])
|
||||
derp2(1,2)
|
||||
derp2(one, two)
|
||||
derp2(data[1], data[2])
|
||||
derp2(bitmapbuf[1], bitmapbuf[2])
|
||||
; 11 22 33
|
||||
txt.print_ub(bitmapbuf[0])
|
||||
txt.spc()
|
||||
txt.print_ub(bitmapbuf[1])
|
||||
txt.spc()
|
||||
txt.print_ub(bitmapbuf[2])
|
||||
txt.nl()
|
||||
rol(bitmapbuf[0])
|
||||
rol(bitmapbuf[0])
|
||||
txt.print_ub(bitmapbuf[0]) ; 44
|
||||
txt.spc()
|
||||
ror(bitmapbuf[0])
|
||||
ror(bitmapbuf[0])
|
||||
txt.print_ub(bitmapbuf[0]) ; 11
|
||||
txt.nl()
|
||||
|
||||
; value = bitmapbuf[2]
|
||||
; txt.print_ub(value) ;; 33
|
||||
; txt.nl()
|
||||
;
|
||||
; ; 11 22 33
|
||||
; txt.print_ub(bitmapbuf[0])
|
||||
; txt.spc()
|
||||
; txt.print_ub(bitmapbuf[1])
|
||||
; txt.spc()
|
||||
; txt.print_ub(bitmapbuf[2])
|
||||
; txt.nl()
|
||||
; rol(bitmapbuf[0])
|
||||
; rol(bitmapbuf[0])
|
||||
; txt.print_ub(bitmapbuf[0]) ; 44
|
||||
; txt.spc()
|
||||
; ror(bitmapbuf[0])
|
||||
; ror(bitmapbuf[0])
|
||||
; txt.print_ub(bitmapbuf[0]) ; 11
|
||||
; txt.nl()
|
||||
;
|
||||
; ; 22 44 66
|
||||
; txt.print_ub(bitmapbuf[0]*2)
|
||||
; txt.spc()
|
||||
; txt.print_ub(bitmapbuf[1]*2)
|
||||
; txt.spc()
|
||||
; txt.print_ub(bitmapbuf[2]*2)
|
||||
; txt.nl()
|
||||
;
|
||||
; value = one+one+one+one+one
|
||||
; txt.print_ub(value) ; 5
|
||||
; txt.nl()
|
||||
;
|
||||
; bitmapbuf[0] = one
|
||||
; bitmapbuf[1] = one+one
|
||||
; bitmapbuf[2] = one+one+one
|
||||
; bitmapbuf[2] += 4
|
||||
; bitmapbuf[2] -= 2
|
||||
; bitmapbuf[2] -= 2
|
||||
; swap(bitmapbuf[0], bitmapbuf[1])
|
||||
;
|
||||
; ; 2 1 3
|
||||
; txt.print_ub(bitmapbuf[0])
|
||||
; txt.spc()
|
||||
; txt.print_ub(bitmapbuf[1])
|
||||
; txt.spc()
|
||||
; txt.print_ub(bitmapbuf[2])
|
||||
; txt.nl()
|
||||
;
|
||||
; for value in data {
|
||||
; txt.print_ub(value)
|
||||
; txt.spc()
|
||||
; }
|
||||
; txt.nl()
|
||||
; 22 44 66
|
||||
txt.print_ub(bitmapbuf[0]*2)
|
||||
txt.spc()
|
||||
txt.print_ub(bitmapbuf[1]*2)
|
||||
txt.spc()
|
||||
txt.print_ub(bitmapbuf[2]*2)
|
||||
txt.nl()
|
||||
|
||||
value = one+one+one+one+one
|
||||
txt.print_ub(value) ; 5
|
||||
txt.nl()
|
||||
|
||||
bitmapbuf[0] = one
|
||||
bitmapbuf[1] = one+one
|
||||
bitmapbuf[2] = one+one+one
|
||||
bitmapbuf[2] += 4
|
||||
bitmapbuf[2] -= 2
|
||||
bitmapbuf[2] -= 2
|
||||
swap(bitmapbuf[0], bitmapbuf[1])
|
||||
|
||||
; 2 1 3
|
||||
txt.print_ub(bitmapbuf[0])
|
||||
txt.spc()
|
||||
txt.print_ub(bitmapbuf[1])
|
||||
txt.spc()
|
||||
txt.print_ub(bitmapbuf[2])
|
||||
txt.nl()
|
||||
|
||||
for value in data {
|
||||
txt.print_ub(value)
|
||||
txt.spc()
|
||||
}
|
||||
txt.nl()
|
||||
|
||||
;test_stack.test()
|
||||
|
||||
|
@ -31,6 +31,7 @@ loadr reg1, reg2 - load reg1 with value in register reg2
|
||||
storem reg1, address - store reg1 at memory address
|
||||
storei reg1, reg2 - store reg1 at memory indirect, memory pointed to by reg2
|
||||
storex reg1, reg2, address - store reg1 at memory address, indexed by value in reg2
|
||||
storeix reg1, reg2, pointeraddr - store reg1 at memory indirect, pointed to by pointeraddr indexed by value in reg2
|
||||
storezm address - store zero at memory address
|
||||
storezi reg1 - store zero at memory pointed to by reg1
|
||||
storezx reg1, address - store zero at memory address, indexed by value in reg
|
||||
@ -190,6 +191,7 @@ enum class Opcode {
|
||||
STOREM,
|
||||
STOREI,
|
||||
STOREX,
|
||||
STOREIX,
|
||||
STOREZM,
|
||||
STOREZI,
|
||||
STOREZX,
|
||||
@ -489,7 +491,8 @@ val instructionFormats = mutableMapOf(
|
||||
Opcode.STOREM to InstructionFormat.from("BW,r1,v | F,fr1,v"),
|
||||
Opcode.STOREI to InstructionFormat.from("BW,r1,r2 | F,fr1,r1"),
|
||||
Opcode.STOREX to InstructionFormat.from("BW,r1,r2,v | F,fr1,r1,v"),
|
||||
Opcode.STOREZM to InstructionFormat.from("BW,v | F,v"),
|
||||
Opcode.STOREIX to InstructionFormat.from("BW,r1,r2,v | F,fr1,r1,v"),
|
||||
Opcode.STOREZM to InstructionFormat.from("BW,v | F,v"),
|
||||
Opcode.STOREZI to InstructionFormat.from("BW,r1 | F,r1"),
|
||||
Opcode.STOREZX to InstructionFormat.from("BW,r1,v | F,r1,v"),
|
||||
Opcode.JUMP to InstructionFormat.from("N,v"),
|
||||
|
@ -95,6 +95,7 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
|
||||
Opcode.LOADR -> InsLOADR(ins)
|
||||
Opcode.STOREM -> InsSTOREM(ins)
|
||||
Opcode.STOREX -> InsSTOREX(ins)
|
||||
Opcode.STOREIX -> InsSTOREIX(ins)
|
||||
Opcode.STOREI -> InsSTOREI(ins)
|
||||
Opcode.STOREZM -> InsSTOREZM(ins)
|
||||
Opcode.STOREZX -> InsSTOREZX(ins)
|
||||
@ -363,6 +364,24 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
|
||||
pc++
|
||||
}
|
||||
|
||||
private fun InsSTOREIX(i: Instruction) {
|
||||
when (i.type!!) {
|
||||
VmDataType.BYTE -> {
|
||||
val pointer = memory.getUW(i.value!!) + registers.getUB(i.reg2!!)
|
||||
memory.setUB(pointer.toInt(), registers.getUB(i.reg1!!))
|
||||
}
|
||||
VmDataType.WORD -> {
|
||||
val pointer = memory.getUW(i.value!!) + registers.getUB(i.reg2!!)
|
||||
memory.setUW(pointer.toInt(), registers.getUW(i.reg1!!))
|
||||
}
|
||||
VmDataType.FLOAT -> {
|
||||
val pointer = memory.getUW(i.value!!) + registers.getUB(i.reg1!!)
|
||||
memory.setFloat(pointer.toInt(), registers.getFloat(i.fpReg1!!))
|
||||
}
|
||||
}
|
||||
pc++
|
||||
}
|
||||
|
||||
private fun InsSTOREZM(i: Instruction) {
|
||||
when(i.type!!) {
|
||||
VmDataType.BYTE -> memory.setUB(i.value!!, 0u)
|
||||
|
Loading…
x
Reference in New Issue
Block a user