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:
parent
d9c387665c
commit
50d034a5a2
@ -1,4 +1,4 @@
|
||||
//KICKC FRAGMENT CACHE 12e560f399
|
||||
//KICKC FRAGMENT CACHE 125a7c9d20
|
||||
//FRAGMENT vbuz1=vbuc1
|
||||
lda #{c1}
|
||||
sta {z1}
|
||||
|
17734
src/main/fragment/cache/fragment-cache-mos6502x.asm
vendored
17734
src/main/fragment/cache/fragment-cache-mos6502x.asm
vendored
File diff suppressed because it is too large
Load Diff
@ -1,4 +0,0 @@
|
||||
lda {m1}
|
||||
sta {c1},x
|
||||
lda {m1}+1
|
||||
sta {c1}+1,x
|
@ -1,5 +0,0 @@
|
||||
lda {m2}
|
||||
sta ({z1}),y
|
||||
iny
|
||||
lda {m2}+1
|
||||
sta ({z1}),y
|
3
src/main/fragment/mos6502-common/qvom1=qvoaa.asm
Normal file
3
src/main/fragment/mos6502-common/qvom1=qvoaa.asm
Normal file
@ -0,0 +1,3 @@
|
||||
sta {m1}
|
||||
lda #0
|
||||
sta {m1}+1
|
4
src/main/fragment/mos6502-common/qvom1=qvoc1.asm
Normal file
4
src/main/fragment/mos6502-common/qvom1=qvoc1.asm
Normal file
@ -0,0 +1,4 @@
|
||||
lda #<{c1}
|
||||
sta {m1}
|
||||
lda #>{c1}
|
||||
sta {m1}+1
|
@ -0,0 +1,7 @@
|
||||
lda #<{c1}
|
||||
clc
|
||||
adc {m1}
|
||||
sta {m1}
|
||||
lda #>{c1}
|
||||
adc {m1}+1
|
||||
sta {m1}+1
|
@ -0,0 +1,7 @@
|
||||
lda #<{c1}
|
||||
clc
|
||||
adc {m2}
|
||||
sta {m1}
|
||||
lda #>{c1}
|
||||
adc {m2}+1
|
||||
sta {m1}+1
|
@ -0,0 +1,6 @@
|
||||
clc
|
||||
adc {m1}
|
||||
sta {m1}
|
||||
bcc !+
|
||||
inc {m1}+1
|
||||
!:
|
@ -0,0 +1,7 @@
|
||||
lda {m1}
|
||||
clc
|
||||
adc {m2}
|
||||
sta {m1}
|
||||
lda {m1}+1
|
||||
adc {m2}+1
|
||||
sta {m1}+1
|
4
src/main/fragment/mos6502-common/qvom1=qvom2.asm
Normal file
4
src/main/fragment/mos6502-common/qvom1=qvom2.asm
Normal file
@ -0,0 +1,4 @@
|
||||
lda {m2}
|
||||
sta {m1}
|
||||
lda {m2}+1
|
||||
sta {m1}+1
|
@ -0,0 +1,7 @@
|
||||
sec
|
||||
lda {m2}
|
||||
sbc #{c1}
|
||||
sta {m1}
|
||||
lda {m2}+1
|
||||
sbc #0
|
||||
sta {m1}+1
|
@ -0,0 +1,6 @@
|
||||
clc
|
||||
adc {m2}
|
||||
sta {m1}
|
||||
lda #0
|
||||
adc {m2}+1
|
||||
sta {m1}+1
|
@ -0,0 +1,7 @@
|
||||
lda {m2}
|
||||
clc
|
||||
adc {m1}
|
||||
sta {m1}
|
||||
lda {m2}+1
|
||||
adc {m1}+1
|
||||
sta {m1}+1
|
@ -0,0 +1,7 @@
|
||||
lda {m2}
|
||||
clc
|
||||
adc {m3}
|
||||
sta {m1}
|
||||
lda {m2}+1
|
||||
adc {m3}+1
|
||||
sta {m1}+1
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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");
|
||||
|
15
src/test/kc/function-infinite-loop.c
Normal file
15
src/test/kc/function-infinite-loop.c
Normal 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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user