From 9227a3a8574ba5a586b39bc6c4f69bfc77b9aae7 Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Mon, 27 Jul 2020 12:12:41 +0200 Subject: [PATCH] Fixed Wrong size of padding for non-byte arrays. Closes #497 --- .../java/dk/camelot64/kickc/asm/AsmChunk.java | 2 +- .../dk/camelot64/kickc/asm/AsmDataChunk.java | 26 +- ...{AsmDataFill.java => AsmDataZeroFill.java} | 13 +- .../dk/camelot64/kickc/asm/AsmProgram.java | 4 +- .../kickc/passes/Pass4CodeGeneration.java | 40 ++- .../passes/Pass5DoubleJumpElimination.java | 2 +- .../passes/Pass5NextJumpElimination.java | 2 +- .../dk/camelot64/kickc/test/TestPrograms.java | 5 + src/test/kc/array-16bit-init.c | 9 + src/test/ref/array-16bit-init.asm | 29 ++ src/test/ref/array-16bit-init.cfg | 17 + src/test/ref/array-16bit-init.log | 333 ++++++++++++++++++ src/test/ref/array-16bit-init.sym | 13 + 13 files changed, 447 insertions(+), 48 deletions(-) rename src/main/java/dk/camelot64/kickc/asm/{AsmDataFill.java => AsmDataZeroFill.java} (74%) create mode 100644 src/test/kc/array-16bit-init.c create mode 100644 src/test/ref/array-16bit-init.asm create mode 100644 src/test/ref/array-16bit-init.cfg create mode 100644 src/test/ref/array-16bit-init.log create mode 100644 src/test/ref/array-16bit-init.sym diff --git a/src/main/java/dk/camelot64/kickc/asm/AsmChunk.java b/src/main/java/dk/camelot64/kickc/asm/AsmChunk.java index 0d6d06b4c..ef8c6629a 100644 --- a/src/main/java/dk/camelot64/kickc/asm/AsmChunk.java +++ b/src/main/java/dk/camelot64/kickc/asm/AsmChunk.java @@ -313,7 +313,7 @@ public class AsmChunk { line instanceof AsmLabelDecl || line instanceof AsmConstant || line instanceof AsmDataNumeric || - line instanceof AsmDataFill || + line instanceof AsmDataZeroFill || line instanceof AsmDataString || line instanceof AsmDataAlignment || (line instanceof AsmInlineKickAsm && !line.getAsm().contains(".pc")); diff --git a/src/main/java/dk/camelot64/kickc/asm/AsmDataChunk.java b/src/main/java/dk/camelot64/kickc/asm/AsmDataChunk.java index 645a67cf1..b2b57ccfc 100644 --- a/src/main/java/dk/camelot64/kickc/asm/AsmDataChunk.java +++ b/src/main/java/dk/camelot64/kickc/asm/AsmDataChunk.java @@ -42,24 +42,22 @@ public class AsmDataChunk { } } - /** A number of identical numerical data elements. */ - public static class AsmDataFilledElement implements AsmDataElement { + /** A number of zero data elements. */ + public static class AsmDataZeroFilledElement implements AsmDataElement { + /** The ASM specifying how the total size in bytes - in ASM-format. */ String totalSizeBytesAsm; /** The type of the element */ AsmDataNumeric.Type type; /** The literal integer number of elements. */ int numElements; - /** The fill value. */ - String fillValue; /** The string encoding used in any char/string value */ Set encoding; - AsmDataFilledElement(AsmDataNumeric.Type type, String totalSizeBytesAsm, int numElements, String fillValue, Set encoding) { + AsmDataZeroFilledElement(AsmDataNumeric.Type type, String totalSizeBytesAsm, int numElements, Set encoding) { this.type = type; this.totalSizeBytesAsm = totalSizeBytesAsm; this.numElements = numElements; - this.fillValue = fillValue; this.encoding = encoding; } @@ -75,10 +73,6 @@ public class AsmDataChunk { return numElements; } - String getFillValue() { - return fillValue; - } - public Set getEncoding() { return encoding; } @@ -145,8 +139,8 @@ public class AsmDataChunk { elements.add(new AsmDataNumericElement(type, value, encoding)); } - public void addDataFilled(AsmDataNumeric.Type type, String totalSizeBytesAsm, int numElements, String fillValue, Set encoding) { - elements.add(new AsmDataFilledElement(type, totalSizeBytesAsm, numElements, fillValue, encoding)); + public void addDataZeroFilled(AsmDataNumeric.Type type, String totalSizeBytesAsm, int numElements, Set encoding) { + elements.add(new AsmDataZeroFilledElement(type, totalSizeBytesAsm, numElements, encoding)); } public void addDataString(String string, Set encoding) { @@ -173,7 +167,7 @@ public class AsmDataChunk { AsmDataNumeric.Type currentNumericType = null; List currentNumericElements = null; for(AsmDataChunk.AsmDataElement element : this.getElements()) { - if(element instanceof AsmDataFilledElement || element instanceof AsmDataStringElement || element instanceof AsmDataKickAsmElement) { + if(element instanceof AsmDataZeroFilledElement || element instanceof AsmDataStringElement || element instanceof AsmDataKickAsmElement) { if(currentNumericElements != null && currentNumericElements.size() > 0) { asm.addDataNumeric(label, currentNumericType, currentNumericElements); label = null; // Only output label once @@ -181,10 +175,10 @@ public class AsmDataChunk { currentNumericType = null; } } - if(element instanceof AsmDataFilledElement) { - AsmDataFilledElement filledElement = (AsmDataFilledElement) element; + if(element instanceof AsmDataZeroFilledElement) { + AsmDataZeroFilledElement filledElement = (AsmDataZeroFilledElement) element; asm.ensureEncoding(filledElement.getEncoding()); - asm.addDataFilled(label, filledElement.getType(), filledElement.getTotalSizeBytesAsm(), filledElement.getNumElements(), filledElement.getFillValue()); + asm.addDataZeroFilled(label, filledElement.getType(), filledElement.getTotalSizeBytesAsm(), filledElement.getNumElements()); label = null; // Only output label once } else if(element instanceof AsmDataKickAsmElement) { AsmDataKickAsmElement kickAsmElement = (AsmDataKickAsmElement) element; diff --git a/src/main/java/dk/camelot64/kickc/asm/AsmDataFill.java b/src/main/java/dk/camelot64/kickc/asm/AsmDataZeroFill.java similarity index 74% rename from src/main/java/dk/camelot64/kickc/asm/AsmDataFill.java rename to src/main/java/dk/camelot64/kickc/asm/AsmDataZeroFill.java index 752cfffc8..8ed6267b8 100644 --- a/src/main/java/dk/camelot64/kickc/asm/AsmDataFill.java +++ b/src/main/java/dk/camelot64/kickc/asm/AsmDataZeroFill.java @@ -1,7 +1,7 @@ package dk.camelot64.kickc.asm; -/** A labelled numeric data directive. */ -public class AsmDataFill implements AsmLine { +/** A labelled zero-filled data directive. */ +public class AsmDataZeroFill implements AsmLine { private String label; /** The calculation of the total number of bytes in ASM-format */ @@ -10,18 +10,14 @@ public class AsmDataFill implements AsmLine { private AsmDataNumeric.Type type; /** The number of elements*/ private int numElements; - /** The value to fill with in ASM-format */ - private String fillValue; private int index; - - public AsmDataFill(String label, AsmDataNumeric.Type type, String totalByteSizeAsm, int numElements, String fillValue) { + public AsmDataZeroFill(String label, AsmDataNumeric.Type type, String totalByteSizeAsm, int numElements) { this.label = label; this.type = type; this.totalByteSizeAsm = totalByteSizeAsm; this.numElements = numElements; - this.fillValue = fillValue; } public int getElementBytes() { @@ -46,8 +42,7 @@ public class AsmDataFill implements AsmLine { } asm.append(".fill "); asm.append(totalByteSizeAsm); - asm.append(", "); - asm.append(fillValue); + asm.append(", 0"); return asm.toString(); } diff --git a/src/main/java/dk/camelot64/kickc/asm/AsmProgram.java b/src/main/java/dk/camelot64/kickc/asm/AsmProgram.java index 21a5bf170..60d0ff14e 100644 --- a/src/main/java/dk/camelot64/kickc/asm/AsmProgram.java +++ b/src/main/java/dk/camelot64/kickc/asm/AsmProgram.java @@ -142,8 +142,8 @@ public class AsmProgram { * @param type The type of the data * @param numElements The size of data to fill */ - public void addDataFilled(String label, AsmDataNumeric.Type type, String totalSizeBytesAsm, int numElements, String fillValue) { - addLine(new AsmDataFill(label, type, totalSizeBytesAsm, numElements, fillValue)); + public void addDataZeroFilled(String label, AsmDataNumeric.Type type, String totalSizeBytesAsm, int numElements) { + addLine(new AsmDataZeroFill(label, type, totalSizeBytesAsm, numElements)); } /** diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java b/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java index 3de7e9efc..9291abd9a 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java @@ -665,7 +665,7 @@ public class Pass4CodeGeneration { final ConstantRef structSize = SizeOfConstants.getSizeOfConstantVar(getScope(), typeStruct); String totalSizeBytesAsm = AsmFormat.getAsmConstant(program, structSize, 99, scopeRef); int totalSizeBytes = typeStruct.getSizeBytes(); - dataChunk.addDataFilled(AsmDataNumeric.Type.BYTE, totalSizeBytesAsm, totalSizeBytes, "0", null); + dataChunk.addDataZeroFilled(AsmDataNumeric.Type.BYTE, totalSizeBytesAsm, totalSizeBytes, null); } } else if(valueType instanceof SymbolTypePointer && valueArraySpec != null) { SymbolTypePointer constTypeArray = (SymbolTypePointer) valueType; @@ -684,17 +684,18 @@ public class Pass4CodeGeneration { int elementSizeBytes = elementType.getSizeBytes(); String totalSizeBytesAsm; if(elementSizeBytes > 1) { + // TODO: Use a SIZEOF constant for the element size ASM totalSizeBytesAsm = AsmFormat.getAsmConstant(program, new ConstantBinary(new ConstantInteger((long) elementSizeBytes, SymbolType.NUMBER), Operators.MULTIPLY, arraySize), 99, scopeRef); } else { totalSizeBytesAsm = AsmFormat.getAsmConstant(program, arraySize, 99, scopeRef); } if(elementType instanceof SymbolTypeIntegerFixed || elementType instanceof SymbolTypePointer) { // Use an ASM type in the fill that matches the element type - dataChunk.addDataFilled(getNumericType(elementType), totalSizeBytesAsm, dataNumElements, "0", null); + dataChunk.addDataZeroFilled(getNumericType(elementType), totalSizeBytesAsm, dataNumElements, null); } else { // Complex fill type - calculate byte size and use that int totalSizeBytes = elementSizeBytes * dataNumElements; - dataChunk.addDataFilled(AsmDataNumeric.Type.BYTE, totalSizeBytesAsm, totalSizeBytes, "0", null); + dataChunk.addDataZeroFilled(AsmDataNumeric.Type.BYTE, totalSizeBytesAsm, totalSizeBytes, null); } } else if(value instanceof ConstantArrayKickAsm) { ConstantArrayKickAsm kickAsm = (ConstantArrayKickAsm) value; @@ -727,31 +728,34 @@ public class Pass4CodeGeneration { if(!(value instanceof ConstantArrayKickAsm)) { Integer declaredSize = getArrayDeclaredSize(valueArraySpec.getArraySize()); if(declaredSize != null && declaredSize > dataNumElements) { - int padding = declaredSize - dataNumElements; - ConstantValue zeroValue = Initializers.createZeroValue(new Initializers.ValueTypeSpec(elementType, valueArraySpec), null); - if(zeroValue instanceof ConstantInteger) { - dataChunk.addDataFilled(getNumericType(elementType), AsmFormat.getAsmNumber(padding), padding, AsmFormat.getAsmConstant(program, zeroValue, 99, scopeRef), getEncoding(zeroValue)); + long paddingSize = declaredSize - dataNumElements; + ConstantValue paddingSizeVal = new ConstantInteger(paddingSize); + int elementSizeBytes = elementType.getSizeBytes(); + String paddingBytesAsm; + if(elementSizeBytes > 1) { + // TODO: Use a SIZEOF constant for the element size ASM - combine this with ConstantArrayFilled above + paddingBytesAsm = AsmFormat.getAsmConstant(program, new ConstantBinary(new ConstantInteger((long) elementSizeBytes, SymbolType.NUMBER), Operators.MULTIPLY, paddingSizeVal), 99, scopeRef); } else { - for(int i = 0; i < padding; i++) { + paddingBytesAsm = AsmFormat.getAsmConstant(program, paddingSizeVal, 99, scopeRef); + } + ConstantValue zeroValue = Initializers.createZeroValue(new Initializers.ValueTypeSpec(elementType, null), null); + if(zeroValue instanceof ConstantInteger | zeroValue instanceof ConstantPointer) { + dataChunk.addDataZeroFilled(getNumericType(elementType), paddingBytesAsm, (int) paddingSize, getEncoding(zeroValue)); + } else { + for(int i = 0; i < paddingSize; i++) { addChunkData(dataChunk, zeroValue, elementType, null, scopeRef); } } } } } else if(value instanceof ConstantString) { - try { - ConstantLiteral literal = value.calculateLiteral(getScope()); - if(literal instanceof ConstantString) { + ConstantString stringValue = (ConstantString) value; // Ensure encoding is good - String asmConstant = AsmFormat.getAsmConstant(program, literal, 99, scopeRef); - dataChunk.addDataString(asmConstant, getEncoding(literal)); - if(((ConstantString) literal).isZeroTerminated()) { + String asmConstant = AsmFormat.getAsmConstant(program, stringValue, 99, scopeRef); + dataChunk.addDataString(asmConstant, getEncoding(stringValue)); + if(stringValue.isZeroTerminated()) { dataChunk.addDataNumeric(AsmDataNumeric.Type.BYTE, "0", null); } - } - } catch(ConstantNotLiteral e) { - // can't calculate literal value, so it is not data - just return - } } else if(SymbolType.BYTE.equals(valueType) || SymbolType.SBYTE.equals(valueType)) { dataChunk.addDataNumeric(AsmDataNumeric.Type.BYTE, AsmFormat.getAsmConstant(program, value, 99, scopeRef), getEncoding(value)); } else if(SymbolType.WORD.equals(valueType) || SymbolType.SWORD.equals(valueType)) { diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass5DoubleJumpElimination.java b/src/main/java/dk/camelot64/kickc/passes/Pass5DoubleJumpElimination.java index 69a4849d6..4d8ca276b 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass5DoubleJumpElimination.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass5DoubleJumpElimination.java @@ -37,7 +37,7 @@ public class Pass5DoubleJumpElimination extends Pass5AsmOptimization { currentLabel = ((AsmLabel) line).getLabel(); } else if(line instanceof AsmComment || line instanceof AsmConstant || line instanceof AsmLabelDecl) { // ignore - } else if(line instanceof AsmBasicUpstart || line instanceof AsmDataNumeric || line instanceof AsmDataFill || line instanceof AsmDataString || line instanceof AsmDataAlignment || line instanceof AsmSetPc || line instanceof AsmInlineKickAsm|| line instanceof AsmSetEncoding|| line instanceof AsmSetCpu|| line instanceof AsmDataKickAsm|| line instanceof AsmSegmentDef|| line instanceof AsmSegment|| line instanceof AsmFile) { + } else if(line instanceof AsmBasicUpstart || line instanceof AsmDataNumeric || line instanceof AsmDataZeroFill || line instanceof AsmDataString || line instanceof AsmDataAlignment || line instanceof AsmSetPc || line instanceof AsmInlineKickAsm|| line instanceof AsmSetEncoding|| line instanceof AsmSetCpu|| line instanceof AsmDataKickAsm|| line instanceof AsmSegmentDef|| line instanceof AsmSegment|| line instanceof AsmFile) { currentLabel = null; } else if(line instanceof AsmInstruction) { if(currentLabel != null) { diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass5NextJumpElimination.java b/src/main/java/dk/camelot64/kickc/passes/Pass5NextJumpElimination.java index 130315f3c..412781379 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass5NextJumpElimination.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass5NextJumpElimination.java @@ -36,7 +36,7 @@ public class Pass5NextJumpElimination extends Pass5AsmOptimization { if(instruction.getAsmOpcode().isJump() && !instruction.getAsmOpcode().getMnemonic().equals("jsr")) { candidate = instruction; } - } else if(line instanceof AsmDataString || line instanceof AsmDataNumeric || line instanceof AsmDataFill || line instanceof AsmInlineKickAsm ) { + } else if(line instanceof AsmDataString || line instanceof AsmDataNumeric || line instanceof AsmDataZeroFill || line instanceof AsmInlineKickAsm ) { candidate = null; } } diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index 7245a76a8..841a09c44 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -1263,6 +1263,11 @@ public class TestPrograms { compileAndCompare("coalesce-assignment.c"); } + @Test + public void testArray16bitInit() throws IOException, URISyntaxException { + compileAndCompare("array-16bit-init.c"); + } + @Test public void testArray16bitLookup() throws IOException, URISyntaxException { compileAndCompare("array-16bit-lookup.c"); diff --git a/src/test/kc/array-16bit-init.c b/src/test/kc/array-16bit-init.c new file mode 100644 index 000000000..e3bdeb3cf --- /dev/null +++ b/src/test/kc/array-16bit-init.c @@ -0,0 +1,9 @@ +// Demonstrates wrong padding for non-byte arrays. +// https://gitlab.com/camelot/kickc/-/issues/497 + +char* levelRowOff[31] = { 1, 2, 3 }; + +void main() { + for(char c=0;c$3039 + sta levelRowOff+1,y + // for(char c=0;cmain::@1] + __b1_from_main: + // [1] phi (byte) main::c#2 = (byte) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1 + lda #0 + sta.z c + jmp __b1 + // main::@1 + __b1: + // [2] if((byte) main::c#2<(byte) $1f*(const byte) SIZEOF_POINTER/(const byte) SIZEOF_POINTER) goto main::@2 -- vbuz1_lt_vbuc1_then_la1 + lda.z c + cmp #$1f*SIZEOF_POINTER/SIZEOF_POINTER + bcc __b2 + jmp __breturn + // main::@return + __breturn: + // [3] return + rts + // main::@2 + __b2: + // [4] (byte~) main::$3 ← (byte) main::c#2 << (byte) 1 -- vbuz1=vbuz2_rol_1 + lda.z c + asl + sta.z __3 + // [5] *((const byte**) levelRowOff + (byte~) main::$3) ← (byte*) 12345 -- qbuc1_derefidx_vbuz1=pbuc2 + ldy.z __3 + lda #<$3039 + sta levelRowOff,y + lda #>$3039 + sta levelRowOff+1,y + // [6] (byte) main::c#1 ← ++ (byte) main::c#2 -- vbuz1=_inc_vbuz1 + inc.z c + // [1] phi from main::@2 to main::@1 [phi:main::@2->main::@1] + __b1_from___b2: + // [1] phi (byte) main::c#2 = (byte) main::c#1 [phi:main::@2->main::@1#0] -- register_copy + jmp __b1 +} + // File Data + levelRowOff: .word 1, 2, 3 + .fill 2*$1c, 0 + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [4] (byte~) main::$3 ← (byte) main::c#2 << (byte) 1 [ main::c#2 main::$3 ] ( [ main::c#2 main::$3 ] { } ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::c#2 main::c#1 ] +Statement [5] *((const byte**) levelRowOff + (byte~) main::$3) ← (byte*) 12345 [ main::c#2 ] ( [ main::c#2 ] { } ) always clobbers reg byte a +Statement [4] (byte~) main::$3 ← (byte) main::c#2 << (byte) 1 [ main::c#2 main::$3 ] ( [ main::c#2 main::$3 ] { } ) always clobbers reg byte a +Statement [5] *((const byte**) levelRowOff + (byte~) main::$3) ← (byte*) 12345 [ main::c#2 ] ( [ main::c#2 ] { } ) always clobbers reg byte a +Potential registers zp[1]:2 [ main::c#2 main::c#1 ] : zp[1]:2 , reg byte x , reg byte y , +Potential registers zp[1]:3 [ main::$3 ] : zp[1]:3 , reg byte a , reg byte x , reg byte y , + +REGISTER UPLIFT SCOPES +Uplift Scope [main] 33: zp[1]:2 [ main::c#2 main::c#1 ] 22: zp[1]:3 [ main::$3 ] +Uplift Scope [] + +Uplifting [main] best 381 combination reg byte x [ main::c#2 main::c#1 ] reg byte a [ main::$3 ] +Uplifting [] best 381 combination + +ASSEMBLER BEFORE OPTIMIZATION + // File Comments +// Demonstrates Wrong allocation of arrays. +// https://gitlab.com/camelot/kickc/-/issues/497 + // Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + // Global Constants & labels + .const SIZEOF_POINTER = 2 + // main +main: { + // [1] phi from main to main::@1 [phi:main->main::@1] + __b1_from_main: + // [1] phi (byte) main::c#2 = (byte) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1 + ldx #0 + jmp __b1 + // main::@1 + __b1: + // [2] if((byte) main::c#2<(byte) $1f*(const byte) SIZEOF_POINTER/(const byte) SIZEOF_POINTER) goto main::@2 -- vbuxx_lt_vbuc1_then_la1 + cpx #$1f*SIZEOF_POINTER/SIZEOF_POINTER + bcc __b2 + jmp __breturn + // main::@return + __breturn: + // [3] return + rts + // main::@2 + __b2: + // [4] (byte~) main::$3 ← (byte) main::c#2 << (byte) 1 -- vbuaa=vbuxx_rol_1 + txa + asl + // [5] *((const byte**) levelRowOff + (byte~) main::$3) ← (byte*) 12345 -- qbuc1_derefidx_vbuaa=pbuc2 + tay + lda #<$3039 + sta levelRowOff,y + lda #>$3039 + sta levelRowOff+1,y + // [6] (byte) main::c#1 ← ++ (byte) main::c#2 -- vbuxx=_inc_vbuxx + inx + // [1] phi from main::@2 to main::@1 [phi:main::@2->main::@1] + __b1_from___b2: + // [1] phi (byte) main::c#2 = (byte) main::c#1 [phi:main::@2->main::@1#0] -- register_copy + jmp __b1 +} + // File Data + levelRowOff: .word 1, 2, 3 + .fill 2*$1c, 0 + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp __b1 +Removing instruction jmp __breturn +Succesful ASM optimization Pass5NextJumpElimination +Removing instruction __b1_from_main: +Removing instruction __breturn: +Removing instruction __b1_from___b2: +Succesful ASM optimization Pass5UnusedLabelElimination + +FINAL SYMBOL TABLE +(const byte) SIZEOF_POINTER = (byte) 2 +(const byte**) levelRowOff[(number) $1f] = { (byte*) 1, (byte*) 2, (byte*) 3 } +(void()) main() +(byte~) main::$3 reg byte a 22.0 +(label) main::@1 +(label) main::@2 +(label) main::@return +(byte) main::c +(byte) main::c#1 reg byte x 22.0 +(byte) main::c#2 reg byte x 11.0 + +reg byte x [ main::c#2 main::c#1 ] +reg byte a [ main::$3 ] + + +FINAL ASSEMBLER +Score: 321 + + // File Comments +// Demonstrates Wrong allocation of arrays. +// https://gitlab.com/camelot/kickc/-/issues/497 + // Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + // Global Constants & labels + .const SIZEOF_POINTER = 2 + // main +main: { + // [1] phi from main to main::@1 [phi:main->main::@1] + // [1] phi (byte) main::c#2 = (byte) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1 + ldx #0 + // main::@1 + __b1: + // for(char c=0;c$3039 + sta levelRowOff+1,y + // for(char c=0;cmain::@1] + // [1] phi (byte) main::c#2 = (byte) main::c#1 [phi:main::@2->main::@1#0] -- register_copy + jmp __b1 +} + // File Data + levelRowOff: .word 1, 2, 3 + .fill 2*$1c, 0 + diff --git a/src/test/ref/array-16bit-init.sym b/src/test/ref/array-16bit-init.sym new file mode 100644 index 000000000..e2feae999 --- /dev/null +++ b/src/test/ref/array-16bit-init.sym @@ -0,0 +1,13 @@ +(const byte) SIZEOF_POINTER = (byte) 2 +(const byte**) levelRowOff[(number) $1f] = { (byte*) 1, (byte*) 2, (byte*) 3 } +(void()) main() +(byte~) main::$3 reg byte a 22.0 +(label) main::@1 +(label) main::@2 +(label) main::@return +(byte) main::c +(byte) main::c#1 reg byte x 22.0 +(byte) main::c#2 reg byte x 11.0 + +reg byte x [ main::c#2 main::c#1 ] +reg byte a [ main::$3 ]