array issue

This commit is contained in:
Irmen de Jong 2024-02-28 01:45:51 +01:00
parent af17f903ee
commit ceaa4cd07d
3 changed files with 68 additions and 31 deletions

View File

@ -79,7 +79,7 @@ internal class IfElseAsmGen(private val program: PtProgram,
}
private fun fallbackTranslate(stmt: PtIfElse, warning: Boolean) {
if(warning) println("WARN: FALLBACK IF: ${stmt.position}") // TODO should have no more of these
if(warning) println("WARN: SLOW FALLBACK IF: ${stmt.position}. Ask for support.") // TODO should have no more of these
val jumpAfterIf = stmt.ifScope.children.singleOrNull() as? PtJump
assignConditionValueToRegisterAndTest(stmt.condition)
if(jumpAfterIf!=null)
@ -733,7 +733,10 @@ _jump jmp ($asmLabel)
is PtArrayIndexer -> {
val varname = asmgen.asmVariableName(value.variable)
asmgen.loadScaledArrayIndexIntoRegister(value, CpuRegister.Y)
asmgen.out(" lda $varname+1,y")
if(value.splitWords)
asmgen.out(" lda ${varname}_msb,y")
else
asmgen.out(" lda $varname+1,y")
}
is PtIdentifier -> {
val varname = asmgen.asmVariableName(value)
@ -1013,10 +1016,14 @@ _jump jmp ($asmLabel)
is PtArrayIndexer -> {
val constIndex = value.index.asConstInteger()
if(constIndex!=null) {
val offset = constIndex * program.memsizer.memorySize(value.type)
if(offset<256) {
val varName = asmgen.asmVariableName(value.variable)
return translateLoadFromVar("$varName+$offset", "bne", "beq")
if(value.splitWords) {
TODO("split word array != 0")
} else {
val offset = constIndex * program.memsizer.memorySize(value.type)
if (offset < 256) {
val varName = asmgen.asmVariableName(value.variable)
return translateLoadFromVar("$varName+$offset", "bne", "beq")
}
}
}
viaScratchReg("bne", "beq")
@ -1029,15 +1036,19 @@ _jump jmp ($asmLabel)
} else {
when (value) {
is PtArrayIndexer -> {
val constIndex = value.index.asConstInteger()
if(constIndex!=null) {
val offset = constIndex * program.memsizer.memorySize(value.type)
if(offset<256) {
val varName = asmgen.asmVariableName(value.variable)
return translateLoadFromVar("$varName+$offset", "beq", "bne")
if(value.splitWords) {
TODO("split word array ==0")
} else {
val constIndex = value.index.asConstInteger()
if (constIndex != null) {
val offset = constIndex * program.memsizer.memorySize(value.type)
if (offset < 256) {
val varName = asmgen.asmVariableName(value.variable)
return translateLoadFromVar("$varName+$offset", "beq", "bne")
}
}
viaScratchReg("beq", "bne")
}
viaScratchReg("beq", "bne")
}
is PtIdentifier -> {
return translateLoadFromVar(asmgen.asmVariableName(value), "beq", "bne")
@ -1156,16 +1167,19 @@ _jump jmp ($asmLabel)
if(notEquals) {
when(left) {
is PtArrayIndexer -> {
asmgen.assignExpressionToRegister(right, RegisterOrPair.AY, signed)
val constIndex = left.index.asConstInteger()
if(constIndex!=null) {
asmgen.assignExpressionToRegister(right, RegisterOrPair.AY, signed)
if(left.splitWords) {
TODO("split word array !=")
}
val offset = constIndex * program.memsizer.memorySize(left.type)
if(offset<256) {
val varName = asmgen.asmVariableName(left.variable)
return translateNotEquals("$varName+$offset", "$varName+$offset+1")
}
}
fallbackTranslate(stmt, false)
fallbackTranslate(stmt, true)
}
is PtIdentifier -> {
asmgen.assignExpressionToRegister(right, RegisterOrPair.AY, signed)
@ -1176,13 +1190,9 @@ _jump jmp ($asmLabel)
if(left.isFromArrayElement)
fallbackTranslate(stmt, false)
else {
if(left.isFromArrayElement)
fallbackTranslate(stmt, false)
else {
asmgen.assignExpressionToRegister(right, RegisterOrPair.AY, signed)
val varname = asmgen.asmVariableName(left.identifier)
return translateNotEquals("#<$varname", "#>$varname")
}
asmgen.assignExpressionToRegister(right, RegisterOrPair.AY, signed)
val varname = asmgen.asmVariableName(left.identifier)
return translateNotEquals("#<$varname", "#>$varname")
}
}
else -> fallbackTranslate(stmt, false)
@ -1190,16 +1200,19 @@ _jump jmp ($asmLabel)
} else {
when(left) {
is PtArrayIndexer -> {
asmgen.assignExpressionToRegister(right, RegisterOrPair.AY, signed)
val constIndex = left.index.asConstInteger()
if(constIndex!=null) {
asmgen.assignExpressionToRegister(right, RegisterOrPair.AY, signed)
if(left.splitWords) {
TODO("split word array ==")
}
val offset = constIndex * program.memsizer.memorySize(left.type)
if(offset<256) {
val varName = asmgen.asmVariableName(left.variable)
return translateEquals("$varName+$offset", "$varName+$offset+1")
}
}
fallbackTranslate(stmt, false)
fallbackTranslate(stmt, true)
}
is PtIdentifier -> {
asmgen.assignExpressionToRegister(right, RegisterOrPair.AY, signed)

View File

@ -1,7 +1,8 @@
TODO
====
test if any()... code size
add peephole asm optimizer that removes a cmp #0 directly after a lda (same for cpx cpy)
check all comparisons for split word arrays (signed+unsigned, all 4 variants)
floatparse is slightly larger
@ -9,7 +10,6 @@ snow is a lot larger
neofetch is sligthly larger
explore possible optimizations for words when comparing to a constant number (BeforeAsmAstChanger)
@ -17,6 +17,10 @@ add tests for comparison that do an assignment rather than an if
assign to variable, and barray[indexvar], test if they're both correct
(bb = value > -100 --> contains a beq +++ that shouldn't be there??)
optimize assignOptimizedComparisonWords for when comparing to simple things like number and identifier.
optimize optimizedPlusMinExpr for when comparing to simple things like number and identifier.
optimize the IfElseAsmgen's fallbackTranslate even more (for arrays without const index for example?)
===== ====== =======

View File

@ -6,12 +6,32 @@
main {
sub start() {
ubyte[] barray = [11,22,33]
uword[] warray = [1111,2222,3333]
if not string.isdigit(cx16.r0L)
goto done
cx16.r0L++
done:
if any(barray)
cx16.r0++
;
;
; if barray[2] == 33
; cx16.r0++
; else
; cx16.r1++
;
; if warray[2] == 3333
; cx16.r0++
; else
; cx16.r1++
;
; if barray[cx16.r0L] == 33
; cx16.r0++
; else
; cx16.r1++
;
; if warray[cx16.r0L] == 3333
; cx16.r0++
; else
; cx16.r1++
}
}