mirror of
https://github.com/irmen/prog8.git
synced 2024-11-25 19:31:36 +00:00
IR: fix & of array-element
This commit is contained in:
parent
9d6d98930b
commit
6a48de9a9f
@ -154,6 +154,8 @@ private fun PtVariable.prefix(st: SymbolTable): PtVariable {
|
||||
else {
|
||||
val newAddr = PtAddressOf(elt.position)
|
||||
newAddr.children.add(elt.identifier.prefix(newAddr, st))
|
||||
if(elt.arrayIndexExpr!=null)
|
||||
newAddr.children.add(elt.arrayIndexExpr!!)
|
||||
newAddr.parent = arrayValue
|
||||
newValue.add(newAddr)
|
||||
}
|
||||
|
@ -66,33 +66,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
ExpressionCodeResult(code, vmDt, resultRegister, -1)
|
||||
}
|
||||
}
|
||||
is PtAddressOf -> {
|
||||
val vmDt = irType(expr.type)
|
||||
val symbol = expr.identifier.name
|
||||
// note: LOAD <symbol> gets you the address of the symbol, whereas LOADM <symbol> would get you the value stored at that location
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val resultRegister = codeGen.registers.nextFree()
|
||||
addInstr(result, IRInstruction(Opcode.LOAD, vmDt, reg1 = resultRegister, labelSymbol = symbol), null)
|
||||
if(expr.isFromArrayElement) {
|
||||
val indexTr = translateExpression(expr.arrayIndexExpr!!)
|
||||
addToResult(result, indexTr, indexTr.resultReg, -1)
|
||||
if(expr.identifier.type in SplitWordArrayTypes) {
|
||||
result += IRCodeChunk(null, null).also {
|
||||
// multiply indexTr resultreg by the eltSize and add this to the resultRegister.
|
||||
it += IRInstruction(Opcode.ADDR, IRDataType.BYTE, reg1=resultRegister, reg2=indexTr.resultReg)
|
||||
}
|
||||
} else {
|
||||
val eltSize = codeGen.program.memsizer.memorySize(expr.identifier.type, 1)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
// multiply indexTr resultreg by the eltSize and add this to the resultRegister.
|
||||
if(eltSize>1)
|
||||
it += IRInstruction(Opcode.MUL, IRDataType.BYTE, reg1=indexTr.resultReg, immediate = eltSize)
|
||||
it += IRInstruction(Opcode.ADDR, IRDataType.BYTE, reg1=resultRegister, reg2=indexTr.resultReg)
|
||||
}
|
||||
}
|
||||
}
|
||||
ExpressionCodeResult(result, vmDt, resultRegister, -1)
|
||||
}
|
||||
is PtAddressOf -> translate(expr)
|
||||
is PtMemoryByte -> translate(expr)
|
||||
is PtTypeCast -> translate(expr)
|
||||
is PtPrefix -> translate(expr)
|
||||
@ -108,6 +82,44 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun translate(expr: PtAddressOf): ExpressionCodeResult {
|
||||
val vmDt = irType(expr.type)
|
||||
val symbol = expr.identifier.name
|
||||
// note: LOAD <symbol> gets you the address of the symbol, whereas LOADM <symbol> would get you the value stored at that location
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val resultRegister = codeGen.registers.nextFree()
|
||||
if(expr.isFromArrayElement) {
|
||||
addInstr(result, IRInstruction(Opcode.LOAD, vmDt, reg1 = resultRegister, labelSymbol = symbol), null)
|
||||
val indexTr2 = translateExpression(expr.arrayIndexExpr!!)
|
||||
addToResult(result, indexTr2, indexTr2.resultReg, -1)
|
||||
val indexWordReg = codeGen.registers.nextFree()
|
||||
addInstr(result, IRInstruction(Opcode.EXT, IRDataType.BYTE, reg1=indexWordReg, reg2=indexTr2.resultReg), null)
|
||||
if(expr.identifier.type in SplitWordArrayTypes) {
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.ADDR, IRDataType.WORD, reg1=resultRegister, reg2=indexWordReg)
|
||||
}
|
||||
} else if(expr.identifier.type == DataType.UWORD) {
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOADM, vmDt, reg1 = resultRegister, labelSymbol = symbol)
|
||||
it += IRInstruction(Opcode.ADDR, IRDataType.WORD, reg1=resultRegister, reg2=indexWordReg)
|
||||
}
|
||||
} else {
|
||||
val eltSize = codeGen.program.memsizer.memorySize(expr.identifier.type, 1)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
// multiply indexTr resultreg by the eltSize and add this to the resultRegister.
|
||||
it += IRInstruction(Opcode.LOAD, vmDt, reg1 = resultRegister, labelSymbol = symbol)
|
||||
if(eltSize>1) {
|
||||
it += IRInstruction(Opcode.MUL, IRDataType.WORD, reg1=indexWordReg, immediate = eltSize)
|
||||
}
|
||||
it += IRInstruction(Opcode.ADDR, IRDataType.WORD, reg1=resultRegister, reg2=indexWordReg)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
addInstr(result, IRInstruction(Opcode.LOAD, vmDt, reg1 = resultRegister, labelSymbol = symbol), null)
|
||||
}
|
||||
return ExpressionCodeResult(result, vmDt, resultRegister, -1)
|
||||
}
|
||||
|
||||
private fun translate(mem: PtMemoryByte): ExpressionCodeResult {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val resultRegister = codeGen.registers.nextFree()
|
||||
|
@ -1,7 +1,7 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
&pointervar[x] isn't the correct value
|
||||
&pointervar[x] isn't the correct value (6502, IR is fixed)
|
||||
@(s) where s is a str parameter, doesn't work
|
||||
|
||||
(after merge in boolean): move all "OperatorXinplace" from expressionGen to AssignmentGen, see if we can get rid of the Result return type.
|
||||
|
@ -9,22 +9,23 @@ main {
|
||||
foo("zzz")
|
||||
}
|
||||
|
||||
sub foo (str s2) {
|
||||
str s = "irmen"
|
||||
txt.print_uwhex(s, true)
|
||||
sub foo (str sarg) {
|
||||
str svar = "irmen"
|
||||
txt.print_uwhex(svar, true)
|
||||
txt.nl()
|
||||
txt.print_uwhex(&s, true)
|
||||
txt.print_uwhex(&svar, true)
|
||||
txt.nl()
|
||||
txt.print_uwhex(&s[2], true)
|
||||
txt.print_uwhex(&svar[2], true)
|
||||
txt.nl()
|
||||
txt.nl()
|
||||
txt.print_uwhex(s2, true)
|
||||
txt.print_uwhex(sarg, true)
|
||||
txt.nl()
|
||||
txt.print_uwhex(&s2, true)
|
||||
txt.print_uwhex(&sarg, true)
|
||||
txt.nl()
|
||||
txt.print_uwhex(s2+2, true)
|
||||
txt.print_uwhex(sarg+2, true)
|
||||
txt.nl()
|
||||
txt.print_uwhex(&s2[2], true) ; TODO should be the same as the previous one!
|
||||
cx16.r0 = &sarg[2]
|
||||
txt.print_uwhex(cx16.r0, true) ; TODO should be the same as the previous one sarg+2 (13)!
|
||||
txt.nl()
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user