1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-04-08 14:37:40 +00:00

Working on better ASM fragment handling for pointer to pointer. #484

This commit is contained in:
jespergravgaard 2020-07-01 08:24:12 +02:00
parent d9c387665c
commit 50d034a5a2
65 changed files with 138 additions and 17790 deletions

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE 12e560f399
//KICKC FRAGMENT CACHE 125a7c9d20
//FRAGMENT vbuz1=vbuc1
lda #{c1}
sta {z1}

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +0,0 @@
lda {m1}
sta {c1},x
lda {m1}+1
sta {c1}+1,x

View File

@ -1,5 +0,0 @@
lda {m2}
sta ({z1}),y
iny
lda {m2}+1
sta ({z1}),y

View File

@ -0,0 +1,3 @@
sta {m1}
lda #0
sta {m1}+1

View File

@ -0,0 +1,4 @@
lda #<{c1}
sta {m1}
lda #>{c1}
sta {m1}+1

View File

@ -0,0 +1,7 @@
lda #<{c1}
clc
adc {m1}
sta {m1}
lda #>{c1}
adc {m1}+1
sta {m1}+1

View File

@ -0,0 +1,7 @@
lda #<{c1}
clc
adc {m2}
sta {m1}
lda #>{c1}
adc {m2}+1
sta {m1}+1

View File

@ -0,0 +1,6 @@
clc
adc {m1}
sta {m1}
bcc !+
inc {m1}+1
!:

View File

@ -0,0 +1,7 @@
lda {m1}
clc
adc {m2}
sta {m1}
lda {m1}+1
adc {m2}+1
sta {m1}+1

View File

@ -0,0 +1,4 @@
lda {m2}
sta {m1}
lda {m2}+1
sta {m1}+1

View File

@ -0,0 +1,7 @@
sec
lda {m2}
sbc #{c1}
sta {m1}
lda {m2}+1
sbc #0
sta {m1}+1

View File

@ -0,0 +1,6 @@
clc
adc {m2}
sta {m1}
lda #0
adc {m2}+1
sta {m1}+1

View File

@ -0,0 +1,7 @@
lda {m2}
clc
adc {m1}
sta {m1}
lda {m2}+1
adc {m1}+1
sta {m1}+1

View File

@ -0,0 +1,7 @@
lda {m2}
clc
adc {m3}
sta {m1}
lda {m2}+1
adc {m3}+1
sta {m1}+1

View File

@ -9,7 +9,9 @@ import dk.camelot64.kickc.model.statements.Statement;
import dk.camelot64.kickc.model.statements.StatementAssignment;
import dk.camelot64.kickc.model.statements.StatementConditionalJump;
import dk.camelot64.kickc.model.statements.StatementExprSideEffect;
import dk.camelot64.kickc.model.symbols.*;
import dk.camelot64.kickc.model.symbols.Label;
import dk.camelot64.kickc.model.symbols.Symbol;
import dk.camelot64.kickc.model.symbols.Variable;
import dk.camelot64.kickc.model.types.*;
import dk.camelot64.kickc.model.values.*;
@ -144,8 +146,8 @@ public class AsmFragmentInstanceSpecFactory {
private String assignmentRightSideSignature(RValue rValue1, Operator operator, RValue rValue2) {
final SymbolType rValue1Type = rValue1==null?null:SymbolTypeInference.inferType(program.getScope(), rValue1);
final SymbolType rValue2Type = rValue2==null?null:SymbolTypeInference.inferType(program.getScope(), rValue2);
final SymbolType rValue1Type = rValue1 == null ? null : SymbolTypeInference.inferType(program.getScope(), rValue1);
final SymbolType rValue2Type = rValue2 == null ? null : SymbolTypeInference.inferType(program.getScope(), rValue2);
StringBuilder signature = new StringBuilder();
if(rValue1 != null) {
@ -427,51 +429,53 @@ public class AsmFragmentInstanceSpecFactory {
* @return The type name
*/
static String getTypePrefix(SymbolType type) {
if(SymbolType.BYTE.equals(type)) {
return "vbu";
} else if(SymbolType.SBYTE.equals(type)) {
return "vbs";
} else if(SymbolType.WORD.equals(type)) {
return "vwu";
} else if(SymbolType.SWORD.equals(type)) {
return "vws";
} else if(SymbolType.DWORD.equals(type)) {
return "vdu";
} else if(SymbolType.SDWORD.equals(type)) {
return "vds";
} else if(SymbolType.BOOLEAN.equals(type)) {
return "vbo";
} else if(type instanceof SymbolTypeStruct) {
return "vss";
} else if(type instanceof SymbolTypePointer) {
SymbolType elementType = ((SymbolTypePointer) type).getElementType();
if(SymbolType.BYTE.equals(elementType)) {
return "pbu";
} else if(SymbolType.SBYTE.equals(elementType)) {
return "pbs";
} else if(SymbolType.WORD.equals(elementType)) {
return "pwu";
} else if(SymbolType.SWORD.equals(elementType)) {
return "pws";
} else if(SymbolType.DWORD.equals(elementType)) {
return "pdu";
} else if(SymbolType.SDWORD.equals(elementType)) {
return "pds";
} else if(SymbolType.BOOLEAN.equals(elementType)) {
return "pbo";
} else if(SymbolType.VOID.equals(elementType)) {
return "pvo";
} else if(elementType instanceof SymbolTypeProcedure) {
return "ppr";
} else if(elementType instanceof SymbolTypePointer) {
return "ppt";
} else if(elementType instanceof SymbolTypeStruct) {
return "pss";
if(type instanceof SymbolTypePointer) {
SymbolType elmType = ((SymbolTypePointer) type).getElementType();
if(elmType instanceof SymbolTypePointer) {
SymbolType eml2Type = ((SymbolTypePointer) elmType).getElementType();
if(eml2Type instanceof SymbolTypePointer) {
throw new RuntimeException("Not implemented " + type);
} else {
return "q" + getBaseTypePrefix(eml2Type);
}
} else {
throw new RuntimeException("Not implemented " + type);
return "p" + getBaseTypePrefix(elmType);
}
} else {
throw new RuntimeException("Not implemented " + type);
return "v" + getBaseTypePrefix(type);
}
}
/**
* Get the base symbol type part of the binding name (eg. bu/ws/...).
* This only handles basic types (not pointers)
*
* @param baseType The basic type
* @return The 2-letter base type name (eg. bu/ws/...).
*/
static String getBaseTypePrefix(SymbolType baseType) {
if(SymbolType.BYTE.equals(baseType)) {
return "bu";
} else if(SymbolType.SBYTE.equals(baseType)) {
return "bs";
} else if(SymbolType.WORD.equals(baseType)) {
return "wu";
} else if(SymbolType.SWORD.equals(baseType)) {
return "ws";
} else if(SymbolType.DWORD.equals(baseType)) {
return "du";
} else if(SymbolType.SDWORD.equals(baseType)) {
return "ds";
} else if(SymbolType.VOID.equals(baseType)) {
return "vo";
} else if(SymbolType.BOOLEAN.equals(baseType)) {
return "bo";
} else if(baseType instanceof SymbolTypeStruct) {
return "ss";
} else if(baseType instanceof SymbolTypeProcedure) {
return "pr";
} else {
throw new InternalError("Not implemented " + baseType);
}
}

View File

@ -712,7 +712,9 @@ class AsmFragmentTemplateSynthesisRule {
// Synthesize typed pointer math using void pointers
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)p[^v][^o]([czm][1-9])(.*)", null, null, "$1pvo$2$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)p[^v][^o]([czm][1-9])(.*p.*)", null, null, "$1pvo$2$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)p[^v][^o]([czm][1-9])(.*[pq].*)", null, null, "$1pvo$2$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)q[^v][^o]([czm][1-9])(.*)", null, null, "$1qvo$2$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)q[^v][^o]([czm][1-9])(.*[pq].*)", null, null, "$1qvo$2$3", null, null));
// Synthesize some constant pointers as constant words (remove when the above section can be included)
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_(lt|gt|le|ge|eq|neq)_p..([czm].)_then_(.*)", null, null, "$1_$2_vwu$3_then_$4", null, null));

View File

@ -1048,6 +1048,11 @@ public class TestPrograms {
assertError("function-as-array.c", "Error! Dereferencing a non-pointer type void()");
}
//@Test
//public void testFunctionInfiniteLoop() throws IOException, URISyntaxException {
// compileAndCompare("function-infinite-loop.c");
//}
@Test
public void testCodeAfterReturn1() throws IOException, URISyntaxException {
compileAndCompare("code-after-return-1.c");

View File

@ -0,0 +1,15 @@
// Test a function returning a value that has an infinite loop
// https://gitlab.com/camelot/kickc/-/issues/310
char * const SCREEN = 0x0400;
void main() {
SCREEN[0] = get(7);
SCREEN[0] = get(5);
}
char get(char x) {
while(1)
x++;
return x+4;
}