1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-12-26 03:32:23 +00:00

#666 Moved intermediate variable creation into VariableBuilder in preparation for fix of memory area.

This commit is contained in:
jespergravgaard 2021-06-06 22:23:14 +02:00
commit 78e378a8e1
35 changed files with 5108 additions and 17856 deletions

2
.idea/compiler.xml generated
View File

@ -24,7 +24,7 @@
</profile>
</annotationProcessing>
<bytecodeTargetLevel>
<module name="kickc" target="11" />
<module name="kickc" target="8" />
</bytecodeTargetLevel>
</component>
</project>

2
.idea/misc.xml generated
View File

@ -43,7 +43,7 @@
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="false" project-jdk-name="14" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="false" project-jdk-name="15" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE 11e0ba6c6b 11e0ba8c9f
//KICKC FRAGMENT CACHE 11c7923005 11c7925062
//FRAGMENT vbuz1=vbuc1
lda #{c1}
sta {z1}

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE 11e0ba6c6b 11e0ba8c9f
//KICKC FRAGMENT CACHE 11c7923005 11c7925062
//FRAGMENT _deref_pbuc1=_inc__deref_pbuc1
inc {c1}
//FRAGMENT isr_hardware_all_entry
@ -792,401 +792,3 @@ iny
tax
//FRAGMENT vbuyy=vbuaa
tay
//FRAGMENT vbuz1=vbuz2_band_vbuc1
lda #{c1}
and {z2}
sta {z1}
//FRAGMENT _deref_pbuc1=_dec__deref_pbuc1
dec {c1}
//FRAGMENT pbuz1=pbuc1_plus_vbuz2
lda {z2}
clc
adc #<{c1}
sta {z1}
lda #>{c1}
adc #0
sta {z1}+1
//FRAGMENT pvoz1=pvoz2
lda {z2}
sta {z1}
lda {z2}+1
sta {z1}+1
//FRAGMENT vbuz1=vbuz1_plus_2
lda {z1}
clc
adc #2
sta {z1}
//FRAGMENT vbuz1=pbuz2_derefidx_vbuc1
ldy #{c1}
lda ({z2}),y
sta {z1}
//FRAGMENT pbuz1=pbuz2_plus_vbuc1
lda #{c1}
clc
adc {z2}
sta {z1}
lda #0
adc {z2}+1
sta {z1}+1
//FRAGMENT pbuz1_neq_pbuc1_then_la1
lda {z1}+1
cmp #>{c1}
bne {la1}
lda {z1}
cmp #<{c1}
bne {la1}
//FRAGMENT _deref_pbuz1=_deref_pbuz2
ldy #0
lda ({z2}),y
ldy #0
sta ({z1}),y
//FRAGMENT vbuz1=vbuaa_band_vbuc1
and #{c1}
sta {z1}
//FRAGMENT vbuz1=vbuxx_band_vbuc1
lda #{c1}
sax {z1}
//FRAGMENT vbuz1=vbuyy_band_vbuc1
tya
and #{c1}
sta {z1}
//FRAGMENT vbuaa=vbuz1_band_vbuc1
lda #{c1}
and {z1}
//FRAGMENT vbuaa=vbuaa_band_vbuc1
and #{c1}
//FRAGMENT vbuaa=vbuxx_band_vbuc1
txa
and #{c1}
//FRAGMENT vbuaa=vbuyy_band_vbuc1
tya
and #{c1}
//FRAGMENT vbuxx=vbuz1_band_vbuc1
lda #{c1}
and {z1}
tax
//FRAGMENT vbuxx=vbuaa_band_vbuc1
ldx #{c1}
axs #0
//FRAGMENT vbuyy=vbuz1_band_vbuc1
lda #{c1}
and {z1}
tay
//FRAGMENT pbuz1=pbuc1_plus_vbuaa
clc
adc #<{c1}
sta {z1}
lda #>{c1}
adc #0
sta {z1}+1
//FRAGMENT pbuz1=pbuc1_plus_vbuxx
txa
clc
adc #<{c1}
sta {z1}
lda #>{c1}
adc #0
sta {z1}+1
//FRAGMENT pbuz1=pbuc1_plus_vbuyy
tya
clc
adc #<{c1}
sta {z1}
lda #>{c1}
adc #0
sta {z1}+1
//FRAGMENT vbuxx=vbuxx_plus_2
inx
inx
//FRAGMENT vbuaa=pbuz1_derefidx_vbuc1
ldy #{c1}
lda ({z1}),y
//FRAGMENT vbuxx=pbuz1_derefidx_vbuc1
ldy #{c1}
lda ({z1}),y
tax
//FRAGMENT vbuyy=pbuz1_derefidx_vbuc1
ldy #{c1}
lda ({z1}),y
tay
//FRAGMENT pbuz1=pbuz1_plus_vbuc1
lda #{c1}
clc
adc {z1}
sta {z1}
bcc !+
inc {z1}+1
!:
//FRAGMENT vbuz1=_dec_vbuz1
dec {z1}
//FRAGMENT pbuz1=pbuz2
lda {z2}
sta {z1}
lda {z2}+1
sta {z1}+1
//FRAGMENT _deref_pbuz1=pbuc1_derefidx_vbuz2
ldy {z2}
lda {c1},y
ldy #0
sta ({z1}),y
//FRAGMENT pbuz1=_inc_pbuz2
clc
lda {z2}
adc #1
sta {z1}
lda {z2}+1
adc #0
sta {z1}+1
//FRAGMENT _deref_pbuz1=vbuc1
lda #{c1}
ldy #0
sta ({z1}),y
//FRAGMENT vbuz1=pbuc1_derefidx_vbuz2
ldy {z2}
lda {c1},y
sta {z1}
//FRAGMENT vbuz1_ge_vbuz2_then_la1
lda {z1}
cmp {z2}
bcs {la1}
//FRAGMENT vbuz1=vbuz1_minus_vbuz2
lda {z1}
sec
sbc {z2}
sta {z1}
//FRAGMENT vwuz1=_word_vbuz2
lda {z2}
sta {z1}
lda #0
sta {z1}+1
//FRAGMENT vwuz1=vwuz2_rol_5
lda {z2}
asl
sta {z1}
lda {z2}+1
rol
sta {z1}+1
asl {z1}
rol {z1}+1
asl {z1}
rol {z1}+1
asl {z1}
rol {z1}+1
asl {z1}
rol {z1}+1
//FRAGMENT pbuz1=pbuc1_plus_vwuz2
clc
lda {z2}
adc #<{c1}
sta {z1}
lda {z2}+1
adc #>{c1}
sta {z1}+1
//FRAGMENT pbuz1=pbuz2_plus_vbuz3
lda {z3}
clc
adc {z2}
sta {z1}
lda #0
adc {z2}+1
sta {z1}+1
//FRAGMENT pbuz1=pbuz1_minus_vbuc1
sec
lda {z1}
sbc #{c1}
sta {z1}
lda {z1}+1
sbc #0
sta {z1}+1
//FRAGMENT vbuz1=_deref_pbuc1
lda {c1}
sta {z1}
//FRAGMENT _deref_pbuz1=vbuz2
lda {z2}
ldy #0
sta ({z1}),y
//FRAGMENT vbuxx=vbuxx_band_vbuc1
lda #{c1}
axs #0
//FRAGMENT vbuyy=vbuxx_band_vbuc1
txa
and #{c1}
tay
//FRAGMENT vbuxx=vbuyy_band_vbuc1
ldx #{c1}
tya
axs #0
//FRAGMENT vbuyy=vbuyy_band_vbuc1
tya
and #{c1}
tay
//FRAGMENT _deref_pbuz1=pbuc1_derefidx_vbuaa
tay
lda {c1},y
ldy #0
sta ({z1}),y
//FRAGMENT _deref_pbuz1=pbuc1_derefidx_vbuxx
lda {c1},x
ldy #0
sta ({z1}),y
//FRAGMENT _deref_pbuz1=pbuc1_derefidx_vbuyy
lda {c1},y
ldy #0
sta ({z1}),y
//FRAGMENT vbuaa=pbuc1_derefidx_vbuz1
ldy {z1}
lda {c1},y
//FRAGMENT vbuxx=pbuc1_derefidx_vbuz1
ldy {z1}
ldx {c1},y
//FRAGMENT vbuyy=pbuc1_derefidx_vbuz1
ldx {z1}
ldy {c1},x
//FRAGMENT vbuz1=pbuc1_derefidx_vbuaa
tay
lda {c1},y
sta {z1}
//FRAGMENT vbuaa=pbuc1_derefidx_vbuaa
tay
lda {c1},y
//FRAGMENT vbuxx=pbuc1_derefidx_vbuaa
tay
ldx {c1},y
//FRAGMENT vbuyy=pbuc1_derefidx_vbuaa
tax
ldy {c1},x
//FRAGMENT vbuz1=pbuc1_derefidx_vbuxx
lda {c1},x
sta {z1}
//FRAGMENT 0_neq_vbuaa_then_la1
cmp #0
bne {la1}
//FRAGMENT vbuaa_ge_vbuz1_then_la1
cmp {z1}
bcs {la1}
//FRAGMENT vbuxx=vbuxx_minus_vbuz1
txa
sec
sbc {z1}
tax
//FRAGMENT vbuz1=vbuz1_minus_vbuaa
eor #$ff
sec
adc {z1}
sta {z1}
//FRAGMENT vbuxx=vbuxx_minus_vbuaa
sta $ff
txa
sec
sbc $ff
tax
//FRAGMENT vbuz1=vbuz1_minus_vbuxx
txa
eor #$ff
sec
adc {z1}
sta {z1}
//FRAGMENT vbuxx=vbuxx_minus_vbuxx
lda #0
tax
//FRAGMENT vbuz1=vbuz1_minus_vbuyy
tya
eor #$ff
sec
adc {z1}
sta {z1}
//FRAGMENT vbuxx=vbuxx_minus_vbuyy
txa
sty $ff
sec
sbc $ff
tax
//FRAGMENT vwuz1=_word_vbuaa
sta {z1}
lda #0
sta {z1}+1
//FRAGMENT vwuz1=_word_vbuxx
txa
sta {z1}
lda #0
sta {z1}+1
//FRAGMENT vwuz1=_word_vbuyy
tya
sta {z1}
lda #0
sta {z1}+1
//FRAGMENT vbuaa_eq_vbuc1_then_la1
cmp #{c1}
beq {la1}
//FRAGMENT vbuaa=_deref_pbuc1
lda {c1}
//FRAGMENT vbuxx=_deref_pbuc1
ldx {c1}
//FRAGMENT _deref_pbuz1=vbuaa
ldy #0
sta ({z1}),y
//FRAGMENT _deref_pbuz1=vbuxx
txa
ldy #0
sta ({z1}),y
//FRAGMENT _deref_pbuz1=vbuyy
tya
ldy #0
sta ({z1}),y
//FRAGMENT vbuxx_ge_vbuz1_then_la1
cpx {z1}
bcs {la1}
//FRAGMENT vbuxx_eq_vbuc1_then_la1
cpx #{c1}
beq {la1}
//FRAGMENT vbuyy=_deref_pbuc1
ldy {c1}
//FRAGMENT vbuz1_ge_vbuxx_then_la1
lda {z1}
stx $ff
cmp $ff
bcs {la1}
//FRAGMENT vbuz1_ge_vbuyy_then_la1
lda {z1}
sty $ff
cmp $ff
bcs {la1}
//FRAGMENT vbuxx_ge_vbuyy_then_la1
sty $ff
cpx $ff
bcs {la1}
//FRAGMENT vbuaa=vbuxx
txa
//FRAGMENT vbuyy=vbuxx
txa
tay
//FRAGMENT vbuyy_eq_vbuc1_then_la1
cpy #{c1}
beq {la1}
//FRAGMENT vbuaa=vbuyy
tya
//FRAGMENT vbuxx=vbuyy
tya
tax
//FRAGMENT vbuyy_ge_vbuz1_then_la1
cpy {z1}
bcs {la1}
//FRAGMENT vwuz1=vwuz1_rol_5
asl {z1}
rol {z1}+1
asl {z1}
rol {z1}+1
asl {z1}
rol {z1}+1
asl {z1}
rol {z1}+1
asl {z1}
rol {z1}+1
//FRAGMENT pbuz1=pbuc1_plus_vwuz1
clc
lda {z1}
adc #<{c1}
sta {z1}
lda {z1}+1
adc #>{c1}
sta {z1}+1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,4 @@
inc {c1}
bne !+
inc {c1}+1
!:

View File

@ -0,0 +1,8 @@
sec
lda ({z2}),y
sbc {m3}
sta {m1}
iny
lda ({z2}),y
sbc {m3}+1
sta {m1}+1

View File

@ -0,0 +1,8 @@
ldy #1
lda {m1}+1
cmp ({z2}),y
bne {la1}
dey
lda {m1}
cmp ({z2}),y
bne {la1}

View File

@ -0,0 +1,7 @@
lda {m1}
cmp ({z2}),y
bne {la1}
iny
lda {m1}
cmp ({z2}),y
bne {la1}

View File

@ -0,0 +1,10 @@
sec
lda ({z1}),y
sbc {m2}
pha
iny
lda ({z1}),y
sbc {m2}+1
sta {z1}+1
pla
sta {z1}

View File

@ -8,6 +8,7 @@ import dk.camelot64.kickc.model.TargetCpu;
import dk.camelot64.kickc.model.statements.StatementSource;
import dk.camelot64.kickc.model.symbols.Label;
import dk.camelot64.kickc.model.symbols.ProgramScope;
import dk.camelot64.kickc.model.symbols.Scope;
import dk.camelot64.kickc.model.symbols.Variable;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.values.ConstantInteger;
@ -74,6 +75,34 @@ public class AsmFragmentTemplate {
this.targetCpu = targetCpu;
}
/**
* Create a load/store variable
*
* @param name The name
* @param type The type
* @param scope The scope
* @param memoryArea The memory area (zeropage/main memory)
* @param dataSegment The data segment (in main memory)
* @return The new PHI-master variable
*/
public static Variable createLoadStore(String name, SymbolType type, Scope scope, Variable.MemoryArea memoryArea, String dataSegment) {
return new Variable(name, Variable.Kind.LOAD_STORE, type, scope, memoryArea, dataSegment, null);
}
/**
* Create a PHI master variable
*
* @param name The name
* @param type The type
* @param scope The scope
* @param memoryArea The memory area (zeropage/main memory)
* @param dataSegment The data segment (in main memory)
* @return The new PHI-master variable
*/
public static Variable createPhiMaster(String name, SymbolType type, Scope scope, Variable.MemoryArea memoryArea, String dataSegment) {
return new Variable(name, Variable.Kind.PHI_MASTER, type, scope, memoryArea, dataSegment, null);
}
/**
* Initialize the fields that require parsing the ASM (bodyAsm, clobber, cycles).
*/
@ -84,7 +113,7 @@ public class AsmFragmentTemplate {
ProgramScope scope = new ProgramScope();
LinkedHashMap<String, Value> bindings = new LinkedHashMap<>();
{
Variable master = Variable.createPhiMaster("z", SymbolType.BYTE, scope, Variable.MemoryArea.ZEROPAGE_MEMORY, null);
Variable master = createPhiMaster("z", SymbolType.BYTE, scope, Variable.MemoryArea.ZEROPAGE_MEMORY, null);
Variable v1 = Variable.createPhiVersion(master, 1); v1.setName("z1");
Variable v2 = Variable.createPhiVersion(master, 2); v2.setName("z2");
Variable v3 = Variable.createPhiVersion(master, 3); v3.setName("z3");
@ -105,12 +134,12 @@ public class AsmFragmentTemplate {
if(signature.contains("z6")) bindings.put("z6", v6);
}
{
Variable v1 = Variable.createLoadStore("m1", SymbolType.BYTE, scope, Variable.MemoryArea.MAIN_MEMORY, null);
Variable v2 = Variable.createLoadStore("m2", SymbolType.BYTE, scope, Variable.MemoryArea.MAIN_MEMORY, null);
Variable v3 = Variable.createLoadStore("m3", SymbolType.BYTE, scope, Variable.MemoryArea.MAIN_MEMORY, null);
Variable v4 = Variable.createLoadStore("m4", SymbolType.BYTE, scope, Variable.MemoryArea.MAIN_MEMORY, null);
Variable v5 = Variable.createLoadStore("m5", SymbolType.BYTE, scope, Variable.MemoryArea.MAIN_MEMORY, null);
Variable v6 = Variable.createLoadStore("m6", SymbolType.BYTE, scope, Variable.MemoryArea.MAIN_MEMORY, null);
Variable v1 = createLoadStore("m1", SymbolType.BYTE, scope, Variable.MemoryArea.MAIN_MEMORY, null);
Variable v2 = createLoadStore("m2", SymbolType.BYTE, scope, Variable.MemoryArea.MAIN_MEMORY, null);
Variable v3 = createLoadStore("m3", SymbolType.BYTE, scope, Variable.MemoryArea.MAIN_MEMORY, null);
Variable v4 = createLoadStore("m4", SymbolType.BYTE, scope, Variable.MemoryArea.MAIN_MEMORY, null);
Variable v5 = createLoadStore("m5", SymbolType.BYTE, scope, Variable.MemoryArea.MAIN_MEMORY, null);
Variable v6 = createLoadStore("m6", SymbolType.BYTE, scope, Variable.MemoryArea.MAIN_MEMORY, null);
v1.setAllocation(new Registers.RegisterMainMem(v1.getVariableRef(), 1, null));
v2.setAllocation(new Registers.RegisterMainMem(v2.getVariableRef(), 1, null));
v3.setAllocation(new Registers.RegisterMainMem(v3.getVariableRef(), 1, null));

View File

@ -23,6 +23,9 @@ public class VariableBuilder {
/** The scope of the variable. */
private Scope scope;
/** The variable is an intermediate variable. */
private boolean isIntermediate;
/** The variable is a function parameter declaration. */
private boolean isParameter;
@ -38,9 +41,10 @@ public class VariableBuilder {
/** Configuration of how to setup optimization/memory area for variables. */
private VariableBuilderConfig config;
public VariableBuilder(String varName, Scope scope, boolean isParameter, SymbolType type, List<Directive> directives, String dataSegment, VariableBuilderConfig config) {
public VariableBuilder(String varName, Scope scope, boolean isParameter, boolean isIntermediate, SymbolType type, List<Directive> directives, String dataSegment, VariableBuilderConfig config) {
this.varName = varName;
this.scope = scope;
this.isIntermediate = isIntermediate;
this.isParameter = isParameter;
this.type = type;
this.directives = directives;
@ -48,6 +52,18 @@ public class VariableBuilder {
this.config = config;
}
/**
* Create a variable builder for an intermediate variable
* @param scope The scope to create the intermediate variable in
* @param type The variable type
* @param program The global program
* @return The new intermediate variable
*/
public static Variable createIntermediate(Scope scope, SymbolType type, Program program) {
VariableBuilder builder = new VariableBuilder(scope.allocateIntermediateVariableName(), scope, false, true, type, null, scope.getSegmentData(), program.getTargetPlatform().getVariableBuilderConfig());
return builder.build();
}
/**
* Build the variable with the properties derived from type, scope, directives and configuration.
*
@ -156,6 +172,19 @@ public class VariableBuilder {
return (s instanceof Procedure) && !isParameter;
}
/**
* Is the variable a (local) intermediate variable in a function
*
* @return true if the variable is an intermediate variable in a function scope
*/
public boolean isScopeIntermediate() {
if(isIntermediate) {
if(isScopeGlobal()) throw new RuntimeException("Globa intermediate not supported");
return true;
} else
return false;
}
/**
* Is the variable a member of a struct definition
*
@ -166,7 +195,16 @@ public class VariableBuilder {
}
/**
* Is the variable an array declaration
* Is the variable an intermediate variable
*
* @return true if the variable is intermediate
*/
public boolean isIntermediate() {
return isIntermediate;
}
/**
* Is the variable an array declaration
*
* @return true if the variable is an array declaration
*/
@ -264,7 +302,7 @@ public class VariableBuilder {
// volatile variables must be load/store
return false;
else {
VariableBuilderConfig.Scope scope = VariableBuilderConfig.getScope(isScopeGlobal(), isScopeLocal(), isScopeParameter(), isScopeMember());
VariableBuilderConfig.Scope scope = VariableBuilderConfig.getScope(isScopeGlobal(), isScopeLocal(), isScopeIntermediate(), isScopeParameter(), isScopeMember());
VariableBuilderConfig.Type type = VariableBuilderConfig.getType(isTypeInteger(), isArray(), isTypePointer(), isTypeStruct());
VariableBuilderConfig.Setting setting = config.getSetting(scope, type);
if(setting != null && VariableBuilderConfig.Optimization.MA.equals(setting.optimization))
@ -280,7 +318,9 @@ public class VariableBuilder {
* @return The variable kind
*/
public Variable.Kind getKind() {
if(isConstant())
if(isIntermediate()) {
return Variable.Kind.INTERMEDIATE;
} else if(isConstant())
return Variable.Kind.CONSTANT;
else if(isSingleStaticAssignment())
return Variable.Kind.PHI_MASTER;
@ -310,13 +350,17 @@ public class VariableBuilder {
else if(!isConstant() && isOptimize())
return Variable.MemoryArea.ZEROPAGE_MEMORY;
else {
VariableBuilderConfig.Scope scope = VariableBuilderConfig.getScope(isScopeGlobal(), isScopeLocal(), isScopeParameter(), isScopeMember());
VariableBuilderConfig.Type type = VariableBuilderConfig.getType(isTypeInteger(), isArray(), isTypePointer(), isTypeStruct());
VariableBuilderConfig.Setting setting = config.getSetting(scope, type);
if(setting != null && VariableBuilderConfig.MemoryArea.MEM.equals(setting.memoryArea))
return Variable.MemoryArea.MAIN_MEMORY;
else
VariableBuilderConfig.Scope scope = VariableBuilderConfig.getScope(isScopeGlobal(), isScopeLocal(), isScopeIntermediate(), isScopeParameter(), isScopeMember());
if(scope.equals(VariableBuilderConfig.Scope.INTERMEDIATE)) {
return Variable.MemoryArea.ZEROPAGE_MEMORY;
} else {
VariableBuilderConfig.Type type = VariableBuilderConfig.getType(isTypeInteger(), isArray(), isTypePointer(), isTypeStruct());
VariableBuilderConfig.Setting setting = config.getSetting(scope, type);
if(setting != null && VariableBuilderConfig.MemoryArea.MEM.equals(setting.memoryArea))
return Variable.MemoryArea.MAIN_MEMORY;
else
return Variable.MemoryArea.ZEROPAGE_MEMORY;
}
}
}

View File

@ -9,7 +9,7 @@ import java.util.*;
* Holds settings specified using <code>#pragma var_model(...)</code>
* The parameters to the pragma has the form <i>scope</i>_<i>type</i>_<i>optimization</i>_<i>memoryarea</i>.
* <ul>
* <li><i>scope</i> is one of <i>global</i>, <i>local</i> or <i>parameter</i></li>
* <li><i>scope</i> is one of <i>global</i>, <i>local</i>, <i>intermediate</i>, <i>parameter</i> or <i>member</i></li>
* <li><i>type</i> is one of <i>struct</i>, <i>array</i>, <i>integer</i>, <i>pointer</i></li>
* <li><i>optimization</i> is one of <i>ma</i> (meaning multiple-assignment or load/store), <i>ssa</i> (meaning single-static-assignment)</li>
* <li><i>memoryarea</i> is one of <i>zp</i> (meaning zeropage), <i>mem</i> (meaning main memory)</li>
@ -97,7 +97,7 @@ public class VariableBuilderConfig {
/** The different scopes. */
public enum Scope {
LOCAL, GLOBAL, PARAMETER, MEMBER
INTERMEDIATE, LOCAL, GLOBAL, PARAMETER, MEMBER
}
/** The different types. */
@ -289,9 +289,11 @@ public class VariableBuilderConfig {
return settings.get(new ScopeType(scope, type));
}
public static Scope getScope(boolean isScopeGlobal, boolean isScopeLocal, boolean isScopeParameter, boolean isScopeMember) {
public static Scope getScope(boolean isScopeGlobal, boolean isScopeLocal, boolean isScopeIntermediate, boolean isScopeParameter, boolean isScopeMember) {
if(isScopeGlobal)
return Scope.GLOBAL;
if(isScopeIntermediate)
return Scope.INTERMEDIATE;
if(isScopeLocal)
return Scope.LOCAL;
if(isScopeParameter)

View File

@ -2,6 +2,8 @@ package dk.camelot64.kickc.model.iterator;
import dk.camelot64.kickc.model.Comment;
import dk.camelot64.kickc.model.InternalError;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.VariableBuilder;
import dk.camelot64.kickc.model.operators.OperatorBinary;
import dk.camelot64.kickc.model.operators.Operators;
import dk.camelot64.kickc.model.statements.Statement;
@ -48,14 +50,14 @@ public interface ProgramExpressionBinary extends ProgramExpression {
*
* @param toType The toType to cast to
*/
void addLeftCast(SymbolType toType, ListIterator<Statement> stmtIt, ScopeRef currentScope, ProgramScope symbols);
void addLeftCast(SymbolType toType, ListIterator<Statement> stmtIt, ScopeRef currentScope, Program program);
/**
* Adds a cast to the right operand
*
* @param toType The toType to cast to
*/
void addRightCast(SymbolType toType, ListIterator<Statement> stmtIt, ScopeRef currentScope, ProgramScope symbols);
void addRightCast(SymbolType toType, ListIterator<Statement> stmtIt, ScopeRef currentScope, Program program);
/**
* Get the left operand as a replaceable program value
@ -124,13 +126,12 @@ public interface ProgramExpressionBinary extends ProgramExpression {
}
@Override
public void addLeftCast(SymbolType toType, ListIterator<Statement> stmtIt, ScopeRef currentScope, ProgramScope symbols) {
public void addLeftCast(SymbolType toType, ListIterator<Statement> stmtIt, ScopeRef currentScope, Program program) {
if(assignment.getrValue1() instanceof ConstantValue) {
assignment.setrValue1(new ConstantCastValue(toType, (ConstantValue) assignment.getrValue1()));
} else {
Scope blockScope = symbols.getScope(currentScope);
Variable tmpVar = blockScope.addVariableIntermediate();
tmpVar.setType(toType);
Scope blockScope = program.getScope().getScope(currentScope);
Variable tmpVar = VariableBuilder.createIntermediate(blockScope, toType, program);
StatementAssignment newAssignment = new StatementAssignment((LValue) tmpVar.getRef(), Operators.getCastUnary(toType), assignment.getrValue1(), true, assignment.getSource(), Comment.NO_COMMENTS);
assignment.setrValue1(tmpVar.getRef());
stmtIt.previous();
@ -140,13 +141,12 @@ public interface ProgramExpressionBinary extends ProgramExpression {
}
@Override
public void addRightCast(SymbolType toType, ListIterator<Statement> stmtIt, ScopeRef currentScope, ProgramScope symbols) {
public void addRightCast(SymbolType toType, ListIterator<Statement> stmtIt, ScopeRef currentScope, Program program) {
if(assignment.getrValue2() instanceof ConstantValue) {
assignment.setrValue2(new ConstantCastValue(toType, (ConstantValue) assignment.getrValue2()));
} else {
Scope blockScope = symbols.getScope(currentScope);
Variable tmpVar = blockScope.addVariableIntermediate();
tmpVar.setType(toType);
Scope blockScope = program.getScope().getScope(currentScope);
Variable tmpVar = VariableBuilder.createIntermediate(blockScope, toType, program);
StatementAssignment newAssignment = new StatementAssignment((LValue) tmpVar.getRef(), Operators.getCastUnary(toType), assignment.getrValue2(), true, assignment.getSource(), Comment.NO_COMMENTS);
assignment.setrValue2(tmpVar.getRef());
stmtIt.previous();
@ -202,12 +202,12 @@ public interface ProgramExpressionBinary extends ProgramExpression {
}
@Override
public void addLeftCast(SymbolType toType, ListIterator<Statement> stmtIt, ScopeRef currentScope, ProgramScope symbols) {
public void addLeftCast(SymbolType toType, ListIterator<Statement> stmtIt, ScopeRef currentScope, Program program) {
throw new InternalError("Casting parameter variable not allowed. " + parameterDef.toString());
}
@Override
public void addRightCast(SymbolType toType, ListIterator<Statement> stmtIt, ScopeRef currentScope, ProgramScope symbols) {
public void addRightCast(SymbolType toType, ListIterator<Statement> stmtIt, ScopeRef currentScope, Program program) {
Value value = parameterValue.get();
if(value instanceof ConstantValue) {
parameterValue.set(new ConstantCastValue(toType, (ConstantValue) value));
@ -270,18 +270,17 @@ public interface ProgramExpressionBinary extends ProgramExpression {
}
@Override
public void addLeftCast(SymbolType toType, ListIterator<Statement> stmtIt, ScopeRef currentScope, ProgramScope symbols) {
public void addLeftCast(SymbolType toType, ListIterator<Statement> stmtIt, ScopeRef currentScope, Program program) {
if(assignment.getlValue() instanceof VariableRef) {
Variable variable = symbols.getVariable((VariableRef) assignment.getlValue());
Variable variable = program.getScope().getVariable((VariableRef) assignment.getlValue());
if(variable.isKindIntermediate())
variable.setType(toType);
else
throw new InternalError("Cannot cast declared type!" + variable.toString());
} else {
Scope blockScope = symbols.getScope(currentScope);
Variable tmpVar = blockScope.addVariableIntermediate();
SymbolType rightType = SymbolTypeInference.inferType(symbols, getRight());
tmpVar.setType(rightType);
Scope blockScope = program.getScope().getScope(currentScope);
SymbolType rightType = SymbolTypeInference.inferType(program.getScope(), getRight());
Variable tmpVar = VariableBuilder.createIntermediate(blockScope, rightType, program);
StatementAssignment newAssignment = new StatementAssignment(assignment.getlValue(), Operators.getCastUnary(toType), tmpVar.getRef(), assignment.isInitialAssignment(), assignment.getSource(), Comment.NO_COMMENTS);
assignment.setlValue((LValue) tmpVar.getRef());
stmtIt.add(newAssignment);
@ -289,14 +288,13 @@ public interface ProgramExpressionBinary extends ProgramExpression {
}
@Override
public void addRightCast(SymbolType toType, ListIterator<Statement> stmtIt, ScopeRef currentScope, ProgramScope symbols) {
public void addRightCast(SymbolType toType, ListIterator<Statement> stmtIt, ScopeRef currentScope, Program program) {
if(assignment.getrValue1() == null && assignment.getOperator() == null) {
assignment.setOperator(Operators.getCastUnary(toType));
} else {
Scope blockScope = symbols.getScope(currentScope);
Variable tmpVar = blockScope.addVariableIntermediate();
SymbolType rightType = SymbolTypeInference.inferType(symbols, getRight());
tmpVar.setType(rightType);
Scope blockScope = program.getScope().getScope(currentScope);
SymbolType rightType = SymbolTypeInference.inferType(program.getScope(), getRight());
Variable tmpVar = VariableBuilder.createIntermediate(blockScope, rightType, program);
StatementAssignment newAssignment = new StatementAssignment(assignment.getlValue(), Operators.getCastUnary(toType), tmpVar.getRef(), assignment.isInitialAssignment(), assignment.getSource(), Comment.NO_COMMENTS);
assignment.setlValue((LValue) tmpVar.getRef());
stmtIt.add(newAssignment);
@ -351,7 +349,7 @@ public interface ProgramExpressionBinary extends ProgramExpression {
}
@Override
public void addLeftCast(SymbolType toType, ListIterator<Statement> stmtIt, ScopeRef currentScope, ProgramScope symbols) {
public void addLeftCast(SymbolType toType, ListIterator<Statement> stmtIt, ScopeRef currentScope, Program program) {
if(conditionalJump.getrValue1() instanceof ConstantValue) {
conditionalJump.setrValue1(new ConstantCastValue(toType, (ConstantValue) conditionalJump.getrValue1()));
} else {
@ -360,7 +358,7 @@ public interface ProgramExpressionBinary extends ProgramExpression {
}
@Override
public void addRightCast(SymbolType toType, ListIterator<Statement> stmtIt, ScopeRef currentScope, ProgramScope symbols) {
public void addRightCast(SymbolType toType, ListIterator<Statement> stmtIt, ScopeRef currentScope, Program program) {
if(conditionalJump.getrValue2() instanceof ConstantValue) {
conditionalJump.setrValue2(new ConstantCastValue(toType, (ConstantValue) conditionalJump.getrValue2()));
} else {
@ -420,12 +418,12 @@ public interface ProgramExpressionBinary extends ProgramExpression {
}
@Override
public void addLeftCast(SymbolType toType, ListIterator<Statement> stmtIt, ScopeRef currentScope, ProgramScope symbols) {
public void addLeftCast(SymbolType toType, ListIterator<Statement> stmtIt, ScopeRef currentScope, Program program) {
getConstantBinary().setLeft(new ConstantCastValue(toType, getConstantBinary().getLeft()));
}
@Override
public void addRightCast(SymbolType toType, ListIterator<Statement> stmtIt, ScopeRef currentScope, ProgramScope symbols) {
public void addRightCast(SymbolType toType, ListIterator<Statement> stmtIt, ScopeRef currentScope, Program program) {
getConstantBinary().setRight(new ConstantCastValue(toType, getConstantBinary().getRight()));
}
}
@ -479,7 +477,7 @@ public interface ProgramExpressionBinary extends ProgramExpression {
}
@Override
public void addLeftCast(SymbolType toType, ListIterator<Statement> stmtIt, ScopeRef currentScope, ProgramScope symbols) {
public void addLeftCast(SymbolType toType, ListIterator<Statement> stmtIt, ScopeRef currentScope, Program program) {
if(getPointerDereferenceIndexed().getPointer() instanceof ConstantValue) {
getPointerDereferenceIndexed().setPointer(new ConstantCastValue(toType, (ConstantValue) getPointerDereferenceIndexed().getPointer()));
} else {
@ -489,11 +487,11 @@ public interface ProgramExpressionBinary extends ProgramExpression {
}
@Override
public void addRightCast(SymbolType toType, ListIterator<Statement> stmtIt, ScopeRef currentScope, ProgramScope symbols) {
public void addRightCast(SymbolType toType, ListIterator<Statement> stmtIt, ScopeRef currentScope, Program program) {
if(getPointerDereferenceIndexed().getIndex() instanceof ConstantValue) {
getPointerDereferenceIndexed().setIndex(new ConstantCastValue(toType, (ConstantValue) getPointerDereferenceIndexed().getIndex()));
} else if(getPointerDereferenceIndexed().getIndex() instanceof VariableRef) {
Variable variable = symbols.getVariable((VariableRef) getPointerDereferenceIndexed().getIndex());
Variable variable = program.getScope().getVariable((VariableRef) getPointerDereferenceIndexed().getIndex());
if(variable.isKindIntermediate())
variable.setType(toType);
else
@ -554,8 +552,8 @@ public interface ProgramExpressionBinary extends ProgramExpression {
}
@Override
public void addLeftCast(SymbolType toType, ListIterator<Statement> stmtIt, ScopeRef currentScope, ProgramScope symbols) {
Variable variable = symbols.getVariable(phiVariable.getVariable());
public void addLeftCast(SymbolType toType, ListIterator<Statement> stmtIt, ScopeRef currentScope, Program program) {
Variable variable = program.getScope().getVariable(phiVariable.getVariable());
if(variable.isKindIntermediate())
variable.setType(toType);
else
@ -563,9 +561,9 @@ public interface ProgramExpressionBinary extends ProgramExpression {
}
@Override
public void addRightCast(SymbolType toType, ListIterator<Statement> stmtIt, ScopeRef currentScope, ProgramScope symbols) {
public void addRightCast(SymbolType toType, ListIterator<Statement> stmtIt, ScopeRef currentScope, Program program) {
if(getRight() instanceof VariableRef) {
Variable variable = symbols.getVariable((VariableRef) getRight());
Variable variable = program.getScope().getVariable((VariableRef) getRight());
if(variable.isKindIntermediate())
variable.setType(toType);
} else if(getRight() instanceof ConstantValue) {

View File

@ -111,11 +111,6 @@ public abstract class Scope implements Symbol, Serializable {
return symbol;
}
public Variable addVariableIntermediate() {
String name = allocateIntermediateVariableName();
return add(Variable.createIntermediate(name, this, getSegmentData()));
}
public Label addLabel(String name) {
return add(new Label(name, this, false));
}

View File

@ -128,46 +128,6 @@ public class Variable implements Symbol {
setFullName();
}
/**
* Create an intermediate variable. The type will initially be set to {@link SymbolType#VAR}.
*
* @param name The name
* @param scope The scope
* @param dataSegment The data segment (in main memory)
* @return The new intermediate variable
*/
public static Variable createIntermediate(String name, Scope scope, String dataSegment) {
return new Variable(name, Kind.INTERMEDIATE, SymbolType.VAR, scope, MemoryArea.ZEROPAGE_MEMORY, dataSegment, null);
}
/**
* Create a load/store variable
*
* @param name The name
* @param type The type
* @param scope The scope
* @param memoryArea The memory area (zeropage/main memory)
* @param dataSegment The data segment (in main memory)
* @return The new PHI-master variable
*/
public static Variable createLoadStore(String name, SymbolType type, Scope scope, Variable.MemoryArea memoryArea, String dataSegment) {
return new Variable(name, Kind.LOAD_STORE, type, scope, memoryArea, dataSegment, null);
}
/**
* Create a PHI master variable
*
* @param name The name
* @param type The type
* @param scope The scope
* @param memoryArea The memory area (zeropage/main memory)
* @param dataSegment The data segment (in main memory)
* @return The new PHI-master variable
*/
public static Variable createPhiMaster(String name, SymbolType type, Scope scope, Variable.MemoryArea memoryArea, String dataSegment) {
return new Variable(name, Kind.PHI_MASTER, type, scope, memoryArea, dataSegment, null);
}
/**
* Create a version of a PHI master variable
*
@ -519,10 +479,6 @@ public class Variable implements Symbol {
this.memoryArea = memoryArea;
}
public boolean isMemoryAreaZp() {
return MemoryArea.ZEROPAGE_MEMORY.equals(getMemoryArea());
}
public boolean isMemoryAreaMain() {
return MemoryArea.MAIN_MEMORY.equals(getMemoryArea());
}

View File

@ -95,7 +95,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
if(currentScope == null || ScopeRef.ROOT.equals(currentScope.getRef())) {
currentScope = getInitProc();
}
return currentScope.addVariableIntermediate();
return VariableBuilder.createIntermediate(currentScope, SymbolType.VAR, program);
}
/**
@ -492,14 +492,14 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
if(parameter.name==null)
throw new CompileError("Illegal unnamed parameter.", statementSource);
VariableBuilder varBuilder = new VariableBuilder(parameter.name, getCurrentScope(), true, parameter.type, null, currentDataSegment, program.getTargetPlatform().getVariableBuilderConfig());
VariableBuilder varBuilder = new VariableBuilder(parameter.name, getCurrentScope(), true, false, parameter.type, null, currentDataSegment, program.getTargetPlatform().getVariableBuilderConfig());
final Variable paramVar = varBuilder.build();
parameterList.add(paramVar);
}
procedure.setParameters(parameterList);
// Add return variable
if(!SymbolType.VOID.equals(procedure.getReturnType())) {
final VariableBuilder builder = new VariableBuilder("return", procedure, false, procedure.getReturnType(), varDecl.getDeclDirectives(), currentDataSegment, program.getTargetPlatform().getVariableBuilderConfig());
final VariableBuilder builder = new VariableBuilder("return", procedure, false, false, procedure.getReturnType(), varDecl.getDeclDirectives(), currentDataSegment, program.getTargetPlatform().getVariableBuilderConfig());
builder.build();
}
// exit the procedure
@ -966,7 +966,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
final List<Directive> effectiveDirectives = varDecl.getDeclDirectives();
final List<Comment> declComments = varDecl.getDeclComments();
varDecl.exitVar();
VariableBuilder varBuilder = new VariableBuilder(varName, getCurrentScope(), false, effectiveType, effectiveDirectives, currentDataSegment, program.getTargetPlatform().getVariableBuilderConfig());
VariableBuilder varBuilder = new VariableBuilder(varName, getCurrentScope(), false, false, effectiveType, effectiveDirectives, currentDataSegment, program.getTargetPlatform().getVariableBuilderConfig());
Variable variable = varBuilder.build();
if(isStructMember && (initializer != null))
throw new CompileError("Initializer not supported inside structs " + effectiveType.getTypeName(), declSource);
@ -1052,7 +1052,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
ConstantArrayKickAsm constantArrayKickAsm = new ConstantArrayKickAsm(((SymbolTypePointer) varDecl.getEffectiveType()).getElementType(), kasm.kickAsmCode, kasm.uses, ((SymbolTypePointer) effectiveType).getArraySpec().getArraySize());
// Add a constant variable
Scope scope = getCurrentScope();
VariableBuilder varBuilder = new VariableBuilder(varName, scope, false, varDecl.getEffectiveType(), varDecl.getDeclDirectives(), currentDataSegment, program.getTargetPlatform().getVariableBuilderConfig());
VariableBuilder varBuilder = new VariableBuilder(varName, scope, false, false, varDecl.getEffectiveType(), varDecl.getDeclDirectives(), currentDataSegment, program.getTargetPlatform().getVariableBuilderConfig());
Variable variable = varBuilder.build();
// Set constant value
variable.setInitValue(getConstInitValue(constantArrayKickAsm, null, statementSource));
@ -1591,7 +1591,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
String varName = varDecl.getVarName();
Variable lValue;
if(varType != null) {
VariableBuilder varBuilder = new VariableBuilder(varName, blockScope, false, varType, varDecl.getDeclDirectives(), currentDataSegment, program.getTargetPlatform().getVariableBuilderConfig());
VariableBuilder varBuilder = new VariableBuilder(varName, blockScope, false, false, varType, varDecl.getDeclDirectives(), currentDataSegment, program.getTargetPlatform().getVariableBuilderConfig());
lValue = varBuilder.build();
} else {
lValue = getCurrentScope().findVariable(varName);
@ -2123,7 +2123,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
this.visit(ctx.declType());
this.visit(ctx.declarator());
String typedefName = varDecl.getVarName();
VariableBuilder varBuilder = new VariableBuilder(typedefName, getCurrentScope(), false, varDecl.getEffectiveType(), varDecl.getDeclDirectives(), currentDataSegment, program.getTargetPlatform().getVariableBuilderConfig());
VariableBuilder varBuilder = new VariableBuilder(typedefName, getCurrentScope(), false, false, varDecl.getEffectiveType(), varDecl.getDeclDirectives(), currentDataSegment, program.getTargetPlatform().getVariableBuilderConfig());
varBuilder.build();
scopeStack.pop();
varDecl.exitType();

View File

@ -2,6 +2,7 @@ package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.ControlFlowBlock;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.VariableBuilder;
import dk.camelot64.kickc.model.operators.Operator;
import dk.camelot64.kickc.model.operators.Operators;
import dk.camelot64.kickc.model.statements.Statement;
@ -10,10 +11,9 @@ import dk.camelot64.kickc.model.statements.StatementLValue;
import dk.camelot64.kickc.model.symbols.ProgramScope;
import dk.camelot64.kickc.model.symbols.Scope;
import dk.camelot64.kickc.model.symbols.Variable;
import dk.camelot64.kickc.model.values.LValue;
import dk.camelot64.kickc.model.values.LvalueIntermediate;
import dk.camelot64.kickc.model.values.SymbolVariableRef;
import dk.camelot64.kickc.model.values.VariableRef;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypeInference;
import dk.camelot64.kickc.model.values.*;
import dk.camelot64.kickc.passes.utils.VarAssignments;
import java.util.ArrayList;
@ -82,10 +82,10 @@ public class Pass1FixLValuesLoHi extends Pass1Base {
Variable intermediateVar = programScope.getVariable(intermediate.getVariable());
Scope currentScope = intermediateVar.getScope();
// Let assignment put value into a tmp Var
Variable tmpVar = currentScope.addVariableIntermediate();
SymbolType type = SymbolTypeInference.inferType(programScope, new AssignmentRValue(intermediateAssignment));
Variable tmpVar = VariableBuilder.createIntermediate(currentScope, type, getProgram());
SymbolVariableRef tmpVarRef = tmpVar.getRef();
statementLValue.setlValue((LValue) tmpVarRef);
PassNTypeInference.updateInferedTypeLValue(getProgram(), statementLValue);
// Insert an extra "set low" assignment statement
Statement setLoHiAssignment = new StatementAssignment(loHiVar, loHiVar, loHiOperator, tmpVarRef, true, statementLValue.getSource(), new ArrayList<>());
statementsIt.add(setLoHiAssignment);

View File

@ -1,13 +1,11 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.Comment;
import dk.camelot64.kickc.model.CompileError;
import dk.camelot64.kickc.model.ControlFlowBlock;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.*;
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
import dk.camelot64.kickc.model.operators.Operators;
import dk.camelot64.kickc.model.statements.Statement;
import dk.camelot64.kickc.model.statements.StatementAssignment;
import dk.camelot64.kickc.model.symbols.Scope;
import dk.camelot64.kickc.model.symbols.StructDefinition;
import dk.camelot64.kickc.model.symbols.Symbol;
import dk.camelot64.kickc.model.symbols.Variable;
@ -71,8 +69,9 @@ public class Pass1PointerSizeofFix extends Pass1Base {
getLog().append("Fixing pointer array-indexing " + deref.toString(getProgram()));
SymbolVariableRef idx2VarRef = handled.getOrDefault(currentStmt, new LinkedHashMap<>()).get(deref.getIndex());
if(idx2VarRef == null) {
Variable idx2Var = getScope().getScope(currentBlock.getScope()).addVariableIntermediate();
idx2Var.setType(SymbolTypeInference.inferType(getScope(), deref.getIndex()));
SymbolType type = SymbolTypeInference.inferType(getScope(), deref.getIndex());
Scope scope = getScope().getScope(currentBlock.getScope());
Variable idx2Var = VariableBuilder.createIntermediate(scope, type, getProgram());
ConstantRef sizeOfTargetType = SizeOfConstants.getSizeOfConstantVar(getProgram().getScope(), pointerType.getElementType());
StatementAssignment idx2 = new StatementAssignment((LValue) idx2Var.getRef(), deref.getIndex(), Operators.MULTIPLY, sizeOfTargetType, true, currentStmt.getSource(), Comment.NO_COMMENTS);
stmtIt.previous();
@ -115,8 +114,9 @@ public class Pass1PointerSizeofFix extends Pass1Base {
if(getLog().isVerboseParse())
getLog().append("Fixing pointer addition " + assignment.toString(getProgram(), false));
LValue lValue = assignment.getlValue();
Variable tmpVar = getScope().getScope(block.getScope()).addVariableIntermediate();
tmpVar.setType(SymbolTypeInference.inferType(getScope(), assignment.getlValue()));
Scope scope = getScope().getScope(block.getScope());
SymbolType type = SymbolTypeInference.inferType(getScope(), assignment.getlValue());
Variable tmpVar = VariableBuilder.createIntermediate(scope, type, getProgram());
assignment.setlValue((LValue) tmpVar.getRef());
ConstantRef sizeOfTargetType = SizeOfConstants.getSizeOfConstantVar(getProgram().getScope(), pointerType.getElementType());
stmtIt.add(new StatementAssignment(lValue, tmpVar.getRef(), Operators.DIVIDE, sizeOfTargetType, assignment.isInitialAssignment(), assignment.getSource(), Comment.NO_COMMENTS));
@ -128,8 +128,9 @@ public class Pass1PointerSizeofFix extends Pass1Base {
// Adding to a pointer - multiply by sizeof()
if(getLog().isVerboseParse())
getLog().append("Fixing pointer addition " + assignment.toString(getProgram(), false));
Variable tmpVar = getScope().getScope(block.getScope()).addVariableIntermediate();
tmpVar.setType(SymbolTypeInference.inferType(getScope(), assignment.getrValue2()));
Scope scope = getScope().getScope(block.getScope());
SymbolType type = SymbolTypeInference.inferType(getScope(), assignment.getrValue2());
Variable tmpVar = VariableBuilder.createIntermediate(scope, type, getProgram());
stmtIt.remove();
ConstantRef sizeOfTargetType = SizeOfConstants.getSizeOfConstantVar(getProgram().getScope(), pointerType.getElementType());
stmtIt.add(new StatementAssignment((LValue) tmpVar.getRef(), assignment.getrValue2(), Operators.MULTIPLY, sizeOfTargetType, true, assignment.getSource(), Comment.NO_COMMENTS));

View File

@ -1,16 +1,12 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.Comment;
import dk.camelot64.kickc.model.ControlFlowBlock;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.VariableReferenceInfos;
import dk.camelot64.kickc.model.*;
import dk.camelot64.kickc.model.iterator.ProgramValue;
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
import dk.camelot64.kickc.model.operators.Operator;
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.StatementInfos;
import dk.camelot64.kickc.model.symbols.Scope;
import dk.camelot64.kickc.model.symbols.Variable;
import dk.camelot64.kickc.model.types.SymbolType;
@ -134,9 +130,8 @@ public class Pass2ConditionalJumpSimplification extends Pass2SsaOptimization {
final ControlFlowBlock conditionDefineBlock = statementInfos.getBlock(simpleCondition.conditionAssignment);
final ScopeRef conditionDefineScopeRef = conditionDefineBlock.getScope();
final Scope conditionDefineScope = getScope().getScope(conditionDefineScopeRef);
final Variable intermediateLoadStoreVar = conditionDefineScope.addVariableIntermediate();
SymbolType typeQualified = referencedLoadStoreVariable.getType().getQualified(false, referencedLoadStoreVariable.getType().isNomodify());
intermediateLoadStoreVar.setType(typeQualified);
final Variable intermediateLoadStoreVar = VariableBuilder.createIntermediate(conditionDefineScope, typeQualified, getProgram());
final StatementAssignment intermediateLoadStoreAssignment = new StatementAssignment(intermediateLoadStoreVar.getVariableRef(), referencedLoadStoreVariable.getRef(), true, simpleCondition.conditionAssignment.getSource(), Comment.NO_COMMENTS);
conditionDefineBlock.addStatementAfter(intermediateLoadStoreAssignment, simpleCondition.conditionAssignment);
// Replace all references to the load/store variable in the expressions with the new intermediate

View File

@ -2,7 +2,9 @@ package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.Comment;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.VariableBuilder;
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
import dk.camelot64.kickc.model.operators.OperatorPlus;
import dk.camelot64.kickc.model.operators.Operators;
import dk.camelot64.kickc.model.statements.StatementAssignment;
import dk.camelot64.kickc.model.symbols.Scope;
@ -33,14 +35,13 @@ public class Pass2DeInlineWordDerefIdx extends Pass2SsaOptimization {
// Index is multiple bytes - de-inline it
getLog().append("De-inlining pointer[w] to *(pointer+w) "+currentStmt.toString(getProgram(), false));
Scope currentScope = getScope().getScope(currentBlock.getScope());
Variable tmpVar = currentScope.addVariableIntermediate();
SymbolType pointerType = Operators.PLUS.inferType(SymbolTypeInference.inferType(getScope(), dereferenceIndexed.getPointer()), SymbolTypeInference.inferType(getScope(), dereferenceIndexed.getIndex()));
Variable tmpVar = VariableBuilder.createIntermediate(currentScope, pointerType, getProgram());
stmtIt.previous();
StatementAssignment tmpVarAssignment = new StatementAssignment((LValue) tmpVar.getRef(), dereferenceIndexed.getPointer(), Operators.PLUS, indexValue, true, currentStmt.getSource(), Comment.NO_COMMENTS);
stmtIt.add(tmpVarAssignment);
stmtIt.next();
programValue.set(new PointerDereferenceSimple(tmpVar.getRef()));
SymbolType pointerType = SymbolTypeInference.inferType(getScope(), new AssignmentRValue(tmpVarAssignment));
tmpVar.setType(pointerType);
optimized.set(true);
}
}

View File

@ -3,6 +3,7 @@ package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.Comment;
import dk.camelot64.kickc.model.ControlFlowBlock;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.VariableBuilder;
import dk.camelot64.kickc.model.iterator.ProgramExpression;
import dk.camelot64.kickc.model.iterator.ProgramExpressionIterator;
import dk.camelot64.kickc.model.iterator.ProgramExpressionUnary;
@ -82,8 +83,7 @@ public class Pass2FixInlineConstructors extends Pass2SsaOptimization {
public void addLiteralWordConstructor(OperatorBinary constructOperator, SymbolType castType, SymbolType constructType, SymbolType subType, ProgramExpression programExpression, List<RValue> listValues, Statement currentStmt, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock) {
// Convert list to a word constructor in a new tmp variable
Scope currentScope = Pass2FixInlineConstructors.this.getScope().getScope(currentBlock.getScope());
Variable tmpVar = currentScope.addVariableIntermediate();
tmpVar.setType(constructType);
Variable tmpVar = VariableBuilder.createIntermediate(currentScope, constructType, getProgram());
// Move backward - to insert before the current statement
stmtIt.previous();
// Add assignment of the new tmpVar

View File

@ -1,9 +1,6 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.Comment;
import dk.camelot64.kickc.model.ConstantNotLiteral;
import dk.camelot64.kickc.model.ControlFlowBlock;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.*;
import dk.camelot64.kickc.model.operators.Operators;
import dk.camelot64.kickc.model.statements.Statement;
import dk.camelot64.kickc.model.statements.StatementAssignment;
@ -71,13 +68,11 @@ public class Pass2MultiplyToShiftRewriting extends Pass2SsaOptimization {
long powVal = 1L <<pow2;
if(remains>=powVal) {
// First add shifts
Variable varShift = scope.addVariableIntermediate();
varShift.setType(resultType);
Variable varShift = VariableBuilder.createIntermediate(scope, resultType, getProgram());
stmtIt.add(new StatementAssignment((LValue) varShift.getRef(), building, Operators.SHIFT_LEFT, new ConstantInteger(shiftCount, SymbolType.BYTE), true, assignment.getSource(), Comment.NO_COMMENTS));
shiftCount = 0;
// Then add rvalue1
Variable varAdd = scope.addVariableIntermediate();
varAdd.setType(resultType);
Variable varAdd = VariableBuilder.createIntermediate(scope, resultType, getProgram());
stmtIt.add(new StatementAssignment((LValue) varAdd.getRef(), varShift.getRef(), Operators.PLUS, assignment.getrValue1(), true, assignment.getSource(), Comment.NO_COMMENTS));
building = varAdd.getRef();
remains -= powVal;
@ -90,8 +85,7 @@ public class Pass2MultiplyToShiftRewriting extends Pass2SsaOptimization {
}
// add remaining shifts
if(shiftCount>0) {
Variable varShift = scope.addVariableIntermediate();
varShift.setType(resultType);
Variable varShift = VariableBuilder.createIntermediate(scope, resultType, getProgram());
stmtIt.add(new StatementAssignment((LValue) varShift.getRef(), building, Operators.SHIFT_LEFT, new ConstantInteger(shiftCount, SymbolType.BYTE), true, assignment.getSource(), Comment.NO_COMMENTS));
building = varShift.getRef();
}

View File

@ -49,14 +49,15 @@ public class Pass3PhiLifting {
//VariableRef rValVarRef = (VariableRef) phiRValue.getrValue();
Variable newVar;
if(phiVariable.getVariable().isVersion()) {
Symbol phiLValue = programScope.getSymbol(phiVariable.getVariable());
Variable lValVar = program.getScope().getVariable(phiVariable.getVariable());
newVar = lValVar.getPhiMaster().createVersion();
newVar.setType(phiLValue.getType());
} else {
Symbol phiLValue = programScope.getSymbol(phiVariable.getVariable());
Variable lValVar = program.getScope().getVariable(phiVariable.getVariable());
newVar = lValVar.getScope().addVariableIntermediate();
newVar = VariableBuilder.createIntermediate(lValVar.getScope(), lValVar.getType(), program);
}
Symbol phiLValue = programScope.getSymbol(phiVariable.getVariable());
newVar.setType(phiLValue.getType());
List<Statement> predecessorStatements = predecessorBlock.getStatements();
Statement lastPredecessorStatement = null;
if(predecessorStatements.size() > 0) {

View File

@ -3,6 +3,7 @@ package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.Comment;
import dk.camelot64.kickc.model.ControlFlowBlock;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.VariableBuilder;
import dk.camelot64.kickc.model.iterator.ProgramExpressionIterator;
import dk.camelot64.kickc.model.iterator.ProgramExpressionUnary;
import dk.camelot64.kickc.model.operators.Operators;
@ -76,8 +77,7 @@ public class PassNAddBooleanCasts extends Pass2SsaOptimization {
private Variable addBooleanCast(RValue rValue, SymbolType rValueType, Statement currentStmt, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock) {
Scope currentScope = getScope().getScope(currentBlock.getScope());
stmtIt.previous();
Variable tmpVar = currentScope.addVariableIntermediate();
tmpVar.setType(SymbolType.BOOLEAN);
Variable tmpVar = VariableBuilder.createIntermediate(currentScope, SymbolType.BOOLEAN, getProgram());
// Go straight to xxx!=0 instead of casting to bool
ConstantValue nullValue;
if(rValueType instanceof SymbolTypePointer) {

View File

@ -33,13 +33,13 @@ public class PassNAddNumberTypeConversions extends Pass2SsaOptimization {
SymbolType leftType = SymbolTypeInference.inferType(getProgram().getScope(), left);
if(SymbolType.NUMBER.equals(leftType)) {
getLog().append("Adding number conversion cast (" + castType + ") " + binary.getLeft().toString() + " in " + (currentStmt==null?"":currentStmt.toString(getProgram(), false)));
binary.addLeftCast(castType, stmtIt, currentBlock==null?null:currentBlock.getScope(), getScope());
binary.addLeftCast(castType, stmtIt, currentBlock==null?null:currentBlock.getScope(), getProgram());
modified.set(true);
}
SymbolType rightType = SymbolTypeInference.inferType(getProgram().getScope(), right);
if(SymbolType.NUMBER.equals(rightType)) {
getLog().append("Adding number conversion cast (" + castType + ") " + binary.getRight().toString() + " in " + ((currentStmt==null)?"":currentStmt.toString(getProgram(), false)));
binary.addRightCast(castType, stmtIt, currentBlock==null?null:currentBlock.getScope(), getScope());
binary.addRightCast(castType, stmtIt, currentBlock==null?null:currentBlock.getScope(), getProgram());
modified.set(true);
}

View File

@ -49,33 +49,33 @@ public class PassNAddTypeConversionAssignment extends Pass2SsaOptimization {
if((leftType instanceof SymbolTypePointer) && rightType instanceof SymbolTypePointer && SymbolType.VOID.equals(((SymbolTypePointer) leftType).getElementType())) {
if(!pass1 || getLog().isVerbosePass1CreateSsa())
getLog().append("Adding void pointer type conversion cast (" + leftType + ") " + binary.getRight().toString() + " in " + currentStmt.toString(getProgram(), false));
binary.addRightCast(leftType, stmtIt, currentBlock.getScope(), getScope());
binary.addRightCast(leftType, stmtIt, currentBlock.getScope(), getProgram());
modified.set(true);
} else if((leftType instanceof SymbolTypePointer) && rightType instanceof SymbolTypePointer && SymbolType.VOID.equals(((SymbolTypePointer) rightType).getElementType())) {
if(!pass1 || getLog().isVerbosePass1CreateSsa())
getLog().append("Adding pointer type conversion cast to void pointer (" + leftType + ") " + binary.getRight().toString() + " in " + currentStmt.toString(getProgram(), false));
binary.addRightCast(leftType, stmtIt, currentBlock.getScope(), getScope());
binary.addRightCast(leftType, stmtIt, currentBlock.getScope(), getProgram());
modified.set(true);
} else if(SymbolType.WORD.equals(leftType) && isLiteralWordCandidate(right)) {
// Detect word literal constructor
SymbolType conversionType = SymbolType.WORD;
if(!pass1 || getLog().isVerbosePass1CreateSsa())
getLog().append("Identified literal word (" + conversionType + ") " + binary.getRight().toString() + " in " + (currentStmt == null ? "" : currentStmt.toString(getProgram(), false)));
binary.addRightCast(conversionType, stmtIt, currentBlock == null ? null : currentBlock.getScope(), getScope());
binary.addRightCast(conversionType, stmtIt, currentBlock == null ? null : currentBlock.getScope(), getProgram());
modified.set(true);
} else if(leftType instanceof SymbolTypePointer && isLiteralWordCandidate(right)) {
// Detect word literal constructor
SymbolType conversionType = SymbolType.WORD;
if(!pass1 || getLog().isVerbosePass1CreateSsa())
getLog().append("Identified literal word (" + conversionType + ") " + binary.getRight().toString() + " in " + (currentStmt == null ? "" : currentStmt.toString(getProgram(), false)));
binary.addRightCast(conversionType, stmtIt, currentBlock == null ? null : currentBlock.getScope(), getScope());
binary.addRightCast(conversionType, stmtIt, currentBlock == null ? null : currentBlock.getScope(), getProgram());
modified.set(true);
} else if(SymbolType.DWORD.equals(leftType) && isLiteralWordCandidate(right)) {
// Detect dword literal constructor
SymbolType conversionType = SymbolType.DWORD;
if(!pass1 || getLog().isVerbosePass1CreateSsa())
getLog().append("Identified literal word (" + conversionType + ") " + binary.getRight().toString() + " in " + (currentStmt == null ? "" : currentStmt.toString(getProgram(), false)));
binary.addRightCast(conversionType, stmtIt, currentBlock == null ? null : currentBlock.getScope(), getScope());
binary.addRightCast(conversionType, stmtIt, currentBlock == null ? null : currentBlock.getScope(), getProgram());
modified.set(true);
}
}

View File

@ -3,6 +3,7 @@ package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.Comment;
import dk.camelot64.kickc.model.ControlFlowBlock;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.VariableBuilder;
import dk.camelot64.kickc.model.iterator.ProgramExpressionBinary;
import dk.camelot64.kickc.model.iterator.ProgramExpressionIterator;
import dk.camelot64.kickc.model.iterator.ProgramValue;
@ -11,6 +12,7 @@ import dk.camelot64.kickc.model.statements.Statement;
import dk.camelot64.kickc.model.statements.StatementAssignment;
import dk.camelot64.kickc.model.symbols.Scope;
import dk.camelot64.kickc.model.symbols.Variable;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.values.CastValue;
import java.util.ListIterator;
@ -50,8 +52,8 @@ public class PassNDeInlineCastValues extends Pass2SsaOptimization {
if(!pass1)
getLog().append("De-inlining cast " + castValue.toString());
final Scope scope = getScope().getScope(currentBlock.getScope());
final Variable tmpVar = scope.addVariableIntermediate();
tmpVar.setType(castValue.getToType());
SymbolType toType = castValue.getToType();
final Variable tmpVar = VariableBuilder.createIntermediate(scope, toType, getProgram());
castProgramValue.set(tmpVar.getRef());
stmtIt.previous();
stmtIt.add(new StatementAssignment(tmpVar.getVariableRef(), castValue, true, currentStmt.getSource(), Comment.NO_COMMENTS));

View File

@ -3,6 +3,7 @@ package dk.camelot64.kickc.passes.unwinding;
import dk.camelot64.kickc.model.ControlFlowBlock;
import dk.camelot64.kickc.model.InternalError;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.VariableBuilder;
import dk.camelot64.kickc.model.operators.Operators;
import dk.camelot64.kickc.model.statements.Statement;
import dk.camelot64.kickc.model.statements.StatementAssignment;
@ -85,9 +86,7 @@ public class ValueSourcePointerDereferenceIndexed extends ValueSourceBase {
return new ValueSourceConstant(new SymbolTypePointer(elementType), elmPointer);
} else {
// Unwind to (elmType*)&struct + OFFSET_MEMBER + idx
Scope scope = programScope.getScope(currentBlock.getScope());
Variable elementAddress = scope.addVariableIntermediate();
elementAddress.setType(new SymbolTypePointer(elementType));
Variable elementAddress = VariableBuilder.createIntermediate(programScope.getScope(currentBlock.getScope()), new SymbolTypePointer(elementType), program);
stmtIt.previous();
stmtIt.add(new StatementAssignment((LValue) elementAddress.getRef(), memberPointer, Operators.PLUS, pointerDereferenceIndexed.getIndex(), true, currentStmt.getSource(), currentStmt.getComments()));
stmtIt.next();
@ -111,9 +110,7 @@ public class ValueSourcePointerDereferenceIndexed extends ValueSourceBase {
return new ValueSourcePointerDereferenceIndexed(memberDeref, memberType, null);
} else {
// Unwind to ((type*)&struct + idx)[OFFSET_MEMBER]
Scope scope = programScope.getScope(currentBlock.getScope());
Variable idxAddress = scope.addVariableIntermediate();
idxAddress.setType(new SymbolTypePointer(memberType));
Variable idxAddress = VariableBuilder.createIntermediate(programScope.getScope(currentBlock.getScope()), new SymbolTypePointer(memberType), program);
stmtIt.previous();
stmtIt.add(new StatementAssignment((LValue) idxAddress.getRef(), structTypedPointer, Operators.PLUS, pointerDereferenceIndexed.getIndex(), true, currentStmt.getSource(), currentStmt.getComments()));
stmtIt.next();
@ -125,8 +122,8 @@ public class ValueSourcePointerDereferenceIndexed extends ValueSourceBase {
if(memberArraySpec != null)
throw new InternalError("Not implemented!");
Scope scope = programScope.getScope(currentBlock.getScope());
Variable memberAddress = scope.addVariableIntermediate();
memberAddress.setType(new SymbolTypePointer(memberType));
SymbolTypePointer type = new SymbolTypePointer(memberType);
Variable memberAddress = VariableBuilder.createIntermediate(scope, type, program);
CastValue structTypedPointer = new CastValue(new SymbolTypePointer(memberType), structPointer);
// Add statement $1 = (memberType*)ptr_struct + OFFSET_MEMBER
stmtIt.previous();

View File

@ -2,6 +2,7 @@ package dk.camelot64.kickc.passes.unwinding;
import dk.camelot64.kickc.model.ControlFlowBlock;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.VariableBuilder;
import dk.camelot64.kickc.model.operators.Operators;
import dk.camelot64.kickc.model.statements.Statement;
import dk.camelot64.kickc.model.statements.StatementAssignment;
@ -92,8 +93,7 @@ public class ValueSourcePointerDereferenceSimple extends ValueSourceBase {
SymbolType elementType = ((SymbolTypePointer) memberType).getElementType();
SymbolTypePointer pointerToElementType = new SymbolTypePointer(elementType);
Scope scope = programScope.getScope(currentBlock.getScope());
Variable memberAddress = scope.addVariableIntermediate();
memberAddress.setType(pointerToElementType);
Variable memberAddress = VariableBuilder.createIntermediate(scope, pointerToElementType, program);
CastValue elementTypedPointer = new CastValue(pointerToElementType, structPointer);
// Add statement $1 = (elmType*)ptr_struct + OFFSET_MEMBER
stmtIt.previous();
@ -103,8 +103,7 @@ public class ValueSourcePointerDereferenceSimple extends ValueSourceBase {
return new ValueSourceVariable(memberAddress);
} else {
Scope scope = programScope.getScope(currentBlock.getScope());
Variable memberAddress = scope.addVariableIntermediate();
memberAddress.setType(new SymbolTypePointer(memberType));
Variable memberAddress = VariableBuilder.createIntermediate(scope, new SymbolTypePointer(memberType), program);
CastValue structTypedPointer = new CastValue(new SymbolTypePointer(memberType), structPointer);
// Add statement $1 = (memberType*)ptr_struct + OFFSET_MEMBER
stmtIt.previous();

View File

@ -174,7 +174,7 @@ public class Unroller {
Scope scope = origVar.getScope();
SymbolVariableRef newVarRef;
if(origVarRef.isIntermediate()) {
newVarRef = scope.addVariableIntermediate().getRef();
newVarRef = VariableBuilder.createIntermediate(scope, origVar.getType(), program).getRef();
} else {
newVarRef = (origVar).getPhiMaster().createVersion().getRef();
}

View File

@ -412,8 +412,8 @@ byte~ main::$25
word~ main::$28
byte~ main::$29
word~ main::$3
number~ main::$32
number~ main::$33
word~ main::$32
word~ main::$33
number~ main::$4
word~ main::$6
number~ main::$7
@ -666,10 +666,8 @@ Adding number conversion cast (unumber) 0 in memset::$0 = memset::num#1 > 0
Adding number conversion cast (unumber) $12345690 in main::$1 = main::dw#2 != $12345690
Adding number conversion cast (unumber) $1111 in main::$4 = main::$3 + $1111
Adding number conversion cast (unumber) main::$4 in main::$4 = main::$3 + (unumber)$1111
Adding number conversion cast (unumber) main::$32 in main::$32 = main::$4
Adding number conversion cast (unumber) $1111 in main::$7 = main::$6 + $1111
Adding number conversion cast (unumber) main::$7 in main::$7 = main::$6 + (unumber)$1111
Adding number conversion cast (unumber) main::$33 in main::$33 = main::$7
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast memset::num#0 = (unumber)$3e8
Inlining cast memset::dst#0 = (byte*)memset::str#2
@ -695,9 +693,7 @@ Finalized unsigned number type (word) $1111
Successful SSA optimization PassNFinalizeNumberTypeConversions
Inferred type updated to byte in print_uchar::$2 = print_uchar::b#7 & $f
Inferred type updated to word in main::$4 = main::$3 + $1111
Inferred type updated to word in main::$32 = main::$4
Inferred type updated to word in main::$7 = main::$6 + $1111
Inferred type updated to word in main::$33 = main::$7
Inversing boolean not [75] memset::$1 = memset::num#1 <= 0 from [74] memset::$0 = memset::num#1 > 0
Successful SSA optimization Pass2UnaryNotSimplification
Alias print_line_cursor#0 = print_ln::$0 print_line_cursor#11 print_char_cursor#0 print_line_cursor#12 print_char_cursor#35 print_line_cursor#1 print_char_cursor#1