mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-01-11 04:29:53 +00:00
Restructured Variable creation to make it more explicit what type is being created.
This commit is contained in:
parent
2bad8c915f
commit
cff815f5d7
@ -79,12 +79,13 @@ public class AsmFragmentTemplate {
|
||||
ProgramScope scope = new ProgramScope();
|
||||
LinkedHashMap<String, Value> bindings = new LinkedHashMap<>();
|
||||
{
|
||||
Variable v1 = new Variable( "z1", Variable.Kind.PHI_VERSION, SymbolType.BYTE, scope, Variable.MemoryArea.ZEROPAGE_MEMORY, null);
|
||||
Variable v2 = new Variable( "z2", Variable.Kind.PHI_VERSION, SymbolType.BYTE, scope, Variable.MemoryArea.ZEROPAGE_MEMORY, null);
|
||||
Variable v3 = new Variable( "z3", Variable.Kind.PHI_VERSION, SymbolType.BYTE, scope, Variable.MemoryArea.ZEROPAGE_MEMORY, null);
|
||||
Variable v4 = new Variable( "z4", Variable.Kind.PHI_VERSION, SymbolType.BYTE, scope, Variable.MemoryArea.ZEROPAGE_MEMORY, null);
|
||||
Variable v5 = new Variable( "z5", Variable.Kind.PHI_VERSION, SymbolType.BYTE, scope, Variable.MemoryArea.ZEROPAGE_MEMORY, null);
|
||||
Variable v6 = new Variable( "z6", Variable.Kind.PHI_VERSION, SymbolType.BYTE, scope, Variable.MemoryArea.ZEROPAGE_MEMORY, null);
|
||||
Variable master = Variable.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");
|
||||
Variable v4 = Variable.createPhiVersion(master, 4); v4.setName("z4");
|
||||
Variable v5 = Variable.createPhiVersion(master, 5); v5.setName("z5");
|
||||
Variable v6 = Variable.createPhiVersion(master, 6); v6.setName("z6");
|
||||
v1.setAllocation(new Registers.RegisterZpMem(2, 1));
|
||||
v2.setAllocation(new Registers.RegisterZpMem(4, 1));
|
||||
v3.setAllocation(new Registers.RegisterZpMem(6, 1));
|
||||
@ -99,12 +100,12 @@ public class AsmFragmentTemplate {
|
||||
if(signature.contains("z6")) bindings.put("z6", v6);
|
||||
}
|
||||
{
|
||||
Variable v1 = new Variable( "m1", Variable.Kind.LOAD_STORE, SymbolType.BYTE, scope, Variable.MemoryArea.MAIN_MEMORY, null);
|
||||
Variable v2 = new Variable( "m2", Variable.Kind.LOAD_STORE, SymbolType.BYTE, scope, Variable.MemoryArea.MAIN_MEMORY, null);
|
||||
Variable v3 = new Variable( "m3", Variable.Kind.LOAD_STORE, SymbolType.BYTE, scope, Variable.MemoryArea.MAIN_MEMORY, null);
|
||||
Variable v4 = new Variable( "m4", Variable.Kind.LOAD_STORE, SymbolType.BYTE, scope, Variable.MemoryArea.MAIN_MEMORY, null);
|
||||
Variable v5 = new Variable( "m5", Variable.Kind.LOAD_STORE, SymbolType.BYTE, scope, Variable.MemoryArea.MAIN_MEMORY, null);
|
||||
Variable v6 = new Variable( "m6", Variable.Kind.LOAD_STORE, SymbolType.BYTE, scope, Variable.MemoryArea.MAIN_MEMORY, null);
|
||||
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);
|
||||
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));
|
||||
|
@ -23,7 +23,7 @@ public class CallingConventionStack {
|
||||
if(returnOffsetConstant == null) {
|
||||
// Constant not found - create it
|
||||
long returnByteOffset = getReturnByteOffset(procedure);
|
||||
returnOffsetConstant = new Variable(returnOffsetConstantName, SymbolType.BYTE, null, procedure, Scope.SEGMENT_DATA_DEFAULT, new ConstantInteger(returnByteOffset & 0xff, SymbolType.BYTE));
|
||||
returnOffsetConstant = Variable.createConstant(returnOffsetConstantName, SymbolType.BYTE, procedure, null, new ConstantInteger(returnByteOffset & 0xff, SymbolType.BYTE), Scope.SEGMENT_DATA_DEFAULT);
|
||||
procedure.add(returnOffsetConstant);
|
||||
}
|
||||
return returnOffsetConstant.getConstantRef();
|
||||
@ -42,7 +42,7 @@ public class CallingConventionStack {
|
||||
if(paramOffsetConstant == null) {
|
||||
// Constant not found - create it
|
||||
long paramByteOffset = getParameterByteOffset(procedure, parameter);
|
||||
paramOffsetConstant = new Variable(paramOffsetConstantName, SymbolType.BYTE, null, procedure, Scope.SEGMENT_DATA_DEFAULT, new ConstantInteger(paramByteOffset & 0xff, SymbolType.BYTE));
|
||||
paramOffsetConstant = Variable.createConstant(paramOffsetConstantName, SymbolType.BYTE, procedure, null, new ConstantInteger(paramByteOffset & 0xff, SymbolType.BYTE), Scope.SEGMENT_DATA_DEFAULT);
|
||||
procedure.add(paramOffsetConstant);
|
||||
}
|
||||
return paramOffsetConstant.getConstantRef();
|
||||
@ -123,7 +123,7 @@ public class CallingConventionStack {
|
||||
*/
|
||||
public static ConstantRef getStackBaseConstant(ProgramScope programScope) {
|
||||
long STACK_BASE_ADDRESS = 0x103L;
|
||||
Variable stackBase = new Variable("STACK_BASE", SymbolType.WORD, null, programScope, Scope.SEGMENT_DATA_DEFAULT, new ConstantInteger(STACK_BASE_ADDRESS, SymbolType.WORD));
|
||||
Variable stackBase = Variable.createConstant("STACK_BASE", SymbolType.WORD, programScope, null, new ConstantInteger(STACK_BASE_ADDRESS, SymbolType.WORD), Scope.SEGMENT_DATA_DEFAULT);
|
||||
programScope.add(stackBase);
|
||||
return stackBase.getConstantRef();
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ public class OperatorSizeOf extends OperatorUnary {
|
||||
if(typeSizeConstant == null) {
|
||||
// Constant not found - create it
|
||||
long typeSize = type.getSizeBytes();
|
||||
typeSizeConstant = new Variable(typeConstName, SymbolType.BYTE, null, programScope, Scope.SEGMENT_DATA_DEFAULT, new ConstantInteger(typeSize&0xff, SymbolType.BYTE));
|
||||
typeSizeConstant = Variable.createConstant(typeConstName, SymbolType.BYTE, programScope, null, new ConstantInteger(typeSize&0xff, SymbolType.BYTE), Scope.SEGMENT_DATA_DEFAULT);
|
||||
programScope.add(typeSizeConstant);
|
||||
}
|
||||
return typeSizeConstant.getConstantRef();
|
||||
|
@ -47,7 +47,7 @@ public class OperatorTypeId extends OperatorUnary {
|
||||
if(typeIdConstant == null) {
|
||||
// Constant not found - create it
|
||||
long typeSize = getTypeId(type);
|
||||
typeIdConstant = new Variable(typeConstName, SymbolType.BYTE, null, programScope, Scope.SEGMENT_DATA_DEFAULT, new ConstantInteger(typeSize));
|
||||
typeIdConstant = Variable.createConstant(typeConstName, SymbolType.BYTE, programScope, null, new ConstantInteger(typeSize), Scope.SEGMENT_DATA_DEFAULT);
|
||||
programScope.add(typeIdConstant);
|
||||
}
|
||||
return typeIdConstant.getConstantRef();
|
||||
|
@ -100,17 +100,9 @@ public abstract class Scope implements Symbol, Serializable {
|
||||
symbols.remove(symbol.getLocalName());
|
||||
}
|
||||
|
||||
public Variable addVariable(Variable.Kind kind, String name, SymbolType type, Variable.MemoryArea memoryArea, String dataSegment) {
|
||||
return add(new Variable( name, kind, type, this, memoryArea, dataSegment));
|
||||
}
|
||||
|
||||
public Variable addVariablePhiMaster(String name, SymbolType type, Variable.MemoryArea memoryArea, String dataSegment) {
|
||||
return add(new Variable( name, Variable.Kind.PHI_MASTER, type, this, memoryArea, dataSegment));
|
||||
}
|
||||
|
||||
public Variable addVariableIntermediate() {
|
||||
String name = allocateIntermediateVariableName();
|
||||
return add(new Variable( name, Variable.Kind.INTERMEDIATE, SymbolType.VAR, this, Variable.MemoryArea.ZEROPAGE_MEMORY, getSegmentData()));
|
||||
return add(Variable.createIntermediate( name, this, getSegmentData()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5,6 +5,7 @@ import dk.camelot64.kickc.model.InternalError;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.Registers;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypePointer;
|
||||
import dk.camelot64.kickc.model.values.ConstantRef;
|
||||
import dk.camelot64.kickc.model.values.ConstantValue;
|
||||
import dk.camelot64.kickc.model.values.SymbolVariableRef;
|
||||
@ -14,12 +15,12 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/** A Variable symbol (can either be a runtime variable or a compile-time constant)*/
|
||||
/** A Variable symbol (can either be a runtime variable or a compile-time constant) */
|
||||
public class Variable implements Symbol {
|
||||
|
||||
/**
|
||||
* The kind of the variable. The kind is the most significant property of the variable since it drives most of the behavior.
|
||||
*
|
||||
* <p>
|
||||
* The value depends on the directives memory/register/volatile/const - and on the compilers optimization decisions.
|
||||
* <ul>
|
||||
* <li>PHI_MASTER variables are turned into PHI-versions and PHI-nodes are used for them throughout the entire program. The PHI-master itself is only an information container and does not live in memory at runtime.</li>
|
||||
@ -33,7 +34,7 @@ public class Variable implements Symbol {
|
||||
PHI_MASTER, PHI_VERSION, INTERMEDIATE, LOAD_STORE, CONSTANT
|
||||
}
|
||||
|
||||
/** The kind of the variable. */
|
||||
/** The kind of the variable. */
|
||||
private Kind kind;
|
||||
|
||||
/** The local name of the variable. [ALL] */
|
||||
@ -42,13 +43,13 @@ public class Variable implements Symbol {
|
||||
/** Full name of variable including scope (scope::name or name) [ALL] */
|
||||
private String fullName;
|
||||
|
||||
/** A short name used for the variable in ASM code. If possible variable names of variables are shortened in ASM code. This is possible, when several versions of the var use the same register. [ALL]*/
|
||||
/** A short name used for the variable in ASM code. If possible variable names of variables are shortened in ASM code. This is possible, when several versions of the var use the same register. [ALL] */
|
||||
private String asmName;
|
||||
|
||||
/** The scope containing the variable. [ALL] */
|
||||
private Scope scope;
|
||||
|
||||
/** The type of the variable. VAR means the type is unknown, and has not been inferred yet. [ALL]*/
|
||||
/** The type of the variable. VAR means the type is unknown, and has not been inferred yet. [ALL] */
|
||||
private SymbolType type;
|
||||
|
||||
/** Specifies that the variable must be aligned in memory. Only allowed for arrays & strings. [Only Variables in memory and arrays] */
|
||||
@ -60,7 +61,7 @@ public class Variable implements Symbol {
|
||||
/** Specifies that the variable is declared as const */
|
||||
private boolean declaredConst;
|
||||
|
||||
/** Specifies that the variable must always live in memory to be available for any multi-threaded accees (eg. in interrupts). [Only Variables]*/
|
||||
/** Specifies that the variable must always live in memory to be available for any multi-threaded accees (eg. in interrupts). [Only Variables] */
|
||||
private boolean declaredVolatile;
|
||||
|
||||
/** Specifies that the variable must always live in memory to be available for any multi-threaded accees (eg. in interrupts). [Only variables] TODO: Remove this */
|
||||
@ -84,7 +85,7 @@ public class Variable implements Symbol {
|
||||
/** The constant value if the variable is a constant. Null otherwise. [Only constants] */
|
||||
private ConstantValue constantValue;
|
||||
|
||||
/** Non-null if the variable is an array. [Only constants that are arrays]*/
|
||||
/** Non-null if the variable is an array. [Only constants that are arrays] */
|
||||
private ArraySpec arraySpec;
|
||||
|
||||
/** The number of the next version (only used for PHI masters) [Only PHI masters] */
|
||||
@ -99,21 +100,26 @@ public class Variable implements Symbol {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a runtime variable
|
||||
* Create a variable (or constant)
|
||||
*
|
||||
* @param name The name
|
||||
* @param kind The storage strategy (PHI-master/PHI-version/Intermediate/load store/constant)
|
||||
* @param type The type
|
||||
* @param scope The scope
|
||||
* @param memoryArea The memory area (zeropage/main memory)
|
||||
* @param memoryArea The memory area (zeropage/main memory)
|
||||
* @param dataSegment The data segment (in main memory)
|
||||
* @param arraySpec The array specification of the variable (if it is an array)
|
||||
* @param constantValue The constant value of the variable (if it is constant)
|
||||
*/
|
||||
public Variable(String name, Kind kind, SymbolType type, Scope scope, MemoryArea memoryArea, String dataSegment) {
|
||||
private Variable(String name, Kind kind, SymbolType type, Scope scope, MemoryArea memoryArea, String dataSegment, ArraySpec arraySpec, ConstantValue constantValue) {
|
||||
this.name = name;
|
||||
this.kind = kind;
|
||||
if(Kind.PHI_MASTER.equals(kind))
|
||||
this.nextPhiVersionNumber = 0;
|
||||
this.type = type;
|
||||
this.scope = scope;
|
||||
this.arraySpec = arraySpec;
|
||||
this.constantValue = constantValue;
|
||||
this.dataSegment = dataSegment;
|
||||
this.memoryArea = memoryArea;
|
||||
this.comments = new ArrayList<>();
|
||||
@ -121,74 +127,132 @@ public class Variable implements Symbol {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a compile-time constant variable
|
||||
* Create an intermediate variable. The type will initially be set to {@link SymbolType#VAR}.
|
||||
*
|
||||
* @param name The name
|
||||
* @param type The type
|
||||
* @param scope The scope
|
||||
* @param dataSegment The data segment (in main memory)
|
||||
* @param value The constant value
|
||||
* @return The new intermediate variable
|
||||
*/
|
||||
public Variable(String name, SymbolType type, ArraySpec arraySpec, Scope scope, String dataSegment, ConstantValue value) {
|
||||
this(name, Kind.CONSTANT, type, scope, MemoryArea.MAIN_MEMORY, dataSegment);
|
||||
this.arraySpec = arraySpec;
|
||||
this.constantValue = value;
|
||||
public static Variable createIntermediate(String name, Scope scope, String dataSegment) {
|
||||
return new Variable(name, Kind.INTERMEDIATE, SymbolType.VAR, scope, MemoryArea.ZEROPAGE_MEMORY, dataSegment, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a constant version of a variable
|
||||
* @param variable The variable to create a constant version of
|
||||
* @param constVal The constant value
|
||||
* 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 Variable(Variable variable, ConstantValue constVal) {
|
||||
this(variable.getName(),variable.getType(), variable.getArraySpec(), variable.getScope(), variable.getDataSegment(), constVal);
|
||||
this.setDeclaredAlignment(variable.getDeclaredAlignment());
|
||||
this.setDeclaredAsRegister(variable.isDeclaredAsRegister());
|
||||
this.setDeclaredConst(variable.isDeclaredConst());
|
||||
this.setDeclaredRegister(variable.getDeclaredRegister());
|
||||
this.setDeclaredVolatile(variable.isDeclaredVolatile());
|
||||
this.setDeclaredExport(variable.isDeclaredExport());
|
||||
this.setInferredVolatile(variable.isInferredVolatile());
|
||||
this.setComments(variable.getComments());
|
||||
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, 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, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a version of a PHI master variable
|
||||
*
|
||||
* @param phiMaster The PHI master variable.
|
||||
* @param version The version number
|
||||
* @param versionNum The version number
|
||||
*/
|
||||
private Variable(Variable phiMaster, int version) {
|
||||
this(phiMaster.getName() + "#" + version, Kind.PHI_VERSION, phiMaster.getType(), phiMaster.getScope(), phiMaster.getMemoryArea(), phiMaster.getDataSegment());
|
||||
this.setArraySpec(phiMaster.getArraySpec());
|
||||
this.setDeclaredAlignment(phiMaster.getDeclaredAlignment());
|
||||
this.setDeclaredAsRegister(phiMaster.isDeclaredAsRegister());
|
||||
this.setDeclaredConst(phiMaster.isDeclaredConst());
|
||||
this.setDeclaredRegister(phiMaster.getDeclaredRegister());
|
||||
this.setDeclaredVolatile(phiMaster.isDeclaredVolatile());
|
||||
this.setDeclaredExport(phiMaster.isDeclaredExport());
|
||||
this.setInferredVolatile(phiMaster.isInferredVolatile());
|
||||
this.setComments(phiMaster.getComments());
|
||||
public static Variable createPhiVersion(Variable phiMaster, int versionNum) {
|
||||
Variable version = new Variable(phiMaster.getName() + "#" + versionNum, Kind.PHI_VERSION, phiMaster.getType(), phiMaster.getScope(), phiMaster.getMemoryArea(), phiMaster.getDataSegment(), phiMaster.getArraySpec(), null);
|
||||
version.setDeclaredAlignment(phiMaster.getDeclaredAlignment());
|
||||
version.setDeclaredAsRegister(phiMaster.isDeclaredAsRegister());
|
||||
version.setDeclaredConst(phiMaster.isDeclaredConst());
|
||||
version.setDeclaredRegister(phiMaster.getDeclaredRegister());
|
||||
version.setDeclaredVolatile(phiMaster.isDeclaredVolatile());
|
||||
version.setDeclaredExport(phiMaster.isDeclaredExport());
|
||||
version.setInferredVolatile(phiMaster.isInferredVolatile());
|
||||
version.setComments(phiMaster.getComments());
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a compile-time constant variable
|
||||
*
|
||||
* @param name The name
|
||||
* @param type The type
|
||||
* @param scope The scope
|
||||
* @param value The constant value
|
||||
* @param dataSegment The data segment (in main memory)
|
||||
*/
|
||||
public static Variable createConstant(String name, SymbolType type, Scope scope, ArraySpec arraySpec, ConstantValue value, String dataSegment) {
|
||||
return new Variable(name, Kind.CONSTANT, type, scope, MemoryArea.MAIN_MEMORY, dataSegment, arraySpec, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a constant version of a variable. Used when a variable is determined to be constant during the compile.
|
||||
*
|
||||
* @param variable The variable to create a constant version of
|
||||
* @param constVal The constant value
|
||||
*/
|
||||
public static Variable createConstant(Variable variable, ConstantValue constVal) {
|
||||
Variable constVar = createConstant(variable.getName(), variable.getType(), variable.getScope(), variable.getArraySpec(), constVal, variable.getDataSegment());
|
||||
constVar.setDeclaredAlignment(variable.getDeclaredAlignment());
|
||||
constVar.setDeclaredAsRegister(variable.isDeclaredAsRegister());
|
||||
constVar.setDeclaredConst(variable.isDeclaredConst());
|
||||
constVar.setDeclaredRegister(variable.getDeclaredRegister());
|
||||
constVar.setDeclaredVolatile(variable.isDeclaredVolatile());
|
||||
constVar.setDeclaredExport(variable.isDeclaredExport());
|
||||
constVar.setInferredVolatile(variable.isInferredVolatile());
|
||||
constVar.setComments(variable.getComments());
|
||||
return constVar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a copy of a variable with a different name in a different scope
|
||||
*
|
||||
* @param name The name
|
||||
* @param scope The scope
|
||||
* @param name The name for the new variable
|
||||
* @param scope The scope for the new variable
|
||||
* @param original The original variable
|
||||
*/
|
||||
public Variable(String name, Scope scope, Variable original) {
|
||||
this(name, original.getKind(), original.getType(), scope, original.getMemoryArea(), original.getDataSegment());
|
||||
this.setArraySpec(original.getArraySpec());
|
||||
this.setDeclaredAlignment(original.getDeclaredAlignment());
|
||||
this.setDeclaredAsRegister(original.isDeclaredAsRegister());
|
||||
this.setDeclaredConst(original.isDeclaredConst());
|
||||
this.setDeclaredVolatile(original.isDeclaredVolatile());
|
||||
this.setDeclaredExport(original.isDeclaredExport());
|
||||
this.setDeclaredRegister(original.getDeclaredRegister());
|
||||
this.setInferredVolatile(original.isInferredVolatile());
|
||||
this.setComments(original.getComments());
|
||||
this.setConstantValue(original.getConstantValue());
|
||||
public static Variable createCopy(String name, Scope scope, Variable original) {
|
||||
Variable copy = new Variable(name, original.getKind(), original.getType(), scope, original.getMemoryArea(), original.getDataSegment(), original.getArraySpec(), original.getConstantValue());
|
||||
copy.setDeclaredAlignment(original.getDeclaredAlignment());
|
||||
copy.setDeclaredAsRegister(original.isDeclaredAsRegister());
|
||||
copy.setDeclaredConst(original.isDeclaredConst());
|
||||
copy.setDeclaredVolatile(original.isDeclaredVolatile());
|
||||
copy.setDeclaredExport(original.isDeclaredExport());
|
||||
copy.setDeclaredRegister(original.getDeclaredRegister());
|
||||
copy.setInferredVolatile(original.isInferredVolatile());
|
||||
copy.setComments(original.getComments());
|
||||
return copy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a variable representing a single member of a struct variable.
|
||||
* @param structVar The variable that holds a struct value.
|
||||
* @param memberDefinition The definition of the struct member
|
||||
* @return The new unwound variable representing the member of the struct
|
||||
*/
|
||||
public static Variable createStructMemberUnwound(Variable structVar, Variable memberDefinition) {
|
||||
String name = structVar.getLocalName() + "_" + memberDefinition.getLocalName();
|
||||
Variable.MemoryArea memoryArea = (memberDefinition.getType() instanceof SymbolTypePointer) ? Variable.MemoryArea.ZEROPAGE_MEMORY : structVar.getMemoryArea();
|
||||
Variable memberVariable = new Variable(name, structVar.getKind(), memberDefinition.getType(), structVar.getScope(), memoryArea, structVar.getDataSegment(), null, null);
|
||||
memberVariable.setArraySpec(memberDefinition.getArraySpec());
|
||||
memberVariable.setDeclaredVolatile(structVar.isDeclaredVolatile());
|
||||
memberVariable.setInferredVolatile(structVar.isInferredVolatile());
|
||||
memberVariable.setDeclaredConst(structVar.isDeclaredConst());
|
||||
memberVariable.setDeclaredExport(structVar.isDeclaredExport());
|
||||
return memberVariable;
|
||||
}
|
||||
|
||||
public Kind getKind() {
|
||||
@ -252,7 +316,7 @@ public class Variable implements Symbol {
|
||||
public Variable createVersion() {
|
||||
if(!isKindPhiMaster())
|
||||
throw new InternalError("Cannot version non-PHI variable " + this.toString());
|
||||
Variable version = new Variable(this, nextPhiVersionNumber++);
|
||||
Variable version = Variable.createPhiVersion(this, nextPhiVersionNumber++);
|
||||
getScope().add(version);
|
||||
return version;
|
||||
}
|
||||
@ -271,7 +335,7 @@ public class Variable implements Symbol {
|
||||
}
|
||||
|
||||
public boolean isArray() {
|
||||
return arraySpec!=null;
|
||||
return arraySpec != null;
|
||||
}
|
||||
|
||||
public ArraySpec getArraySpec() {
|
||||
|
@ -4,6 +4,7 @@ import dk.camelot64.kickc.NumberParser;
|
||||
import dk.camelot64.kickc.SourceLoader;
|
||||
import dk.camelot64.kickc.asm.AsmClobber;
|
||||
import dk.camelot64.kickc.model.*;
|
||||
import dk.camelot64.kickc.model.InternalError;
|
||||
import dk.camelot64.kickc.model.iterator.ProgramValue;
|
||||
import dk.camelot64.kickc.model.operators.*;
|
||||
import dk.camelot64.kickc.model.statements.*;
|
||||
@ -208,7 +209,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
Label procExit = procedure.addLabel(SymbolRef.PROCEXIT_BLOCK_NAME);
|
||||
Variable returnVar = null;
|
||||
if(!SymbolType.VOID.equals(type)) {
|
||||
returnVar = procedure.addVariablePhiMaster("return", type, defaultMemoryArea, procedure.getSegmentData());
|
||||
returnVar = procedure.add(Variable.createPhiMaster("return", type, procedure, defaultMemoryArea, procedure.getSegmentData()));
|
||||
}
|
||||
List<Variable> parameterList = new ArrayList<>();
|
||||
if(ctx.parameterListDecl() != null) {
|
||||
@ -267,7 +268,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
this.visitDeclTypes(ctx.declTypes());
|
||||
SymbolType type = declVarType;
|
||||
List<Directive> directives = declVarDirectives;
|
||||
Variable param = new Variable( ctx.NAME().getText(), Variable.Kind.PHI_MASTER, type, getCurrentScope(), defaultMemoryArea, currentDataSegment);
|
||||
Variable param = Variable.createPhiMaster( ctx.NAME().getText(), type, getCurrentScope(), defaultMemoryArea, currentDataSegment);
|
||||
// Add directives
|
||||
directiveContext.applyDirectives(param, true, false, directives, new StatementSource(ctx));
|
||||
exitDeclTypes();
|
||||
@ -577,14 +578,22 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
arraySpec = new ArraySpec(declArraySize);
|
||||
}
|
||||
Scope scope = getCurrentScope();
|
||||
Variable constVar = new Variable(varName, declVarType, arraySpec, scope, currentDataSegment, initConstantValue);
|
||||
Variable constVar = Variable.createConstant(varName, declVarType, scope, arraySpec, initConstantValue, currentDataSegment);
|
||||
scope.add(constVar);
|
||||
// Add comments to constant
|
||||
constVar.setComments(ensureUnusedComments(declVarComments));
|
||||
directiveContext.applyDirectives(constVar, false, declIsArray, declVarDirectives, statementSource);
|
||||
} else {
|
||||
// Create variable
|
||||
Variable lValue = getCurrentScope().addVariable(kind, varName, declVarType, defaultMemoryArea, currentDataSegment);
|
||||
Variable lValue;
|
||||
if(kind.equals(Variable.Kind.PHI_MASTER)) {
|
||||
lValue = Variable.createPhiMaster(varName, declVarType, getCurrentScope(), defaultMemoryArea, currentDataSegment);
|
||||
} else if (kind.equals(Variable.Kind.LOAD_STORE)) {
|
||||
lValue = Variable.createLoadStore(varName, declVarType, getCurrentScope(), defaultMemoryArea, currentDataSegment);
|
||||
} else {
|
||||
throw new InternalError("Unexpected variable kind! "+kind.name(), statementSource);
|
||||
}
|
||||
getCurrentScope().add(lValue);
|
||||
// Add directives
|
||||
directiveContext.applyDirectives(lValue, false, declIsArray, declVarDirectives, statementSource);
|
||||
if(declVarStructMember) {
|
||||
@ -715,7 +724,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
}
|
||||
// Add a constant variable
|
||||
Scope scope = getCurrentScope();
|
||||
Variable constVar = new Variable(varName, declVarType, arraySpec, scope, currentDataSegment, constantArrayKickAsm);
|
||||
Variable constVar = Variable.createConstant(varName, declVarType, scope, arraySpec, constantArrayKickAsm, currentDataSegment);
|
||||
scope.add(constVar);
|
||||
// Add comments to constant
|
||||
constVar.setComments(ensureUnusedComments(declVarComments));
|
||||
@ -1236,7 +1245,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
Variable lValue;
|
||||
if(varType != null) {
|
||||
try {
|
||||
lValue = getCurrentScope().addVariablePhiMaster(varName, varType, defaultMemoryArea, currentDataSegment);
|
||||
lValue = getCurrentScope().add(Variable.createPhiMaster(varName, varType, getCurrentScope(), defaultMemoryArea, currentDataSegment));
|
||||
} catch(CompileError e) {
|
||||
throw new CompileError(e.getMessage(), statementSource);
|
||||
}
|
||||
@ -1542,7 +1551,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
Scope parentScope = getCurrentScope();
|
||||
while(parentScope instanceof StructDefinition) parentScope = parentScope.getScope();
|
||||
for(Variable member : enumDefinition.getAllConstants(false)) {
|
||||
parentScope.add(new Variable(member.getLocalName(), SymbolType.BYTE, null, parentScope, currentDataSegment, member.getConstantValue()));
|
||||
parentScope.add(Variable.createConstant(member.getLocalName(), SymbolType.BYTE, parentScope, null, member.getConstantValue(), currentDataSegment));
|
||||
}
|
||||
return SymbolType.BYTE;
|
||||
} catch(CompileError e) {
|
||||
@ -1576,7 +1585,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
}
|
||||
}
|
||||
}
|
||||
currentEnum.add(new Variable(memberName, SymbolType.BYTE, null, getCurrentScope(), currentDataSegment, enumValue));
|
||||
currentEnum.add(Variable.createConstant(memberName, SymbolType.BYTE, getCurrentScope(), null, enumValue, currentDataSegment));
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -1661,7 +1670,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
scopeStack.push(typedefScope);
|
||||
SymbolType type = (SymbolType) this.visit(ctx.typeDecl());
|
||||
String typedefName = ctx.NAME().getText();
|
||||
typedefScope.addVariablePhiMaster(typedefName, type, defaultMemoryArea, currentDataSegment);
|
||||
typedefScope.add(Variable.createPhiMaster(typedefName, type, typedefScope, defaultMemoryArea, currentDataSegment));
|
||||
scopeStack.pop();
|
||||
return null;
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ public class Pass1EarlyConstantIdentification extends Pass1Base {
|
||||
SymbolVariableRef variableRef = variable.getRef();
|
||||
Scope scope = variable.getScope();
|
||||
scope.remove(variable);
|
||||
Variable constVar = new Variable(variable, constantValue);
|
||||
Variable constVar = Variable.createConstant(variable, constantValue);
|
||||
constVar.getComments().addAll(assignment.getComments());
|
||||
SymbolVariableRef constRef = constVar.getRef();
|
||||
aliases.put(variableRef, constRef);
|
||||
|
@ -74,7 +74,7 @@ public class Pass1ExtractInlineStrings extends Pass1Base {
|
||||
name = nameHint + nameHintIdx++;
|
||||
}
|
||||
}
|
||||
Variable strConst = new Variable(name, SymbolType.STRING, new ArraySpec(), blockScope, blockScope.getSegmentData(), constantString);
|
||||
Variable strConst = Variable.createConstant(name, SymbolType.STRING, blockScope, new ArraySpec(), constantString, blockScope.getSegmentData());
|
||||
blockScope.add(strConst);
|
||||
if(getLog().isVerbosePass1CreateSsa()) {
|
||||
getLog().append("Creating constant string variable for inline " + strConst.toString(getProgram()) + " \"" + constantString.getValue() + "\"");
|
||||
|
@ -300,7 +300,7 @@ public class Pass1ProcedureInline extends Pass1Base {
|
||||
if(procSymbol instanceof Variable) {
|
||||
Variable procVar = (Variable) procSymbol;
|
||||
String inlineVarName = getInlineSymbolName(procedure, procSymbol, serial);
|
||||
Variable inlineVar = new Variable(inlineVarName, callScope, procVar);
|
||||
Variable inlineVar = Variable.createCopy(inlineVarName, callScope, procVar);
|
||||
callScope.add(inlineVar);
|
||||
} else if(procSymbol instanceof Label) {
|
||||
String inlineLabelName = getInlineSymbolName(procedure, procSymbol, serial);
|
||||
|
@ -72,17 +72,17 @@ public class Pass1UnwindBlockScopes extends Pass1Base {
|
||||
Variable variable = (Variable) symbol;
|
||||
if(variable.isKindConstant()) {
|
||||
String name = findLocalName(procedure, symbol);
|
||||
Variable unwound = new Variable(name, procedure, (Variable) symbol);
|
||||
Variable unwound = Variable.createCopy(name, procedure, (Variable) symbol);
|
||||
procedure.add(unwound);
|
||||
unwoundSymbols.put(symbol.getRef(), unwound.getRef());
|
||||
} else if(variable.isKindPhiMaster() || variable.isKindConstant()) {
|
||||
String name = findLocalName(procedure, symbol);
|
||||
Variable unwound = new Variable(name, procedure, (Variable) symbol);
|
||||
Variable unwound = Variable.createCopy(name, procedure, (Variable) symbol);
|
||||
procedure.add(unwound);
|
||||
unwoundSymbols.put(symbol.getRef(), unwound.getRef());
|
||||
} else if(variable.isKindIntermediate()) {
|
||||
String name = procedure.allocateIntermediateVariableName();
|
||||
Variable unwound = new Variable(name, procedure, (Variable) symbol);
|
||||
Variable unwound = Variable.createCopy(name, procedure, (Variable) symbol);
|
||||
procedure.add(unwound);
|
||||
unwoundSymbols.put(symbol.getRef(), unwound.getRef());
|
||||
} else {
|
||||
|
@ -207,14 +207,8 @@ public class Pass1UnwindStructValues extends Pass1Base {
|
||||
StructDefinition structDefinition = ((SymbolTypeStruct) variable.getType()).getStructDefinition(getProgram().getScope());
|
||||
StructUnwinding.VariableUnwinding variableUnwinding = structUnwinding.createVariableUnwinding(variable.getRef());
|
||||
for(Variable member : structDefinition.getAllVars(false)) {
|
||||
String name = variable.getLocalName() + "_" + member.getLocalName();
|
||||
Variable.MemoryArea memoryArea = (member.getType() instanceof SymbolTypePointer)?Variable.MemoryArea.ZEROPAGE_MEMORY:variable.getMemoryArea();
|
||||
Variable memberVariable = scope.add(new Variable( name, variable.getKind(), member.getType(), scope, memoryArea, variable.getDataSegment()));
|
||||
memberVariable.setArraySpec(member.getArraySpec());
|
||||
memberVariable.setDeclaredVolatile(variable.isDeclaredVolatile());
|
||||
memberVariable.setInferredVolatile(variable.isInferredVolatile());
|
||||
memberVariable.setDeclaredConst(variable.isDeclaredConst());
|
||||
memberVariable.setDeclaredExport(variable.isDeclaredExport());
|
||||
Variable memberVariable = Variable.createStructMemberUnwound(variable, member);
|
||||
scope.add(memberVariable);
|
||||
variableUnwinding.setMemberUnwinding(member.getLocalName(), memberVariable.getRef());
|
||||
getLog().append("Created struct value member variable " + memberVariable.toString(getProgram()));
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
|
||||
);
|
||||
}
|
||||
scope.remove(variable);
|
||||
Variable constVar = new Variable(variable, constVal);
|
||||
Variable constVar = Variable.createConstant(variable, constVal);
|
||||
constVar.getComments().addAll(constVarVal.getAssignment().getComments());
|
||||
scope.add(constVar);
|
||||
constAliases.put(constRef, constVar.getRef());
|
||||
|
@ -93,7 +93,7 @@ public class Pass2ConstantStringConsolidation extends Pass2SsaOptimization {
|
||||
// Create a new root - and roll around again
|
||||
ProgramScope rootScope = getScope();
|
||||
String localName = getRootName(constantVars);
|
||||
Variable newRootConstant = new Variable(localName, SymbolType.STRING, new ArraySpec(), rootScope, segmentData, constString);
|
||||
Variable newRootConstant = Variable.createConstant(localName, SymbolType.STRING, rootScope, new ArraySpec(), constString, segmentData);
|
||||
rootScope.add(newRootConstant);
|
||||
rootConstant = newRootConstant;
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ public class PassNStructPointerRewriting extends Pass2SsaOptimization {
|
||||
// Constant not found - create it
|
||||
Variable memberDef = structDefinition.getMember(memberName);
|
||||
long memberByteOffset = structDefinition.getMemberByteOffset(memberDef, programScope);
|
||||
memberOffsetConstant = new Variable(typeConstName, SymbolType.BYTE, null, programScope, Scope.SEGMENT_DATA_DEFAULT, new ConstantInteger(memberByteOffset & 0xff, SymbolType.BYTE));
|
||||
memberOffsetConstant = Variable.createConstant(typeConstName, SymbolType.BYTE, programScope, null, new ConstantInteger(memberByteOffset & 0xff, SymbolType.BYTE), Scope.SEGMENT_DATA_DEFAULT);
|
||||
programScope.add(memberOffsetConstant);
|
||||
}
|
||||
return memberOffsetConstant.getConstantRef();
|
||||
|
@ -231,7 +231,7 @@ public class Unroller {
|
||||
if(definedVarRef.isIntermediate()) {
|
||||
Scope scope = definedVar.getScope();
|
||||
String name = scope.allocateIntermediateVariableName();
|
||||
newVar = new Variable(name, scope, definedVar);
|
||||
newVar = Variable.createCopy(name, scope, definedVar);
|
||||
scope.add(newVar);
|
||||
} else if(definedVarRef.isVersion()) {
|
||||
newVar = (definedVar).getVersionOf().createVersion();
|
||||
|
Loading…
x
Reference in New Issue
Block a user