mirror of
https://github.com/irmen/prog8.git
synced 2024-06-11 11:29:31 +00:00
fix & of pointervar indexing
This commit is contained in:
parent
6a48de9a9f
commit
68669dbef0
|
@ -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])
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user