mirror of
https://github.com/irmen/prog8.git
synced 2024-11-16 22:09:56 +00:00
getting rid of pointer[idx] in ast, instead always use @(ptr+idx)
This commit is contained in:
parent
ef79d0c43e
commit
b0f5b6925d
@ -138,16 +138,16 @@ class PtAddressOf(position: Position) : PtExpression(DataType.UWORD, position) {
|
||||
|
||||
class PtArrayIndexer(elementType: DataType, position: Position): PtExpression(elementType, position) {
|
||||
val variable: PtIdentifier
|
||||
get() = children[0] as PtIdentifier
|
||||
get() {
|
||||
require((children[0] as? PtIdentifier)?.type in ArrayDatatypes+DataType.STR) // TODO remove
|
||||
return children[0] as PtIdentifier
|
||||
}
|
||||
val index: PtExpression
|
||||
get() = children[1] as PtExpression
|
||||
|
||||
val splitWords: Boolean
|
||||
get() = variable.type in SplitWordArrayTypes
|
||||
|
||||
val usesPointerVariable: Boolean
|
||||
get() = variable.type==DataType.UWORD
|
||||
|
||||
init {
|
||||
require(elementType in NumericDatatypes)
|
||||
}
|
||||
|
@ -677,7 +677,6 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
}
|
||||
is PtArrayIndexer -> {
|
||||
val indexer = fcall.args[0] as PtArrayIndexer
|
||||
require(!indexer.usesPointerVariable)
|
||||
val elementSize: Int
|
||||
val msbAdd: Int
|
||||
if(indexer.splitWords) {
|
||||
@ -846,8 +845,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
}
|
||||
else -> {
|
||||
val tempvar = asmgen.getTempVarName(DataType.FLOAT)
|
||||
asmgen.assignExpressionTo(fcall.args[1],
|
||||
AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.FLOAT, fcall.definingISub(), fcall.position, tempvar, null, null, null, null))
|
||||
asmgen.assignExpressionToVariable(fcall.args[1], tempvar, DataType.FLOAT)
|
||||
asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.AY)
|
||||
asmgen.out("""
|
||||
pha
|
||||
|
@ -91,22 +91,7 @@ internal class PostIncrDecrAsmGen(private val program: PtProgram, private val as
|
||||
val indexValue = constIndex * program.memsizer.memorySize(elementDt)
|
||||
when(elementDt) {
|
||||
in ByteDatatypes -> {
|
||||
if(targetArrayIdx.usesPointerVariable) {
|
||||
asmgen.out("""
|
||||
lda $asmArrayvarname
|
||||
clc
|
||||
adc #$indexValue
|
||||
sta (+) +1
|
||||
lda $asmArrayvarname+1
|
||||
adc #0
|
||||
sta (+) +2""")
|
||||
if(incr)
|
||||
asmgen.out("+\tinc ${'$'}ffff\t; modified")
|
||||
else
|
||||
asmgen.out("+\tdec ${'$'}ffff\t; modified")
|
||||
} else {
|
||||
asmgen.out(if (incr) " inc $asmArrayvarname+$indexValue" else " dec $asmArrayvarname+$indexValue")
|
||||
}
|
||||
asmgen.out(if (incr) " inc $asmArrayvarname+$indexValue" else " dec $asmArrayvarname+$indexValue")
|
||||
}
|
||||
in WordDatatypes -> {
|
||||
if(incr)
|
||||
@ -130,22 +115,7 @@ internal class PostIncrDecrAsmGen(private val program: PtProgram, private val as
|
||||
asmgen.loadScaledArrayIndexIntoRegister(targetArrayIdx, CpuRegister.X)
|
||||
when(elementDt) {
|
||||
in ByteDatatypes -> {
|
||||
if(targetArrayIdx.usesPointerVariable) {
|
||||
asmgen.out("""
|
||||
txa
|
||||
clc
|
||||
adc $asmArrayvarname
|
||||
sta (+) +1
|
||||
lda $asmArrayvarname+1
|
||||
adc #0
|
||||
sta (+) +2""")
|
||||
if(incr)
|
||||
asmgen.out("+\tinc ${'$'}ffff\t; modified")
|
||||
else
|
||||
asmgen.out("+\tdec ${'$'}ffff\t; modified")
|
||||
} else {
|
||||
asmgen.out(if (incr) " inc $asmArrayvarname,x" else " dec $asmArrayvarname,x")
|
||||
}
|
||||
asmgen.out(if (incr) " inc $asmArrayvarname,x" else " dec $asmArrayvarname,x")
|
||||
}
|
||||
in WordDatatypes -> {
|
||||
if(incr)
|
||||
|
@ -64,32 +64,6 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
val value = assign.source.array!!
|
||||
val elementDt = assign.source.datatype
|
||||
val arrayVarName = asmgen.asmVariableName(value.variable)
|
||||
|
||||
if(value.usesPointerVariable) {
|
||||
if(elementDt !in ByteDatatypes)
|
||||
throw AssemblyError("non-array var indexing requires bytes dt")
|
||||
if(value.type != DataType.UBYTE)
|
||||
throw AssemblyError("non-array var indexing requires bytes index")
|
||||
if(asmgen.isTargetCpu(CpuType.CPU65c02) && (value.index as? PtNumber)?.number==0.0) {
|
||||
if (asmgen.isZpVar(value.variable)) {
|
||||
asmgen.out(" lda ($arrayVarName)")
|
||||
} else {
|
||||
asmgen.out(" lda $arrayVarName | sta P8ZP_SCRATCH_W1 | lda $arrayVarName+1 | sta P8ZP_SCRATCH_W1+1")
|
||||
asmgen.out(" lda (P8ZP_SCRATCH_W1)")
|
||||
}
|
||||
} else {
|
||||
asmgen.loadScaledArrayIndexIntoRegister(value, CpuRegister.Y)
|
||||
if (asmgen.isZpVar(value.variable)) {
|
||||
asmgen.out(" lda ($arrayVarName),y")
|
||||
} else {
|
||||
asmgen.out(" lda $arrayVarName | sta P8ZP_SCRATCH_W1 | lda $arrayVarName+1 | sta P8ZP_SCRATCH_W1+1")
|
||||
asmgen.out(" lda (P8ZP_SCRATCH_W1),y")
|
||||
}
|
||||
}
|
||||
assignRegisterByte(assign.target, CpuRegister.A, elementDt in SignedDatatypes, false)
|
||||
return
|
||||
}
|
||||
|
||||
val constIndex = value.index.asConstInteger()
|
||||
|
||||
if(value.splitWords) {
|
||||
@ -805,26 +779,11 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
if(!rightArrayIndexer.index.isSimple()) asmgen.out(" pha")
|
||||
asmgen.assignExpressionToRegister(rightArrayIndexer.index, RegisterOrPair.Y, false)
|
||||
if(!rightArrayIndexer.index.isSimple()) asmgen.out(" pla")
|
||||
if(rightArrayIndexer.usesPointerVariable && !asmgen.isZpVar(rightArrayIndexer.variable)) {
|
||||
asmgen.out("""
|
||||
ldx ${rightArrayIndexer.variable.name}
|
||||
stx P8ZP_SCRATCH_W1
|
||||
ldx ${rightArrayIndexer.variable.name}+1
|
||||
stx P8ZP_SCRATCH_W1+1""")
|
||||
if (expr.operator == "+")
|
||||
asmgen.out(" clc | adc (P8ZP_SCRATCH_W1),y")
|
||||
else
|
||||
asmgen.out(" sec | sbc (P8ZP_SCRATCH_W1),y")
|
||||
} else {
|
||||
val arrayvarname = if (rightArrayIndexer.usesPointerVariable)
|
||||
"(${rightArrayIndexer.variable.name})"
|
||||
else
|
||||
asmgen.asmSymbolName(rightArrayIndexer.variable)
|
||||
if (expr.operator == "+")
|
||||
asmgen.out(" clc | adc $arrayvarname,y")
|
||||
else
|
||||
asmgen.out(" sec | sbc $arrayvarname,y")
|
||||
}
|
||||
val arrayvarname = asmgen.asmSymbolName(rightArrayIndexer.variable)
|
||||
if (expr.operator == "+")
|
||||
asmgen.out(" clc | adc $arrayvarname,y")
|
||||
else
|
||||
asmgen.out(" sec | sbc $arrayvarname,y")
|
||||
assignRegisterByte(target, CpuRegister.A, dt in SignedDatatypes, true)
|
||||
} else {
|
||||
assignExpressionToRegister(left, RegisterOrPair.A, left.type==DataType.BYTE)
|
||||
@ -2836,21 +2795,6 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
storeRegisterAInMemoryAddress(target.memory!!)
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
if(assignsIndexedPointerVar(target)) {
|
||||
if (target.constArrayIndexValue==0u) {
|
||||
asmgen.out(" lda $sourceName")
|
||||
asmgen.storeAIntoPointerVar(target.origAstTarget!!.array!!.variable)
|
||||
} else {
|
||||
asmgen.loadScaledArrayIndexIntoRegister(target.array!!, CpuRegister.Y)
|
||||
if (asmgen.isZpVar(target.origAstTarget!!.array!!.variable)) {
|
||||
asmgen.out(" lda $sourceName | sta (${target.asmVarname}),y")
|
||||
} else {
|
||||
asmgen.out(" lda ${target.asmVarname} | sta P8ZP_SCRATCH_W2 | lda ${target.asmVarname}+1 | sta P8ZP_SCRATCH_W2+1")
|
||||
asmgen.out(" lda $sourceName | sta (P8ZP_SCRATCH_W2),y")
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
if(target.array!!.splitWords)
|
||||
TODO("assign into split words ${target.position}")
|
||||
if (target.constArrayIndexValue!=null) {
|
||||
@ -3256,87 +3200,29 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
if(target.array!!.splitWords)
|
||||
throw AssemblyError("cannot assign byte to split word array here ${target.position}")
|
||||
|
||||
if(assignsIndexedPointerVar(target)) {
|
||||
// assign byte to a byte array via an uword pointervariable instead of a regular array variable
|
||||
if (target.constArrayIndexValue!=null) {
|
||||
when (register) {
|
||||
CpuRegister.A -> {}
|
||||
CpuRegister.X -> asmgen.out(" txa")
|
||||
CpuRegister.Y -> asmgen.out(" tya")
|
||||
}
|
||||
if(asmgen.isZpVar(target.origAstTarget!!.array!!.variable)) {
|
||||
asmgen.out(" ldy #${target.constArrayIndexValue} | sta (${target.asmVarname}),y")
|
||||
} else {
|
||||
asmgen.out("""
|
||||
ldy ${target.asmVarname}
|
||||
sty P8ZP_SCRATCH_W1
|
||||
ldy ${target.asmVarname}+1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
ldy #${target.constArrayIndexValue}
|
||||
sta (P8ZP_SCRATCH_W1),y""")
|
||||
}
|
||||
// assign regular array indexing
|
||||
if (target.constArrayIndexValue!=null) {
|
||||
when (register) {
|
||||
CpuRegister.A -> {}
|
||||
CpuRegister.X -> asmgen.out(" txa")
|
||||
CpuRegister.Y -> asmgen.out(" tya")
|
||||
}
|
||||
else {
|
||||
when (register) {
|
||||
CpuRegister.A -> {}
|
||||
CpuRegister.X -> asmgen.out(" txa")
|
||||
CpuRegister.Y -> asmgen.out(" tya")
|
||||
}
|
||||
val indexVar = target.array.index as? PtIdentifier
|
||||
if(indexVar!=null) {
|
||||
if(asmgen.isZpVar(target.origAstTarget!!.array!!.variable)) {
|
||||
asmgen.out(" ldy ${asmgen.asmVariableName(indexVar)} | sta (${target.asmVarname}),y")
|
||||
} else {
|
||||
asmgen.out("""
|
||||
ldy ${target.asmVarname}
|
||||
sty P8ZP_SCRATCH_W1
|
||||
ldy ${target.asmVarname}+1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
ldy ${asmgen.asmVariableName(indexVar)}
|
||||
sta (P8ZP_SCRATCH_W1),y""")
|
||||
}
|
||||
} else {
|
||||
asmgen.saveRegisterStack(register, false)
|
||||
asmgen.assignExpressionToRegister(target.array.index, RegisterOrPair.Y, false)
|
||||
asmgen.out(" pla")
|
||||
if(asmgen.isZpVar(target.origAstTarget!!.array!!.variable)) {
|
||||
asmgen.out(" sta (${target.asmVarname}),y")
|
||||
} else {
|
||||
asmgen.out("""
|
||||
ldx ${target.asmVarname}
|
||||
stx P8ZP_SCRATCH_W1
|
||||
ldx ${target.asmVarname}+1
|
||||
stx P8ZP_SCRATCH_W1+1
|
||||
sta (P8ZP_SCRATCH_W1),y""")
|
||||
}
|
||||
}
|
||||
asmgen.out(" sta ${target.asmVarname}+${target.constArrayIndexValue}")
|
||||
}
|
||||
else {
|
||||
when (register) {
|
||||
CpuRegister.A -> {}
|
||||
CpuRegister.X -> asmgen.out(" txa")
|
||||
CpuRegister.Y -> asmgen.out(" tya")
|
||||
}
|
||||
return
|
||||
} else {
|
||||
// assign regular array indexing
|
||||
if (target.constArrayIndexValue!=null) {
|
||||
when (register) {
|
||||
CpuRegister.A -> {}
|
||||
CpuRegister.X -> asmgen.out(" txa")
|
||||
CpuRegister.Y -> asmgen.out(" tya")
|
||||
}
|
||||
asmgen.out(" sta ${target.asmVarname}+${target.constArrayIndexValue}")
|
||||
}
|
||||
else {
|
||||
when (register) {
|
||||
CpuRegister.A -> {}
|
||||
CpuRegister.X -> asmgen.out(" txa")
|
||||
CpuRegister.Y -> asmgen.out(" tya")
|
||||
}
|
||||
val indexVar = target.array.index as? PtIdentifier
|
||||
if(indexVar!=null) {
|
||||
asmgen.out(" ldy ${asmgen.asmVariableName(indexVar)} | sta ${target.asmVarname},y")
|
||||
} else {
|
||||
require(target.array.index.type in ByteDatatypes)
|
||||
asmgen.saveRegisterStack(register, false)
|
||||
asmgen.assignExpressionToRegister(target.array.index, RegisterOrPair.Y, false)
|
||||
asmgen.out(" pla | sta ${target.asmVarname},y")
|
||||
}
|
||||
val indexVar = target.array.index as? PtIdentifier
|
||||
if(indexVar!=null) {
|
||||
asmgen.out(" ldy ${asmgen.asmVariableName(indexVar)} | sta ${target.asmVarname},y")
|
||||
} else {
|
||||
require(target.array.index.type in ByteDatatypes)
|
||||
asmgen.saveRegisterStack(register, false)
|
||||
asmgen.assignExpressionToRegister(target.array.index, RegisterOrPair.Y, false)
|
||||
asmgen.out(" pla | sta ${target.asmVarname},y")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3632,21 +3518,6 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
storeRegisterAInMemoryAddress(target.memory!!)
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
if(assignsIndexedPointerVar(target)) {
|
||||
if (target.constArrayIndexValue==0u) {
|
||||
asmgen.out(" lda #0")
|
||||
asmgen.storeAIntoPointerVar(target.origAstTarget!!.array!!.variable)
|
||||
} else {
|
||||
asmgen.loadScaledArrayIndexIntoRegister(target.array!!, CpuRegister.Y)
|
||||
if (asmgen.isZpVar(target.origAstTarget!!.array!!.variable)) {
|
||||
asmgen.out(" lda #0 | sta (${target.asmVarname}),y")
|
||||
} else {
|
||||
asmgen.out(" lda ${target.asmVarname} | sta P8ZP_SCRATCH_W2 | lda ${target.asmVarname}+1 | sta P8ZP_SCRATCH_W2+1")
|
||||
asmgen.out(" lda #0 | sta (P8ZP_SCRATCH_W2),y")
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
if(target.array!!.splitWords)
|
||||
throw AssemblyError("cannot assign byte to split word array here ${target.position}")
|
||||
if (target.constArrayIndexValue!=null) {
|
||||
@ -3686,21 +3557,6 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
storeRegisterAInMemoryAddress(target.memory!!)
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
if(assignsIndexedPointerVar(target)) {
|
||||
if (target.constArrayIndexValue==0u) {
|
||||
asmgen.out(" lda #${byte.toHex()}")
|
||||
asmgen.storeAIntoPointerVar(target.origAstTarget!!.array!!.variable)
|
||||
} else {
|
||||
asmgen.loadScaledArrayIndexIntoRegister(target.array!!, CpuRegister.Y)
|
||||
if (asmgen.isZpVar(target.origAstTarget!!.array!!.variable)) {
|
||||
asmgen.out(" lda #${byte.toHex()} | sta (${target.asmVarname}),y")
|
||||
} else {
|
||||
asmgen.out(" lda ${target.asmVarname} | sta P8ZP_SCRATCH_W2 | lda ${target.asmVarname}+1 | sta P8ZP_SCRATCH_W2+1")
|
||||
asmgen.out(" lda #${byte.toHex()} | sta (P8ZP_SCRATCH_W2),y")
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
if(target.array!!.splitWords)
|
||||
TODO("assign into split words ${target.position}")
|
||||
if (target.constArrayIndexValue!=null) {
|
||||
@ -3732,9 +3588,6 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
}
|
||||
}
|
||||
|
||||
private fun assignsIndexedPointerVar(target: AsmAssignTarget): Boolean =
|
||||
target.origAstTarget?.array?.variable?.type==DataType.UWORD
|
||||
|
||||
internal fun assignConstantFloat(target: AsmAssignTarget, float: Double) {
|
||||
if (float == 0.0) {
|
||||
// optimized case for float zero
|
||||
|
@ -163,7 +163,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
asmgen.assignExpressionTo(memory.address, AsmAssignTarget(TargetStorageKind.REGISTER, asmgen, DataType.UWORD, memory.definingISub(), target.position, register = RegisterOrPair.AY))
|
||||
asmgen.assignExpressionToRegister(memory.address, RegisterOrPair.AY, false)
|
||||
asmgen.saveRegisterStack(CpuRegister.A, true)
|
||||
asmgen.saveRegisterStack(CpuRegister.Y, true)
|
||||
asmgen.out(" jsr prog8_lib.read_byte_from_address_in_AY_into_A")
|
||||
|
@ -302,25 +302,6 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
||||
val variable = targetArray.variable.name
|
||||
val itemsize = codeGen.program.memsizer.memorySize(targetArray.type)
|
||||
|
||||
if(targetArray.usesPointerVariable) {
|
||||
if(itemsize!=1)
|
||||
throw AssemblyError("non-array var indexing requires bytes dt")
|
||||
if(targetArray.index.type!=DataType.UBYTE)
|
||||
throw AssemblyError("non-array var indexing requires bytes index")
|
||||
val tr = expressionEval.translateExpression(targetArray.index)
|
||||
val idxReg = tr.resultReg
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
val code = IRCodeChunk(null, null)
|
||||
if(zero) {
|
||||
// there's no STOREZIX instruction
|
||||
valueRegister = codeGen.registers.nextFree()
|
||||
code += IRInstruction(Opcode.LOAD, targetDt, reg1=valueRegister, immediate = 0)
|
||||
}
|
||||
code += IRInstruction(Opcode.STOREIX, targetDt, reg1=valueRegister, reg2=idxReg, labelSymbol = variable)
|
||||
result += code
|
||||
return result
|
||||
}
|
||||
|
||||
val fixedIndex = constIntValue(targetArray.index)
|
||||
val arrayLength = codeGen.symbolTable.getLength(targetArray.variable.name)
|
||||
if(zero) {
|
||||
|
@ -705,7 +705,6 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
}
|
||||
}
|
||||
is PtArrayIndexer -> {
|
||||
require(!target.usesPointerVariable)
|
||||
if(target.splitWords) {
|
||||
// lsb/msb in split arrays, element index 'size' is always 1
|
||||
val constIndex = target.index.asConstInteger()
|
||||
|
@ -180,19 +180,6 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
val vmDt = irType(arrayIx.type)
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val arrayVarSymbol = arrayIx.variable.name
|
||||
|
||||
if(arrayIx.usesPointerVariable) {
|
||||
if(eltSize!=1)
|
||||
throw AssemblyError("non-array var indexing requires bytes dt")
|
||||
if(arrayIx.index.type !in ByteDatatypes)
|
||||
throw AssemblyError("non-array var indexing requires bytes index")
|
||||
val tr = translateExpression(arrayIx.index)
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
val resultReg = codeGen.registers.nextFree()
|
||||
addInstr(result, IRInstruction(Opcode.LOADIX, vmDt, reg1=resultReg, reg2=tr.resultReg, labelSymbol = arrayVarSymbol), null)
|
||||
return ExpressionCodeResult(result, vmDt, resultReg, -1)
|
||||
}
|
||||
|
||||
var resultRegister = -1
|
||||
|
||||
if(arrayIx.splitWords) {
|
||||
@ -1253,20 +1240,17 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
if(array.splitWords)
|
||||
return operatorMinusInplaceSplitArray(array, operand)
|
||||
if(array.usesPointerVariable) {
|
||||
TODO("inplace - for pointer variable")
|
||||
}
|
||||
val vmDt = irType(array.type)
|
||||
val eltDt = irType(array.type)
|
||||
val constIndex = array.index.asConstInteger()
|
||||
val constValue = operand.asConstInteger()
|
||||
if(constIndex!=null && constValue!=null) {
|
||||
if(constValue==1) {
|
||||
addInstr(result, IRInstruction(Opcode.DECM, vmDt, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize), null)
|
||||
addInstr(result, IRInstruction(Opcode.DECM, eltDt, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize), null)
|
||||
} else {
|
||||
val valueReg=codeGen.registers.nextFree()
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.LOAD, vmDt, reg1=valueReg, immediate = constValue)
|
||||
it += IRInstruction(Opcode.SUBM, vmDt, reg1=valueReg, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize)
|
||||
it += IRInstruction(Opcode.LOAD, eltDt, reg1=valueReg, immediate = constValue)
|
||||
it += IRInstruction(Opcode.SUBM, eltDt, reg1=valueReg, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize)
|
||||
}
|
||||
}
|
||||
return Ok(result)
|
||||
@ -1344,9 +1328,6 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
if(array.splitWords)
|
||||
return operatorPlusInplaceSplitArray(array, operand)
|
||||
if(array.usesPointerVariable) {
|
||||
TODO("inplace + for pointer variable")
|
||||
}
|
||||
val eltSize = codeGen.program.memsizer.memorySize(array.type)
|
||||
val elementDt = irType(array.type)
|
||||
val constIndex = array.index.asConstInteger()
|
||||
@ -1806,8 +1787,6 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
if(array.splitWords)
|
||||
TODO("inplace compare for split word array")
|
||||
if(array.usesPointerVariable)
|
||||
TODO("inplace compare for pointer variable")
|
||||
val vmDt = irType(array.type)
|
||||
val constIndex = array.index.asConstInteger()
|
||||
val constValue = value.asConstInteger()
|
||||
|
@ -1534,20 +1534,7 @@ class IRCodeGen(
|
||||
val itemsize = program.memsizer.memorySize(array.type)
|
||||
val fixedIndex = constIntValue(array.index)
|
||||
if(fixedIndex!=null) {
|
||||
val offset = fixedIndex*itemsize
|
||||
val indexReg = registers.nextFree()
|
||||
val dataReg = registers.nextFree()
|
||||
if(array.usesPointerVariable) {
|
||||
// we don't have an indirect dec/inc so do it via an intermediate register
|
||||
result += IRCodeChunk(null,null).also {
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = indexReg, immediate = offset)
|
||||
it += IRInstruction(Opcode.LOADIX, irDt, reg1 = dataReg, reg2 = indexReg, labelSymbol = variable)
|
||||
it += IRInstruction(operationRegister, irDt, reg1=dataReg)
|
||||
it += IRInstruction(Opcode.STOREIX, irDt, reg1 = dataReg, reg2 = indexReg, labelSymbol = variable)
|
||||
}
|
||||
} else {
|
||||
addInstr(result, IRInstruction(operationMem, irDt, labelSymbol = variable, symbolOffset = offset), null)
|
||||
}
|
||||
addInstr(result, IRInstruction(operationMem, irDt, labelSymbol = variable, symbolOffset = fixedIndex*itemsize), null)
|
||||
} else {
|
||||
val indexTr = expressionEval.translateExpression(array.index)
|
||||
addToResult(result, indexTr, indexTr.resultReg, -1)
|
||||
@ -1555,15 +1542,9 @@ class IRCodeGen(
|
||||
result += multiplyByConst(IRDataType.BYTE, indexTr.resultReg, itemsize)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
val incReg = registers.nextFree()
|
||||
if(array.usesPointerVariable) {
|
||||
it += IRInstruction(Opcode.LOADIX, irDt, reg1=incReg, reg2=indexTr.resultReg, labelSymbol=variable)
|
||||
it += IRInstruction(operationRegister, irDt, reg1=incReg)
|
||||
it += IRInstruction(Opcode.STOREIX, irDt, reg1=incReg, reg2=indexTr.resultReg, labelSymbol=variable)
|
||||
} else {
|
||||
it += IRInstruction(Opcode.LOADX, irDt, reg1=incReg, reg2=indexTr.resultReg, labelSymbol=variable)
|
||||
it += IRInstruction(operationRegister, irDt, reg1=incReg)
|
||||
it += IRInstruction(Opcode.STOREX, irDt, reg1=incReg, reg2=indexTr.resultReg, labelSymbol=variable)
|
||||
}
|
||||
it += IRInstruction(Opcode.LOADX, irDt, reg1=incReg, reg2=indexTr.resultReg, labelSymbol=variable)
|
||||
it += IRInstruction(operationRegister, irDt, reg1=incReg)
|
||||
it += IRInstruction(Opcode.STOREX, irDt, reg1=incReg, reg2=indexTr.resultReg, labelSymbol=variable)
|
||||
}
|
||||
}
|
||||
} else
|
||||
|
@ -195,25 +195,22 @@ _after:
|
||||
// replace pointervar[word] by @(pointervar+word) to avoid the
|
||||
// "array indexing is limited to byte size 0..255" error for pointervariables.
|
||||
val indexExpr = arrayIndexedExpression.indexer.indexExpr
|
||||
val indexerDt = indexExpr.inferType(program)
|
||||
if(indexerDt.isWords) {
|
||||
val arrayVar = arrayIndexedExpression.arrayvar.targetVarDecl(program)
|
||||
if(arrayVar!=null && arrayVar.datatype==DataType.UWORD) {
|
||||
val add: Expression =
|
||||
if(indexExpr.constValue(program)?.number==0.0)
|
||||
arrayIndexedExpression.arrayvar.copy()
|
||||
else
|
||||
BinaryExpression(arrayIndexedExpression.arrayvar.copy(), "+", indexExpr, arrayIndexedExpression.position)
|
||||
return if(parent is AssignTarget) {
|
||||
// assignment to array
|
||||
val memwrite = DirectMemoryWrite(add, arrayIndexedExpression.position)
|
||||
val newtarget = AssignTarget(null, null, memwrite, arrayIndexedExpression.position)
|
||||
listOf(IAstModification.ReplaceNode(parent, newtarget, parent.parent))
|
||||
} else {
|
||||
// read from array
|
||||
val memread = DirectMemoryRead(add, arrayIndexedExpression.position)
|
||||
listOf(IAstModification.ReplaceNode(arrayIndexedExpression, memread, parent))
|
||||
}
|
||||
val arrayVar = arrayIndexedExpression.arrayvar.targetVarDecl(program)
|
||||
if(arrayVar!=null && arrayVar.datatype==DataType.UWORD) {
|
||||
val add: Expression =
|
||||
if(indexExpr.constValue(program)?.number==0.0)
|
||||
arrayIndexedExpression.arrayvar.copy()
|
||||
else
|
||||
BinaryExpression(arrayIndexedExpression.arrayvar.copy(), "+", indexExpr, arrayIndexedExpression.position)
|
||||
return if(parent is AssignTarget) {
|
||||
// assignment to array
|
||||
val memwrite = DirectMemoryWrite(add, arrayIndexedExpression.position)
|
||||
val newtarget = AssignTarget(null, null, memwrite, arrayIndexedExpression.position)
|
||||
listOf(IAstModification.ReplaceNode(parent, newtarget, parent.parent))
|
||||
} else {
|
||||
// read from array
|
||||
val memread = DirectMemoryRead(add, arrayIndexedExpression.position)
|
||||
listOf(IAstModification.ReplaceNode(arrayIndexedExpression, memread, parent))
|
||||
}
|
||||
}
|
||||
return noModifications
|
||||
|
@ -551,8 +551,10 @@ class IntermediateAstMaker(private val program: Program, private val errors: IEr
|
||||
}
|
||||
|
||||
private fun transform(srcArr: ArrayIndexedExpression): PtArrayIndexer {
|
||||
val arrayVarType = srcArr.inferType(program).getOrElse { throw FatalAstException("unknown dt") }
|
||||
val array = PtArrayIndexer(arrayVarType, srcArr.position)
|
||||
if(srcArr.arrayvar.targetVarDecl(program)!!.datatype !in ArrayDatatypes + DataType.STR)
|
||||
throw FatalAstException("array indexing can be used on array or string variables ${srcArr.position}")
|
||||
val eltType = srcArr.inferType(program).getOrElse { throw FatalAstException("unknown dt") }
|
||||
val array = PtArrayIndexer(eltType, srcArr.position)
|
||||
array.add(transform(srcArr.arrayvar))
|
||||
array.add(transformExpression(srcArr.indexer.indexExpr))
|
||||
return array
|
||||
|
@ -288,9 +288,6 @@ mylabel:
|
||||
|
||||
test("nesting with overlapping names is ok (doesn't work for 64tass)") {
|
||||
val src="""
|
||||
%import textio
|
||||
%zeropage basicsafe
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
main()
|
||||
|
@ -1,6 +1,9 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
petaxian is now a lot larger since pointer[idx] is rewritten into @(ptr+idx). Missing some optimized code somewhere now?
|
||||
VM textelite is now a lot larger too
|
||||
|
||||
(after merge in boolean): move all "OperatorXinplace" from expressionGen to AssignmentGen, see if we can get rid of the Result return type.
|
||||
|
||||
...
|
||||
|
@ -1,74 +1,30 @@
|
||||
%import textio
|
||||
;; %import test_stack
|
||||
%import floats
|
||||
%import math
|
||||
%zeropage basicsafe
|
||||
%option no_sysinit
|
||||
|
||||
main {
|
||||
uword[3] a
|
||||
uword[3] b
|
||||
ubyte @shared j
|
||||
uword @shared aa = 1
|
||||
|
||||
sub derp() {
|
||||
return aa=5
|
||||
sub derp(str arg) {
|
||||
arg[4] = '?'
|
||||
}
|
||||
|
||||
sub start() {
|
||||
derp()
|
||||
;; test_stack.test()
|
||||
j = 1
|
||||
a[j] = 1
|
||||
b[j] = 0
|
||||
b[j] += 5 * aa
|
||||
b[j] += 5 * aa
|
||||
b[j] += 5 * aa
|
||||
b[j] += 5 * aa
|
||||
txt.print_uw(b[j]) ; 20
|
||||
str msg = "hello"
|
||||
derp(msg)
|
||||
txt.chrout(msg[4]) ; ?
|
||||
txt.nl()
|
||||
b[j] += 5 * a[1]
|
||||
b[j] += 5 * a[1]
|
||||
b[j] += 5 * a[1]
|
||||
b[j] += 5 * a[1]
|
||||
txt.print_uw(b[j]) ; 40
|
||||
uword @shared az = $4000
|
||||
@($4004) = 0
|
||||
az[4] |= $40
|
||||
txt.print_ub(@($4004)) ; 64
|
||||
txt.nl()
|
||||
b[j] += 5 * a[j]
|
||||
b[j] += 5 * a[j]
|
||||
b[j] += 5 * a[j]
|
||||
b[j] += 5 * a[j]
|
||||
txt.print_uw(b[j]) ; 60
|
||||
@(az+4) = 0
|
||||
@(az+4) |= $4f
|
||||
txt.print_ub(@($4004)) ; 79
|
||||
txt.nl()
|
||||
;; test_stack.test()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
;%import textio
|
||||
;%import floats
|
||||
;%zeropage basicsafe
|
||||
;%option no_sysinit
|
||||
;
|
||||
;main {
|
||||
; sub start() {
|
||||
|
||||
; uword @shared addr = 2000
|
||||
; @(2000) = 199
|
||||
; txt.print_ub(@(2000))
|
||||
; txt.nl()
|
||||
; @(addr) = ~@(addr)
|
||||
; txt.print_ub(@(2000))
|
||||
; txt.nl()
|
||||
;
|
||||
; word[3] @split @shared array = [1111,$10ff,3333]
|
||||
;
|
||||
; txt.print_w(array[1])
|
||||
; txt.nl()
|
||||
; txt.print_w(-array[1])
|
||||
; txt.nl()
|
||||
; array[1] = -array[1]
|
||||
; txt.print_w(array[1])
|
||||
; txt.nl()
|
||||
; txt.nl()
|
||||
;
|
||||
; ubyte @shared idx = 1
|
||||
; txt.print_w(array[idx])
|
||||
; txt.nl()
|
||||
@ -151,5 +107,5 @@ main {
|
||||
; bb = bb or barr[1]
|
||||
; bb = bb xor barr[1]
|
||||
; bb = not bb
|
||||
; }
|
||||
;}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user