fix & of pointervar indexing

This commit is contained in:
Irmen de Jong 2024-02-08 22:45:36 +01:00
parent 6a48de9a9f
commit 68669dbef0
8 changed files with 95 additions and 57 deletions

View File

@ -665,6 +665,8 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
}
is PtAddressOf -> {
val mem = PtMemoryByte(fcall.position)
if((fcall.args[0] as PtAddressOf).isFromArrayElement)
TODO("address-of arrayelement")
if(msb) {
val address = PtBinaryExpression("+", DataType.UWORD, fcall.args[0].position)
address.add(fcall.args[0])

View File

@ -2522,67 +2522,87 @@ internal class AssignmentAsmGen(private val program: PtProgram,
}
private fun assignAddressOf(target: AsmAssignTarget, sourceName: String, arrayDt: DataType?, arrayIndexExpr: PtExpression?) {
val offset = if(arrayIndexExpr!=null) {
if(arrayIndexExpr!=null) {
require(arrayDt !in SplitWordArrayTypes)
val constIndex = arrayIndexExpr.asConstInteger()
if(constIndex!=null) {
if(arrayDt in SplitWordArrayTypes)
constIndex
else
program.memsizer.memorySize(arrayDt!!, constIndex) // add arrayIndexExpr * elementsize to the address of the array variable.
} else {
val eltSize = if(arrayDt==DataType.UWORD) 1 else program.memsizer.memorySize(ArrayToElementTypes.getValue(arrayDt!!))
assignExpressionToVariable(arrayIndexExpr, "P8ZP_SCRATCH_W1", DataType.UWORD)
when(eltSize) {
1 -> {}
2 -> {
if(arrayDt !in SplitWordArrayTypes)
asmgen.out(" asl P8ZP_SCRATCH_W1 | rol P8ZP_SCRATCH_W1+1")
}
else -> TODO("address-of array element $sourceName size $eltSize with non-const index at ${target.position}")
if (arrayDt == DataType.UWORD) {
assignVariableToRegister(sourceName, RegisterOrPair.AY, false, arrayIndexExpr.definingISub(), arrayIndexExpr.position)
if(constIndex>0)
asmgen.out("""
clc
adc #$constIndex
bne +
iny
+""")
}
else {
if(constIndex>0) {
val offset = program.memsizer.memorySize(arrayDt!!, constIndex) // add arrayIndexExpr * elementsize to the address of the array variable.
asmgen.out(" lda #<($sourceName + $offset) | ldy #>($sourceName + $offset)")
} else {
asmgen.out(" lda #<$sourceName | ldy #>$sourceName")
}
}
assignRegisterpairWord(target, RegisterOrPair.AY)
return
} else {
if (arrayDt == DataType.UWORD) {
assignVariableToRegister(sourceName, RegisterOrPair.AY, false, arrayIndexExpr.definingISub(), arrayIndexExpr.position)
asmgen.saveRegisterStack(CpuRegister.A, false)
asmgen.saveRegisterStack(CpuRegister.Y, false)
assignExpressionToVariable(arrayIndexExpr, "P8ZP_SCRATCH_REG", DataType.UBYTE)
asmgen.restoreRegisterStack(CpuRegister.Y, false)
asmgen.restoreRegisterStack(CpuRegister.A, false)
asmgen.out("""
clc
adc P8ZP_SCRATCH_REG
bne +
iny
+""")
}
else {
assignExpressionToRegister(arrayIndexExpr, RegisterOrPair.A, false)
asmgen.out("""
ldy #>$sourceName
clc
adc #<$sourceName
bne +
iny
+""")
}
asmgen.out("""
lda #<$sourceName
clc
adc P8ZP_SCRATCH_W1
tax
lda #>$sourceName
adc P8ZP_SCRATCH_W1+1
tay
txa""")
assignRegisterpairWord(target, RegisterOrPair.AY)
return
}
} else 0
}
// address of a normal variable
when(target.kind) {
TargetStorageKind.VARIABLE -> {
asmgen.out("""
lda #<$sourceName+$offset
ldy #>$sourceName+$offset
lda #<$sourceName
ldy #>$sourceName
sta ${target.asmVarname}
sty ${target.asmVarname}+1
""")
sty ${target.asmVarname}+1""")
}
TargetStorageKind.MEMORY -> {
throw AssemblyError("can't store word into memory byte")
}
TargetStorageKind.ARRAY -> {
asmgen.out(" lda #<$sourceName+$offset | ldy #>$sourceName+$offset")
asmgen.out(" lda #<$sourceName | ldy #>$sourceName")
assignRegisterpairWord(target, RegisterOrPair.AY)
}
TargetStorageKind.REGISTER -> {
when(target.register!!) {
RegisterOrPair.AX -> asmgen.out(" ldx #>$sourceName+$offset | lda #<$sourceName+$offset")
RegisterOrPair.AY -> asmgen.out(" ldy #>$sourceName+$offset | lda #<$sourceName+$offset")
RegisterOrPair.XY -> asmgen.out(" ldy #>$sourceName+$offset | ldx #<$sourceName+$offset")
RegisterOrPair.AX -> asmgen.out(" ldx #>$sourceName | lda #<$sourceName")
RegisterOrPair.AY -> asmgen.out(" ldy #>$sourceName | lda #<$sourceName")
RegisterOrPair.XY -> asmgen.out(" ldy #>$sourceName | ldx #<$sourceName")
in Cx16VirtualRegisters -> {
asmgen.out(
"""
lda #<$sourceName+$offset
asmgen.out("""
lda #<$sourceName
ldy #>$sourceName
sta cx16.${target.register.toString().lowercase()}
lda #>$sourceName+$offset
sta cx16.${target.register.toString().lowercase()}+1
""")
sty cx16.${target.register.toString().lowercase()}+1""")
}
else -> throw AssemblyError("can't load address in a single 8-bit register")
}

View File

@ -89,16 +89,13 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
val result = mutableListOf<IRCodeChunkBase>()
val resultRegister = codeGen.registers.nextFree()
if(expr.isFromArrayElement) {
require(expr.identifier.type !in SplitWordArrayTypes)
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) {
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)

View File

@ -604,10 +604,12 @@ internal class AstChecker(private val program: Program,
override fun visit(addressOf: AddressOf) {
checkLongType(addressOf)
val variable=addressOf.identifier.targetVarDecl(program)
if(variable!=null && variable.type==VarDeclType.CONST && addressOf.arrayIndex==null) errors.err(
"invalid pointer-of operand type",
addressOf.position
)
if (variable!=null) {
if (variable.type == VarDeclType.CONST && addressOf.arrayIndex == null)
errors.err("invalid pointer-of operand type",addressOf.position)
if (variable.splitArray)
errors.err("cannot take address of split word array",addressOf.position)
}
super.visit(addressOf)
}

View File

@ -533,11 +533,7 @@ class IntermediateAstMaker(private val program: Program, private val errors: IEr
private fun transform(src: AddressOf): PtAddressOf {
val addr = PtAddressOf(src.position)
val (name, dt) = src.identifier.targetNameAndType(program)
if(dt in SplitWordArrayTypes)
addr.add(PtIdentifier(name+"_lsb", dt, src.identifier.position)) // NOTE: assumes _lsb is first in memory! (immediately followed by _msb)
else
addr.add(transform(src.identifier))
addr.add(transform(src.identifier))
if(src.arrayIndex!=null)
addr.add(transformExpression(src.arrayIndex!!.indexExpr))
return addr

View File

@ -262,6 +262,13 @@ internal class StatementReorderer(
if(!errors.noErrors())
return noModifications
if(sourceVar.splitArray && targetVar.splitArray)
TODO("copy split to split array")
if(sourceVar.splitArray)
TODO("copy from split source array to normal")
if(targetVar.splitArray)
TODO("copy from normal to split source array")
val numelements = targetVar.arraysize!!.constIndex()!!
val eltsize = program.memsizer.memorySize(ArrayToElementTypes.getValue(sourceVar.datatype))
val memcopy = FunctionCallStatement(IdentifierReference(listOf("sys", "memcopy"), assign.position),

View File

@ -1,8 +1,8 @@
TODO
====
&pointervar[x] isn't the correct value (6502, IR is fixed)
@(s) where s is a str parameter, doesn't work
fix TODO's to assign from and to split arrays (StatementReorderer) -- cannot use simple single memcopy here (6502 + IR)
assembler, imageviewer is bigger than before (since commit "added string.lstripped() and string.ltrimmed()" )
(after merge in boolean): move all "OperatorXinplace" from expressionGen to AssignmentGen, see if we can get rid of the Result return type.

View File

@ -6,18 +6,28 @@
main {
sub start() {
foo("zzz")
str name1 = "name1"
str name2 = "name2"
uword[] @split names = [name1, name2, "name3"]
uword[] addresses = [0,0,0]
names = [1111,2222,3333]
addresses = names
;foo("zzz")
}
sub foo (str sarg) {
str svar = "irmen"
ubyte[3] svar
txt.print_uwhex(svar, true)
txt.nl()
txt.print_uwhex(&svar, true)
txt.nl()
txt.print_uwhex(&svar[2], true)
txt.nl()
cx16.r1L = 3
txt.print_uwhex(&svar[cx16.r1L], true)
txt.nl()
txt.nl()
txt.print_uwhex(sarg, true)
txt.nl()
txt.print_uwhex(&sarg, true)
@ -27,5 +37,9 @@ main {
cx16.r0 = &sarg[2]
txt.print_uwhex(cx16.r0, true) ; TODO should be the same as the previous one sarg+2 (13)!
txt.nl()
cx16.r1L=3
cx16.r0 = &sarg[cx16.r1L]
txt.print_uwhex(cx16.r0, true) ; TODO should be the same as the previous one sarg+2 (13)!
txt.nl()
}
}