1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-06-03 07:29:37 +00:00

- Fixed test cases. Full retest of all test cases.

- Treat global variables of libraries, as part of the .asm library .namespace.
- Fix bugs.
- Assign meaningful struct names to .asm internal variables and labels. (Remove the $x notation).
This commit is contained in:
Flight_Control 2024-04-19 16:55:24 +03:00
parent e371d304f6
commit 00df07b7bf
70 changed files with 762 additions and 444 deletions

View File

@ -13,6 +13,8 @@ import dk.camelot64.kickc.model.types.SymbolTypeInference;
import dk.camelot64.kickc.model.types.SymbolTypePointer; import dk.camelot64.kickc.model.types.SymbolTypePointer;
import dk.camelot64.kickc.model.values.*; import dk.camelot64.kickc.model.values.*;
import java.util.HashMap;
/** Formatting of numbers, constants, names and more for KickAssembler */ /** Formatting of numbers, constants, names and more for KickAssembler */
public class AsmFormat { public class AsmFormat {
@ -287,11 +289,12 @@ public class AsmFormat {
public static String getAsmSymbolName(Program program, Symbol symbol, ScopeRef codeScopeRef) { public static String getAsmSymbolName(Program program, Symbol symbol, ScopeRef codeScopeRef) {
ScopeRef symbolScopeRef = symbol.getScope().getRef(); ScopeRef symbolScopeRef = symbol.getScope().getRef();
String asmName = symbol.getLocalName(); String asmName = symbol.getLocalName();
String asmLibraryLabel = null; String asmLibraryLabel = "";
if(symbol instanceof Variable boundVariable) { if(symbol instanceof Variable boundVariable) {
if (boundVariable.getAsmName() != null) { if (boundVariable.getAsmName() != null) {
asmName = boundVariable.getAsmName(); asmName = boundVariable.getAsmName();
asmLibraryLabel = boundVariable.getAsmExportLibraryLabel(); if(boundVariable.getAsmExportLibraryLabel() != null)
asmLibraryLabel = boundVariable.getAsmExportLibraryLabel() + ".";
} }
} }
if(!symbolScopeRef.equals(codeScopeRef)) { if(!symbolScopeRef.equals(codeScopeRef)) {
@ -299,11 +302,12 @@ public class AsmFormat {
if (codeScopeRef instanceof ProcedureRef procedureRef) { if (codeScopeRef instanceof ProcedureRef procedureRef) {
Procedure procedure = program.getScope().getProcedure(procedureRef); Procedure procedure = program.getScope().getProcedure(procedureRef);
String procedureAsmLibraryLabel = procedure.getAsmLibraryLabel(); String procedureAsmLibraryLabel = procedure.getAsmLibraryLabel();
if (asmLibraryLabel != null) { // #820/34 - Handle global variables within libraries correctly.
if (!asmLibraryLabel.isEmpty()) {
if (procedureAsmLibraryLabel != null && procedureAsmLibraryLabel.equals(asmLibraryLabel)) { if (procedureAsmLibraryLabel != null && procedureAsmLibraryLabel.equals(asmLibraryLabel)) {
return asmFix2(symbolScopeRef.getFullName() + "." + asmName, symbolScopeRef.getFullName()); return asmFix2(symbolScopeRef.getFullName() + "." + asmName, symbolScopeRef.getFullName());
} else { } else {
return asmFix2(asmLibraryLabel + "." + symbolScopeRef.getFullName() + "." + asmName, symbolScopeRef.getFullName()); return asmFix2(asmLibraryLabel + symbolScopeRef.getFullName() + "." + asmName, symbolScopeRef.getFullName());
} }
} }
} }
@ -332,7 +336,22 @@ public class AsmFormat {
if (namespace != null) if (namespace != null)
asmName = namespace + "." + asmName; asmName = namespace + "." + asmName;
} }
return asmFix2(asmName, codeScopeRef.getLocalName()); // #820/34 - Handle global variables within libraries.
if(codeScopeRef.equals(ScopeRef.ROOT)) {
String asmLibraryName = program.getScope().getAsmLibraryName();
HashMap<String, Symbol> asmLibraryNameSpaceSymbols = program.getAsmLibraryNamespaceSymbols();
if(program.isAsmLibraryNamespace()) {
asmLibraryNameSpaceSymbols.put(asmName, symbol);
}
if(asmLibraryName.isEmpty() || asmLibraryNameSpaceSymbols.get(asmName) == null) {
return asmFix2(asmName, codeScopeRef.getLocalName());
} else {
asmLibraryName = asmLibraryName + ".";
return asmLibraryName + asmFix2(asmName, codeScopeRef.getLocalName());
}
} else {
return asmFix2(asmName, codeScopeRef.getLocalName());
}
} }
} }

View File

@ -7,6 +7,8 @@ import dk.camelot64.kickc.model.symbols.Procedure;
import dk.camelot64.kickc.model.symbols.Scope; import dk.camelot64.kickc.model.symbols.Scope;
import dk.camelot64.kickc.model.symbols.Symbol; import dk.camelot64.kickc.model.symbols.Symbol;
import dk.camelot64.kickc.model.symbols.Variable; import dk.camelot64.kickc.model.symbols.Variable;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypeStruct;
import dk.camelot64.kickc.model.values.*; import dk.camelot64.kickc.model.values.*;
import java.nio.file.Path; import java.nio.file.Path;
@ -257,9 +259,15 @@ public class AsmLibrary extends AsmLine {
private String generateVariableStructForward(Variable variable, Program program) { private String generateVariableStructForward(Variable variable, Program program) {
StringBuilder signature = new StringBuilder(); StringBuilder signature = new StringBuilder();
// #820/50 - Handle struct definitions correctly for proper declaration.
if(variable.isStruct()) { if(variable.isStruct()) {
String structName = variable.getType().toCDecl(); SymbolType symbolType = variable.getType();
signature.append(structName).append(";\n"); if(symbolType instanceof SymbolTypeStruct typeStruct) {
if(typeStruct.getTypeDefName() == null) {
String structName = variable.getType().toCDecl();
signature.append(structName).append(";\n");
}
}
} }
return signature.toString(); return signature.toString();
@ -313,7 +321,11 @@ public class AsmLibrary extends AsmLine {
} }
} }
} }
headers.append(generateVariableHeader(globalVariable, program)); // TODO: #820/50 - Declaration of global variables only when they are exported using asm_export pragma.
// This requires rework. It is a challenge to generate only those global var
// By default at this moment, all global variables in libraries are encapsulated in the asm namespace.
// This prevents any conflict of global variables.
// headers.append(generateVariableHeader(globalVariable, program));
structs.append(generateVariableStructForward(globalVariable, program)); structs.append(generateVariableStructForward(globalVariable, program));
} }
} }

View File

@ -1,6 +1,6 @@
package dk.camelot64.kickc.asm; package dk.camelot64.kickc.asm;
/** The end of a namespace scope (for an .asm library and other assembler level encapsulation purposes) */ /** #820/1 - The end of a namespace scope (for an .asm library and other assembler level encapsulation purposes) */
public class AsmNamespaceEnd extends AsmLine { public class AsmNamespaceEnd extends AsmLine {
public AsmNamespaceEnd() { public AsmNamespaceEnd() {
@ -18,7 +18,7 @@ public class AsmNamespaceEnd extends AsmLine {
@Override @Override
public String getAsm() { public String getAsm() {
return "}"; return "} // namespace";
} }
@Override @Override

View File

@ -138,9 +138,24 @@ public class AsmProgram {
return asmLabel; return asmLabel;
} }
public void addNamespaceBegin(String namespace) { addLine(new AsmNamespaceBegin(namespace)); }
public void addNamespaceEnd() { addLine(new AsmNamespaceEnd()); } /** #820/1 - Handle begin namespace for the .asm library.
*
* @param program
*/
public void addNamespaceBegin(Program program) {
program.setAsmLibraryNamespace(true);
addLine(new AsmNamespaceBegin(program.getAsmLibraryLabel()));
}
/** #820/1 - Handle end namespace for the .asm library.
*
* @param program
*/
public void addNamespaceEnd(Program program) {
program.setAsmLibraryNamespace(false);
addLine(new AsmNamespaceEnd());
}
public void addScopeBegin(String label) { public void addScopeBegin(String label) {
addLine(new AsmScopeBegin(label)); addLine(new AsmScopeBegin(label));

View File

@ -120,6 +120,16 @@ public class Program {
*/ */
private AsmIdentifier asmLibraryName; private AsmIdentifier asmLibraryName;
/** #820/34 - Declare global variables that aren't yet declared.
* Specifies whether during ASM generation, a library .namespace is active.
*/
private boolean asmLibraryNamespace;
/** #820/34 - Declare global variables that aren't yet declared.
* Keeps all the symbols that have been added into the library
*/
private HashMap<String, Symbol> asmLibraryNamespaceSymbols;
/** /**
* Defines the asm source to be imported with the defined procedures. * Defines the asm source to be imported with the defined procedures.
*/ */
@ -128,7 +138,7 @@ public class Program {
/** /**
* Defines the asm source to be exported with the defined procedures. * Defines the asm source to be exported with the defined procedures.
*/ */
private Map<String, AsmExportLibrary> asmExports; private final Map<String, AsmExportLibrary> asmExports;
/** All #pragma code segments. Collected during parsing. These are used by the bank() pragmas to validate if the code segment exists during compilation.*/ /** All #pragma code segments. Collected during parsing. These are used by the bank() pragmas to validate if the code segment exists during compilation.*/
@ -147,6 +157,8 @@ public class Program {
this.asmImports = new LinkedHashMap<>(); this.asmImports = new LinkedHashMap<>();
this.asmExports = new LinkedHashMap<>(); this.asmExports = new LinkedHashMap<>();
this.currentPath = new File(".").toPath(); this.currentPath = new File(".").toPath();
this.asmLibraryNamespace = false;
this.asmLibraryNamespaceSymbols = new HashMap<>();
} }
/** /**
@ -878,4 +890,21 @@ public class Program {
procedure.setDeclaredInline(false); procedure.setDeclaredInline(false);
} }
public boolean isAsmLibraryNamespace() {
return asmLibraryNamespace;
}
public void setAsmLibraryNamespace(boolean asmLibraryNamespace) {
this.asmLibraryNamespace = asmLibraryNamespace;
}
public HashMap<String, Symbol> getAsmLibraryNamespaceSymbols() {
return asmLibraryNamespaceSymbols;
}
public void setAsmLibraryNamespaceSymbols(HashMap<String, Symbol> asmLibraryNamespaceSymbols) {
this.asmLibraryNamespaceSymbols = asmLibraryNamespaceSymbols;
}
} }

View File

@ -1,5 +1,6 @@
package dk.camelot64.kickc.model.symbols; package dk.camelot64.kickc.model.symbols;
import dk.camelot64.kickc.asm.AsmIdentifier;
import dk.camelot64.kickc.model.InternalError; import dk.camelot64.kickc.model.InternalError;
import dk.camelot64.kickc.model.*; import dk.camelot64.kickc.model.*;
import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.types.SymbolType;
@ -17,7 +18,9 @@ public abstract class Scope implements Symbol {
/** The default data segment. */ /** The default data segment. */
public static final String SEGMENT_DATA_DEFAULT = "Data"; public static final String SEGMENT_DATA_DEFAULT = "Data";
private String name; protected String name;
protected AsmIdentifier asmLibraryIdentifier;
private HashMap<String, Symbol> symbols; private HashMap<String, Symbol> symbols;
private int intermediateVarCount = 0; private int intermediateVarCount = 0;
private int intermediateLabelCount = 1; private int intermediateLabelCount = 1;
@ -28,6 +31,7 @@ public abstract class Scope implements Symbol {
public Scope(String name, Scope parentScope, String segmentData) { public Scope(String name, Scope parentScope, String segmentData) {
this.name = name; this.name = name;
this.asmLibraryIdentifier = new AsmIdentifier("");
this.parentScope = parentScope; this.parentScope = parentScope;
this.symbols = new LinkedHashMap<>(); this.symbols = new LinkedHashMap<>();
this.segmentData = Objects.requireNonNull(segmentData); this.segmentData = Objects.requireNonNull(segmentData);
@ -47,7 +51,7 @@ public abstract class Scope implements Symbol {
return this.getScope().getContainingProcedure(); return this.getScope().getContainingProcedure();
} }
private void setFullName() { protected void setFullName() {
String scopeName = (parentScope == null) ? "" : parentScope.getFullName(); String scopeName = (parentScope == null) ? "" : parentScope.getFullName();
fullName = (scopeName.length() > 0) ? scopeName + "::" + name : name; fullName = (scopeName.length() > 0) ? scopeName + "::" + name : name;
} }
@ -185,6 +189,13 @@ public abstract class Scope implements Symbol {
return symbols.get(name); return symbols.get(name);
} }
public Symbol replaceLocalSymbol(String oldName, String newName) {
Symbol symbolValue = symbols.get(oldName);
symbols.put(newName, symbolValue);
symbols.remove(oldName);
return symbolValue;
}
/** /**
* Look for a symbol by it's (short) name. Looks through this scope first and then through any parent scope. * Look for a symbol by it's (short) name. Looks through this scope first and then through any parent scope.
* *
@ -343,6 +354,15 @@ public abstract class Scope implements Symbol {
return (StructDefinition) symbol; return (StructDefinition) symbol;
} }
public StructDefinition replaceLocalStructDefinition(String oldName, String newName) {
final Symbol oldSymbol = getLocalSymbol(oldName);
if(oldSymbol != null && !(oldSymbol instanceof StructDefinition))
throw new InternalError("Symbol is not a struct definition! " + oldSymbol.toString());
return (StructDefinition) replaceLocalSymbol(oldName, newName);
}
public EnumDefinition getLocalEnumDefinition(String name) { public EnumDefinition getLocalEnumDefinition(String name) {
final Symbol symbol = getLocalSymbol(name); final Symbol symbol = getLocalSymbol(name);
if(symbol != null && !(symbol instanceof EnumDefinition)) if(symbol != null && !(symbol instanceof EnumDefinition))
@ -454,4 +474,14 @@ public abstract class Scope implements Symbol {
return result; return result;
} }
public String getAsmLibraryName() {
if(asmLibraryIdentifier != null)
return asmLibraryIdentifier.getAsm();
else
return null;
}
public void setAsmLibraryName(String asmLibraryName) {
this.asmLibraryIdentifier.setIdentifier(asmLibraryName);
}
} }

View File

@ -7,19 +7,37 @@ import dk.camelot64.kickc.model.types.SymbolTypeStruct;
/** /**
* A struct definition containing a set of variables. * A struct definition containing a set of variables.
* The struct definition can either represent a struct (member memory-layout is linearly consecutive ) or a union (member start at the same memory address) * The struct definition can either represent a struct (member memory-layout is linearly consecutive ) or a union (member start at the same memory address)
* #820/50 - Link the typedef to the structure definition, if any.
*/ */
public class StructDefinition extends Scope { public class StructDefinition extends Scope {
private boolean isUnion; private boolean isUnion;
private SymbolTypeStruct typeDefStruct;
public StructDefinition(String name, boolean isUnion, Scope parentScope) { public StructDefinition(String name, boolean isUnion, Scope parentScope) {
super(name, parentScope, SEGMENT_DATA_DEFAULT); super(name, parentScope, SEGMENT_DATA_DEFAULT);
this.isUnion = isUnion; this.isUnion = isUnion;
this.typeDefStruct = null;
} }
@Override @Override
public SymbolType getType() { public SymbolType getType() {
return new SymbolTypeStruct(this, false, false); if(typeDefStruct == null) {
return new SymbolTypeStruct(this, false, false);
} else {
return typeDefStruct;
}
}
public void setName(String typedefName) {setFullName();}
public SymbolTypeStruct getTypeDefStruct() {
return typeDefStruct;
}
public void setTypeDefStruct(SymbolTypeStruct typeDefStruct) {
this.typeDefStruct = typeDefStruct;
} }
public boolean isUnion() { public boolean isUnion() {

View File

@ -101,6 +101,13 @@ public interface SymbolType {
return null; return null;
} }
/** #820/50 - Get the type definition of the type, if any */
default String getTypeDefName() {
return "";
}
default void setTypeDefName(String typeDefName) {}
/** /**
* Get the size of the type (in bytes). * Get the size of the type (in bytes).
* *

View File

@ -2,6 +2,7 @@ package dk.camelot64.kickc.model.types;
import dk.camelot64.kickc.model.symbols.ProgramScope; import dk.camelot64.kickc.model.symbols.ProgramScope;
import dk.camelot64.kickc.model.symbols.StructDefinition; import dk.camelot64.kickc.model.symbols.StructDefinition;
import dk.camelot64.kickc.model.symbols.Symbol;
import dk.camelot64.kickc.model.symbols.Variable; import dk.camelot64.kickc.model.symbols.Variable;
import dk.camelot64.kickc.model.values.ConstantInteger; import dk.camelot64.kickc.model.values.ConstantInteger;
import dk.camelot64.kickc.model.values.ConstantLiteral; import dk.camelot64.kickc.model.values.ConstantLiteral;
@ -10,7 +11,10 @@ import dk.camelot64.kickc.model.values.ConstantValue;
import java.util.Locale; import java.util.Locale;
import java.util.Objects; import java.util.Objects;
/** A struct/union */ /**
* A struct/union
* #820/50 - Handle typedefs linkage.
*/
public class SymbolTypeStruct implements SymbolType { public class SymbolTypeStruct implements SymbolType {
/** Name of the struct/union type. */ /** Name of the struct/union type. */
@ -27,12 +31,15 @@ public class SymbolTypeStruct implements SymbolType {
/** Const type qualifier. */ /** Const type qualifier. */
private final boolean isNomodify; private final boolean isNomodify;
private String typeDefName;
public SymbolTypeStruct(String structName, boolean isUnion, int sizeBytes, boolean isVolatile, boolean isNomodify) { public SymbolTypeStruct(String structName, boolean isUnion, int sizeBytes, boolean isVolatile, boolean isNomodify) {
this.structName = structName; this.structName = structName;
this.isUnion = isUnion; this.isUnion = isUnion;
this.sizeBytes = sizeBytes; this.sizeBytes = sizeBytes;
this.isVolatile = isVolatile; this.isVolatile = isVolatile;
this.isNomodify = isNomodify; this.isNomodify = isNomodify;
this.typeDefName = null;
} }
public SymbolTypeStruct(StructDefinition structDefinition, boolean isVolatile, boolean isNomodify) { public SymbolTypeStruct(StructDefinition structDefinition, boolean isVolatile, boolean isNomodify) {
@ -41,14 +48,34 @@ public class SymbolTypeStruct implements SymbolType {
this.sizeBytes = calculateSizeBytes(structDefinition, null); this.sizeBytes = calculateSizeBytes(structDefinition, null);
this.isVolatile = isVolatile; this.isVolatile = isVolatile;
this.isNomodify = isNomodify; this.isNomodify = isNomodify;
this.typeDefName = null;
} }
@Override @Override
public SymbolType getQualified(boolean isVolatile, boolean isNomodify) { public SymbolType getQualified(boolean isVolatile, boolean isNomodify) {
return new SymbolTypeStruct(this.structName, isUnion, this.sizeBytes, isVolatile, isNomodify); SymbolTypeStruct typeStruct = new SymbolTypeStruct(this.structName, isUnion, this.sizeBytes, isVolatile, isNomodify);
typeStruct.typeDefName = this.typeDefName;
return typeStruct;
} }
public boolean isUnion() { public String getTypeDefName() {
return this.typeDefName;
}
public void setTypeDefName(String typeDefName) {
this.typeDefName = typeDefName;
}
public String getStructName() {
if(typeDefName != null) {
return typeDefName;
} else {
return structName;
}
}
public boolean isUnion() {
return isUnion; return isUnion;
} }
@ -146,12 +173,16 @@ public class SymbolTypeStruct implements SymbolType {
cdecl.append("volatile "); cdecl.append("volatile ");
if(isNomodify()) if(isNomodify())
cdecl.append("const "); cdecl.append("const ");
if(isUnion) { if(getTypeDefName() == null) {
cdecl.append("union "); if (isUnion) {
} else { cdecl.append("union ");
cdecl.append("struct "); } else {
cdecl.append("struct ");
}
cdecl.append(this.getStructName());
} else {
cdecl.append(this.getStructName());
} }
cdecl.append(this.getStructTypeName());
if(parentCDecl.length()>0) if(parentCDecl.length()>0)
cdecl.append(" "); cdecl.append(" ");
cdecl.append(parentCDecl); cdecl.append(parentCDecl);
@ -161,9 +192,9 @@ public class SymbolTypeStruct implements SymbolType {
@Override @Override
public String getConstantFriendlyName() { public String getConstantFriendlyName() {
if(isUnion) { if(isUnion) {
return "UNION_"+structName.toUpperCase(Locale.ENGLISH); return "UNION_"+getStructName().toUpperCase(Locale.ENGLISH);
} else { } else {
return "STRUCT_"+structName.toUpperCase(Locale.ENGLISH); return "STRUCT_"+getStructName().toUpperCase(Locale.ENGLISH);
} }
} }
} }

View File

@ -375,6 +375,9 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
if(!program.hasAsmImportLibrary(asmLibraryName)) { if(!program.hasAsmImportLibrary(asmLibraryName)) {
program.setAsmLibraryName(asmLibraryName); program.setAsmLibraryName(asmLibraryName);
program.addAsmExportLibrary(asmLibraryName, exportAll); program.addAsmExportLibrary(asmLibraryName, exportAll);
// The scope of the program needs to have a reference to the name of the .asm library.
// For use in AsmFormat!
program.getScope().setAsmLibraryName(asmLibraryName);
} }
} }
} }
@ -387,7 +390,10 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
Procedure.CallingConvention callingConvention = currentCallingConvention; Procedure.CallingConvention callingConvention = currentCallingConvention;
List<String> procedures = pragmaParamAsmExportProcedures(ctx.pragmaParam()); List<String> procedures = pragmaParamAsmExportProcedures(ctx.pragmaParam());
AsmExportLibrary asmExportLibrary = program.addAsmExportLibrary(asmExportLibraryName, false); AsmExportLibrary asmExportLibrary = program.addAsmExportLibrary(asmExportLibraryName, false);
program.addAsmExportProcedures(asmExportLibrary, callingConvention, procedures); program.addAsmExportProcedures(asmExportLibrary, currentCallingConvention, procedures);
// TODO: #820/2 - Ensure that an export can be done with a calling convention tagged.
// Versus the current currentCallingConvention implementation.
//program.addAsmExportProcedures(asmExportLibrary, Procedure.CallingConvention.VAR_CALL, procedures);
} }
} }
case CParser.PRAGMA_ASM_IMPORT -> { // Defines that an asm routine or capability library is imported into the program. case CParser.PRAGMA_ASM_IMPORT -> { // Defines that an asm routine or capability library is imported into the program.
@ -2559,6 +2565,32 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
String typedefName = varDecl.getVarName(); String typedefName = varDecl.getVarName();
VariableBuilder varBuilder = new VariableBuilder(typedefName, getCurrentScope(), false, false, varDecl.getEffectiveType(), varDecl.getDeclDirectives(), currentSegmentData, program.getTargetPlatform().getVariableBuilderConfig()); VariableBuilder varBuilder = new VariableBuilder(typedefName, getCurrentScope(), false, false, varDecl.getEffectiveType(), varDecl.getDeclDirectives(), currentSegmentData, program.getTargetPlatform().getVariableBuilderConfig());
varBuilder.build(); varBuilder.build();
if(typedefName != null) {
// #820/50 - Define the name of structures, based on the typedef name, if any.
// For structures, the generation of CDecl has a hidden and conceptual problem ...
// Structures with an empty name get the structure name $n allocated by the compiler.
// And this name can vary depending on the structure declaration order etc.
// Also, the structure name struct $0 etc is not C syntax compatible.
// So, in order to avoid conflicts, we use the typedef name if given.
// We could also have given the struct name the typedef name appended with _s,
// but that idea seemed to be way too complicated to implement.
// Because the generated struct definition name $n gets assigned during parsing
// before the typedef name is parsed.
// It is complicated to replace the structure definition name once it is defined and allocated.
// So the idea is that the typedef name gets stored as part of the structure type definition,
// and used in CDecl when needed.
if(varDecl.declType instanceof SymbolTypeStruct) {
ProgramScope programScope = program.getScope();
StructDefinition structDef = ((SymbolTypeStruct) varDecl.declType).getStructDefinition(programScope);
if(structDef.getLocalName().startsWith("$")) {
varDecl.declType.setTypeDefName(typedefName);
//StructDefinition structDefinition = ((SymbolTypeStruct) varDecl.declType).replaceStructDefinition(programScope, typedefName);
StructDefinition structDefinition = ((SymbolTypeStruct) varDecl.declType).getStructDefinition(programScope);
structDefinition.setTypeDefStruct((SymbolTypeStruct) varDecl.declType);
//((SymbolTypeStruct) varDecl.declType).setStructName(typedefName);
}
}
}
scopeStack.pop(); scopeStack.pop();
varDecl.exitType(); varDecl.exitType();
return null; return null;

View File

@ -102,6 +102,8 @@ public class Pass1ExtractInlineStrings extends Pass1Base {
final long stringLength = constantString.getStringLength(); final long stringLength = constantString.getStringLength();
final ConstantInteger arraySize = new ConstantInteger(stringLength, stringLength<256?SymbolType.BYTE : SymbolType.WORD); final ConstantInteger arraySize = new ConstantInteger(stringLength, stringLength<256?SymbolType.BYTE : SymbolType.WORD);
Variable strConst = Variable.createConstant(name, new SymbolTypePointer(SymbolType.BYTE, new ArraySpec(arraySize), false, false), blockScope, constantString, blockScope.getSegmentData()); Variable strConst = Variable.createConstant(name, new SymbolTypePointer(SymbolType.BYTE, new ArraySpec(arraySize), false, false), blockScope, constantString, blockScope.getSegmentData());
// #820 - Set the library for string constant pointers.
strConst.setAsmExportLibrary(getProgram().getAsmLibraryName());
blockScope.add(strConst); blockScope.add(strConst);
if(getLog().isVerbosePass1CreateSsa()) { if(getLog().isVerbosePass1CreateSsa()) {
getLog().append("Creating constant string variable for inline " + strConst.toString(getProgram()) + " \"" + constantString.getValue() + "\""); getLog().append("Creating constant string variable for inline " + strConst.toString(getProgram()) + " \"" + constantString.getValue() + "\"");

View File

@ -47,8 +47,12 @@ public class Pass1StructTypeSizeFix extends Pass2SsaOptimization {
// Update all SIZEOF_XXX constants // Update all SIZEOF_XXX constants
for(Scope subScope : getProgramScope().getAllScopes(false)) { for(Scope subScope : getProgramScope().getAllScopes(false)) {
if(subScope instanceof StructDefinition) { // #820/50 - Ensure that the structure definitions within the scope are used.
SymbolTypeStruct typeStruct = new SymbolTypeStruct((StructDefinition) subScope, false, false); if(subScope instanceof StructDefinition structDef) {
SymbolTypeStruct typeStruct = structDef.getTypeDefStruct();
if(typeStruct == null) {
typeStruct = new SymbolTypeStruct((StructDefinition) subScope, false, false);
}
StructDefinition structDefinition = typeStruct.getStructDefinition(getProgramScope()); StructDefinition structDefinition = typeStruct.getStructDefinition(getProgramScope());
int sizeBytes = typeStruct.calculateSizeBytes(structDefinition, getProgramScope()); int sizeBytes = typeStruct.calculateSizeBytes(structDefinition, getProgramScope());
if(sizeBytes != typeStruct.getSizeBytes()) { if(sizeBytes != typeStruct.getSizeBytes()) {

View File

@ -103,9 +103,9 @@ public class Pass4CodeGeneration {
String asmLibraryName = program.getAsmLibraryName(); String asmLibraryName = program.getAsmLibraryName();
ScopeRef currentScope = ScopeRef.ROOT; ScopeRef currentScope = ScopeRef.ROOT;
asm.startChunk(currentScope, null, null);
// 820/25 - #import .asm libraries only once! // 820/25 - #import .asm libraries only once!
asm.startChunk(currentScope, null, null);
asm.addImportOnce(); asm.addImportOnce();
// Add file level comments // Add file level comments
@ -115,7 +115,7 @@ public class Pass4CodeGeneration {
// #820/24 - Create a namespace if the output of the compile is an .asm library instead of a program. // #820/24 - Create a namespace if the output of the compile is an .asm library instead of a program.
if (program.getAsmLibraryName() != null) { if (program.getAsmLibraryName() != null) {
asm.startChunk(currentScope, null, "Library"); asm.startChunk(currentScope, null, "Library");
asm.addNamespaceBegin(program.getAsmLibraryLabel()); asm.addNamespaceBegin(program);
} }
asm.startChunk(currentScope, null, "Upstart"); asm.startChunk(currentScope, null, "Upstart");
@ -238,26 +238,22 @@ public class Pass4CodeGeneration {
generateScopeEnding(asm, currentScope); generateScopeEnding(asm, currentScope);
} }
currentScope = ScopeRef.ROOT; if (program.getAsmLibraryName() == null) {
asm.startChunk(currentScope, null, "File Data Internal or Ignore"); asm.startChunk(ScopeRef.ROOT, null, "File Data Internal or Ignore");
addData(asm, ScopeRef.ROOT, null);
addData(asm, ScopeRef.ROOT, null); addAbsoluteAddressData(asm, ScopeRef.ROOT, null);
addAbsoluteAddressData(asm, ScopeRef.ROOT, null); } else {
// #820/34 - Export the global data, but when the compilation is an .asm export library.
// #820/24 - Close the namespace of the asm library. asm.startChunk(ScopeRef.ROOT, null, "Exported Global Data");
if (program.getAsmLibraryName() != null) {
asm.addNamespaceEnd();
}
// #820/34 - Export the global data, but when the compilation is an .asm export library.
if (program.getAsmLibraryName() != null) {
asm.startChunk(currentScope, null, "Exported Global Data");
// Add the global data elements for the ROOT scope of the .asm library. // Add the global data elements for the ROOT scope of the .asm library.
addData(asm, ScopeRef.ROOT, program.getAsmLibraryName()); addData(asm, ScopeRef.ROOT, program.getAsmLibraryName());
addAbsoluteAddressData(asm, ScopeRef.ROOT, program.getAsmLibraryName()); addAbsoluteAddressData(asm, ScopeRef.ROOT, program.getAsmLibraryName());
// #820/24 - Close the namespace of the asm library.
asm.addNamespaceEnd(program);
} }
generateImportAsmLibraries(asm, program); // #820/25 - .asm library #import stub code. // #820/25 - .asm library #import stub code.
generateImportAsmLibraries(asm, program);
program.setAsm(asm); program.setAsm(asm);
} }
@ -298,7 +294,7 @@ public class Pass4CodeGeneration {
if (asm.hasStash()) asm.startChunk(currentScope, null, "Outside Flow"); if (asm.hasStash()) asm.startChunk(currentScope, null, "Outside Flow");
// Generate all stashed ASM lines // Generate all stashed ASM lines
asm.addStash(); asm.addStash();
addData(asm, currentScope, null); addData(asm, currentScope, program.getAsmLibraryName());
asm.addScopeEnd(); asm.addScopeEnd();
} }
} }
@ -405,16 +401,16 @@ public class Pass4CodeGeneration {
if(varExportAsmLibrary != null) { if(varExportAsmLibrary != null) {
return varExportAsmLibrary.equals(exportAsmLibrary); return varExportAsmLibrary.equals(exportAsmLibrary);
} else { } else {
return false; return true; // Bugfix
} }
} else { } else {
boolean isImportAsmLibraryGlobal = constantVar.isAsmImportLibraryGlobal(); boolean isImportAsmLibraryGlobal = constantVar.isAsmImportLibraryGlobal();
boolean isExportAsmLibraryParameter = constantVar.isAsmExportLibraryParameter(); boolean isExportAsmLibraryParameter = constantVar.isAsmExportLibraryParameter();
boolean isExportAsmLibraryReturn = constantVar.isAsmExportLibraryReturn(); boolean isExportAsmLibraryReturn = constantVar.isAsmExportLibraryReturn();
return ( varExportAsmLibrary == null || isExportAsmLibraryParameter || isExportAsmLibraryReturn ) return ( varExportAsmLibrary == null || isExportAsmLibraryParameter || isExportAsmLibraryReturn )
&& !isImportAsmLibraryGlobal; && !isImportAsmLibraryGlobal;
}
} }
}
private boolean hasData(Variable constantVar) { private boolean hasData(Variable constantVar) {
ConstantValue constantValue = constantVar.getInitValue(); ConstantValue constantValue = constantVar.getInitValue();
@ -504,22 +500,22 @@ public class Pass4CodeGeneration {
String asmExportLibraryName = program.getAsmLibraryName(); String asmExportLibraryName = program.getAsmLibraryName();
if(var.isStruct()) { if(var.isStruct()) {
String typeVar = "SIZEOF_" + var.getType().getConstantFriendlyName(); // String typeVar = "SIZEOF_" + var.getType().getConstantFriendlyName();
// First add all constants without data that can become constants in KickAsm // // First add all constants without data that can become constants in KickAsm
for (Variable constantVar : scopeConstants) { // for (Variable constantVar : scopeConstants) {
if (!hasData(constantVar)) { // if (!hasData(constantVar)) {
String asmName = constantVar.getAsmName() == null ? constantVar.getLocalName() : constantVar.getAsmName(); // String asmName = constantVar.getAsmName() == null ? constantVar.getLocalName() : constantVar.getAsmName();
if (asmName != null && !added.contains(asmName)) { // if (asmName != null && !added.contains(asmName)) {
if (constantVar.getLocalName().equals(typeVar)) { // if (constantVar.getLocalName().equals(typeVar)) {
// Use constant otherwise // // Use constant otherwise
added.add(asmName); // added.add(asmName);
// Find the constant value calculation // // Find the constant value calculation
String asmConstant = AsmFormat.getAsmConstant(program, constantVar.getInitValue(), 99, scopeRef); // String asmConstant = AsmFormat.getAsmConstant(program, constantVar.getInitValue(), 99, scopeRef);
addConstant(asmName, constantVar, asmConstant, asm); // addConstant(asmName, constantVar, asmConstant, asm);
} // }
} // }
} // }
} // }
} }
} }
@ -546,6 +542,7 @@ public class Pass4CodeGeneration {
if (!useLabelForConst(scopeRef, constantVar)) { if (!useLabelForConst(scopeRef, constantVar)) {
// Use constant for constant integers not referenced outside scope // Use constant for constant integers not referenced outside scope
added.add(asmName); added.add(asmName);
program.getAsmLibraryNamespaceSymbols().put(asmName, constantVar);
// Find the constant value calculation // Find the constant value calculation
String asmConstant = AsmFormat.getAsmConstant(program, constantVar.getInitValue(), 99, scopeRef); String asmConstant = AsmFormat.getAsmConstant(program, constantVar.getInitValue(), 99, scopeRef);
addConstant(asmName, constantVar, asmConstant, asm); addConstant(asmName, constantVar, asmConstant, asm);
@ -553,9 +550,12 @@ public class Pass4CodeGeneration {
} else if (!(constantVar.getType() instanceof SymbolTypePointer)) { } else if (!(constantVar.getType() instanceof SymbolTypePointer)) {
// Use constant otherwise // Use constant otherwise
added.add(asmName); added.add(asmName);
program.getAsmLibraryNamespaceSymbols().put(asmName, constantVar);
// Find the constant value calculation // Find the constant value calculation
String asmConstant = AsmFormat.getAsmConstant(program, constantVar.getInitValue(), 99, scopeRef); String asmConstant = AsmFormat.getAsmConstant(program, constantVar.getInitValue(), 99, scopeRef);
addConstant(asmName, constantVar, asmConstant, asm); // constantVar.setAsmExportLibrary(exportAsmLibrary);
addConstantLabelDecl(asmName, constantVar, asmConstant, asm);
// addConstant(asmName, constantVar, asmConstant, asm);
} }
} }
} }
@ -569,6 +569,7 @@ public class Pass4CodeGeneration {
if (constantVar.getType() instanceof SymbolTypePointer) { if (constantVar.getType() instanceof SymbolTypePointer) {
// Must use a label for pointers // Must use a label for pointers
added.add(asmName); added.add(asmName);
program.getAsmLibraryNamespaceSymbols().put(asmName, constantVar);
String asmConstant = AsmFormat.getAsmConstant(program, constantVar.getInitValue(), 99, scopeRef); String asmConstant = AsmFormat.getAsmConstant(program, constantVar.getInitValue(), 99, scopeRef);
addConstantLabelDecl(asmName, constantVar, asmConstant, asm); addConstantLabelDecl(asmName, constantVar, asmConstant, asm);
} else if (isIntTypeInScope(constantVar)) { } else if (isIntTypeInScope(constantVar)) {
@ -576,6 +577,7 @@ public class Pass4CodeGeneration {
if (useLabelForConst(scopeRef, constantVar)) { if (useLabelForConst(scopeRef, constantVar)) {
// Use label for integers referenced in other scope - to allow cross-scope referencing // Use label for integers referenced in other scope - to allow cross-scope referencing
added.add(asmName); added.add(asmName);
program.getAsmLibraryNamespaceSymbols().put(asmName, constantVar);
// Add any comments // Add any comments
String asmConstant = AsmFormat.getAsmConstant(program, constantVar.getInitValue(), 99, scopeRef); String asmConstant = AsmFormat.getAsmConstant(program, constantVar.getInitValue(), 99, scopeRef);
addConstantLabelDecl(asmName, constantVar, asmConstant, asm); addConstantLabelDecl(asmName, constantVar, asmConstant, asm);
@ -595,12 +597,14 @@ public class Pass4CodeGeneration {
String asmName = scopeVar.getAsmName(); String asmName = scopeVar.getAsmName();
if (asmName != null && !added.contains(asmName)) { if (asmName != null && !added.contains(asmName)) {
added.add(asmName); added.add(asmName);
program.getAsmLibraryNamespaceSymbols().put(asmName, scopeVar);
addConstantLabelDecl(asmName, scopeVar, AsmFormat.getAsmNumber(registerZp.getZp()), asm); addConstantLabelDecl(asmName, scopeVar, AsmFormat.getAsmNumber(registerZp.getZp()), asm);
} }
} else if (Registers.RegisterType.MAIN_MEM.equals(register.getType()) && ((Registers.RegisterMainMem) register).getAddress() != null) { } else if (Registers.RegisterType.MAIN_MEM.equals(register.getType()) && ((Registers.RegisterMainMem) register).getAddress() != null) {
String asmName = scopeVar.getAsmName(); String asmName = scopeVar.getAsmName();
if (asmName != null && !added.contains(asmName)) { if (asmName != null && !added.contains(asmName)) {
added.add(asmName); added.add(asmName);
program.getAsmLibraryNamespaceSymbols().put(asmName, scopeVar);
// Add the label declaration // Add the label declaration
Long address = ((Registers.RegisterMainMem) register).getAddress(); Long address = ((Registers.RegisterMainMem) register).getAddress();
addConstantLabelDecl(asmName, scopeVar, AsmFormat.getAsmNumber(address), asm); addConstantLabelDecl(asmName, scopeVar, AsmFormat.getAsmNumber(address), asm);

View File

@ -20,7 +20,7 @@
#define __STDIO_FILECOUNT 4 #define __STDIO_FILECOUNT 4
#endif #endif
typedef struct file_handle_s { typedef struct {
char filename[__STDIO_FILECOUNT*__STDIO_FILELEN]; char filename[__STDIO_FILECOUNT*__STDIO_FILELEN];
char channel[__STDIO_FILECOUNT]; char channel[__STDIO_FILECOUNT];
char device[__STDIO_FILECOUNT]; char device[__STDIO_FILECOUNT];

View File

@ -26,7 +26,7 @@
#define CONIO_TEXTCOLOR_DEFAULT WHITE // The default text color #define CONIO_TEXTCOLOR_DEFAULT WHITE // The default text color
#define CONIO_BACKCOLOR_DEFAULT BLUE // The default back color #define CONIO_BACKCOLOR_DEFAULT BLUE // The default back color
typedef struct __cx16_conio_s { typedef struct {
unsigned char cursor_x; ///< current cursor x-position unsigned char cursor_x; ///< current cursor x-position
unsigned char cursor_y; ///< current cursor y-position unsigned char cursor_y; ///< current cursor y-position
unsigned char layer; unsigned char layer;

View File

@ -1,50 +0,0 @@
/* Testing an export library flight_lib.asm file generation.
The result of this compile should result in:
- A new flight_lib.asm file created in the compiler output directory.
- A new flight_lib_asm.h file created in the compiler output directory.
*/
#pragma encoding(screencode_mixed)
#pragma var_model(zp)
// Register the compilation as an calc.asm export library output artefact.
// There is no main() function!
#pragma asm_library
// Register the exported procedures that should be included in the calc.asm export library.
#pragma calling(__stackcall)
#pragma asm_export(flight_init)
#pragma calling(__varcall)
#pragma asm_export(flight_route, flight_distance)
#pragma calling(__phicall)
struct flight {
char flightno;
char direction;
char distance;
unsigned int x, y;
};
struct flight flights[8];
void flight_init(char flightno) {
flights[flightno].x = 0x8000;
flights[flightno].y = 0x8000;
}
void flight_route(char flightno, char direction) {
flights[flightno].direction = direction;
}
void flight_distance(char flightno, unsigned int distance) {
flights[flightno].distance = distance;
}
void flight_display() {
}
void flight_calculate() {
}

View File

@ -1,15 +0,0 @@
/* Here we use the flight_lib.asm library functions.
*/
#pragma encoding(screencode_mixed)
#pragma var_model(zp)
// We include the flight_lib_asm.h generated C function prototype file.
// This file contains the C function prototypes for import and usage.
#include "flight_lib_asm.h"
void main() {
flight_init(2);
flight_route(2, 10);
flight_distance(2, 0X2000);
}

View File

@ -1,48 +0,0 @@
/* Testing an export library flight_lib.asm file generation.
The result of this compile should result in:
- A new flight_lib.asm file created in the compiler output directory.
- A new flight_lib_asm.h file created in the compiler output directory.
*/
#pragma encoding(screencode_mixed)
#pragma var_model(zp)
// Register the compilation as an calc.asm export library output artefact.
// There is no main() function!
#pragma asm_library
#pragma calling(__phicall)
struct flight {
char flightno;
char direction;
char distance;
unsigned int x, y;
};
struct flight flights[8];
// Now with __asm_export directive!
void __stackcall __asm_export flight_init(char flightno) {
flights[flightno].x = 0x8000;
flights[flightno].y = 0x8000;
}
// Now with __asm_export directive!
void __varcall __asm_export flight_route(char flightno, char direction) {
flights[flightno].direction = direction;
}
// Now with __asm_export directive!
void __varcall __asm_export flight_distance(char flightno, unsigned int distance) {
flights[flightno].distance = distance;
}
void flight_display() {
}
void flight_calculate() {
}

View File

@ -1,15 +0,0 @@
/* Here we use the flight_lib.asm library functions.
*/
#pragma encoding(screencode_mixed)
#pragma var_model(zp)
// We include the flight_lib_asm.h generated C function prototype file.
// This file contains the C function prototypes for import and usage.
#include "flight_lib_asm.h"
void main() {
flight_init(2);
flight_route(2, 10);
flight_distance(2, 0X2000);
}

View File

@ -1,49 +0,0 @@
/* Testing an export library flight_lib.asm file generation.
The result of this compile should result in:
- A new flight_lib.asm file created in the compiler output directory.
- A new flight_lib_asm.h file created in the compiler output directory.
*/
#pragma encoding(screencode_mixed)
#pragma var_model(zp)
// Register the compilation as an calc.asm export library output artefact.
// There is no main() function!
#pragma asm_library
#pragma calling(__phicall)
#pragma asm_export(flight_init, flight_route, flight_distance)
struct flight {
char flightno;
char direction;
char distance;
unsigned int x, y;
};
struct flight flights[8];
// Now with __asm_export directive!
void __stackcall flight_init(char flightno) {
flights[flightno].x = 0x8000;
flights[flightno].y = 0x8000;
}
// Now with __asm_export directive!
void __varcall flight_route(char flightno, char direction) {
flights[flightno].direction = direction;
}
// Now with __asm_export directive!
void __varcall flight_distance(char flightno, unsigned int distance) {
flights[flightno].distance = distance;
}
void flight_display() {
}
void flight_calculate() {
}

View File

@ -1,15 +0,0 @@
/* Here we use the flight_lib.asm library functions.
*/
#pragma encoding(screencode_mixed)
#pragma var_model(zp)
// We include the flight_lib_asm.h generated C function prototype file.
// This file contains the C function prototypes for import and usage.
#include "flight_lib_asm.h"
void main() {
flight_init(2);
flight_route(2, 10);
flight_distance(2, 0X2000);
}

View File

@ -1,3 +1,5 @@
/* Generate a library for printing. */
#pragma encoding(screencode_mixed) #pragma encoding(screencode_mixed)
#pragma var_model(mem) #pragma var_model(mem)
#pragma struct_model(classic) // This is important or kickc messes up the parameters ... #pragma struct_model(classic) // This is important or kickc messes up the parameters ...
@ -23,7 +25,7 @@
#pragma calling(__stackcall) #pragma calling(__stackcall)
#pragma asm_export(cputc) #pragma asm_export(cputc)
#pragma calling(__varcall) #pragma calling(__phicall)
#include <conio.h> #include <conio.h>
#include <printf.h> #include <printf.h>

View File

@ -1,6 +1,5 @@
#pragma encoding(screencode_mixed) #pragma encoding(screencode_mixed)
#pragma struct_model(classic) // This is important or kickc messes up the parameters ... #pragma struct_model(classic) // This is important or kickc messes up the parameters ...
#pragma zp_reserve($0..$1f)
#include "printf_lib_asm.h" #include "printf_lib_asm.h"
@ -24,4 +23,4 @@ void main() {
printf("signed char = %hhi to %hhi\n", (signed char)-((1<<7)), (signed char)((1<<7)-1)); printf("signed char = %hhi to %hhi\n", (signed char)-((1<<7)), (signed char)((1<<7)-1));
printf("pointer address = %p to %p\n", (char*)0, (char*)0xFFFF); printf("pointer address = %p to %p\n", (char*)0, (char*)0xFFFF);
printf("hexadecimal char = %03x\n", char_test); printf("hexadecimal char = %03x\n", char_test);
} }

View File

@ -0,0 +1,22 @@
/*
Generate a calculation library that can add and subtract 2 chars.
- Both plus and min are exported functions within the .asm library.
- Validate the resulting calc_lib.asm and calc_lib_asm.h files.
*/
#pragma encoding(screencode_mixed)
#pragma var_model(zp)
#pragma asm_library
#pragma calling(__varcall)
#pragma asm_export(plus, min)
#pragma calling(__phicall)
char plus(char a, char b) {
return a+b;
}
char min(char a, char b) {
return a-b;
}

View File

@ -0,0 +1,19 @@
/* Use the calculation library.
Compile first calc_lib.c.
Validate the .asm library calc_lib.asm.
Validate the main program using the functions of calc_lib.asm.
Notice the function calls into the calc_lib .namespace of calc_lib.asm.
*/
#pragma encoding(screencode_mixed)
#pragma var_model(zp)
#include "calc_lib_asm.h"
__export char r;
void main() {
r = 10;
r = plus(5,4);
r = min(5,4);
}

View File

@ -1,15 +0,0 @@
#pragma encoding(screencode_mixed)
#pragma var_model(zp)
#pragma asm_library
#pragma calling(__varcall)
#pragma asm_export(plus, min)
char plus(char a, char b) {
return a+b;
}
char min(char a, char b) {
return a-b;
}

View File

@ -1,12 +0,0 @@
#pragma encoding(screencode_mixed)
#pragma var_model(zp)
#include "calc_asm.h"
__export char r; // Ensure that r does not get deleted by the optimizer by exporting it.
void main() {
r = 10;
r = plus(5,4);
r = min(5,4);
}

View File

@ -0,0 +1,29 @@
#pragma encoding(screencode_mixed)
#pragma var_model(local_zp)
#pragma asm_library
#pragma calling(__varcall)
#pragma var_model(zp)
__export const char CONST1 = 20;
__export const char CONST2 = 40;
__export const char CONST3 = 60;
__export volatile char global1a;
__export volatile int global2a;
__export volatile long global3a;
__export volatile char* global4a;
__export volatile int* global5a;
__export volatile long global6a;
__export volatile char global1b[256];
__export volatile int global2b[256];
__export volatile long global3b[256];
__export volatile char global1c[3] = {1,2,3};
__export volatile char global2c[3] = {CONST1, CONST2, CONST3};
__export volatile char global1d[3] = {&global1a, &global2a, &global3a};
__export volatile char global2d[3] = {(char*)0x4000, (char*)0x5000, (char*)0x6000};
//__export char* global3d[3] = {"test1", "test2", "test3"};

View File

@ -1,16 +1,11 @@
#pragma encoding(screencode_mixed) #pragma encoding(screencode_mixed)
#pragma var_model(zp) #pragma var_model(zp)
struct printf_buffer_number;
#include <calc_asm.h> #include <global_lib_asm.h>
__export char r = 5; // Ensure that r does not get deleted by the optimizer by exporting it. __export char r = 5; // Ensure that r does not get deleted by the optimizer by exporting it.
void main() { void main() {
asm {sei} r = global1d[1];
clrscr();
r = 10;
r = plus(r, 2);
r = plus(r, 4);
asm {cli}
} }

View File

@ -0,0 +1,20 @@
#pragma encoding(screencode_mixed)
#pragma var_model(zp)
#include "struct_lib_types.h"
#include <struct_lib_asm.h>
#include <print_lib_asm.h>
#include <stdio.h>
void main() {
clrscr();
struct data data1 = {1,2,3};
struct data data2 = {10,20,30};
printf("x = %u\n", get_f1(&data1));
printf("y = %u\n", get_f2(&data2));
}

View File

@ -0,0 +1,19 @@
#pragma encoding(screencode_mixed)
#pragma var_model(local_zp)
#pragma asm_library
#pragma calling(__varcall)
#pragma asm_export(get_f1, get_f2)
#pragma calling(__phicall)
#include "struct_lib_types.h"
char get_f1(struct data* d) {
return d->f1;
}
char get_f2(struct data* d) {
return d->f2;
}

View File

@ -0,0 +1,4 @@
#include "struct_lib_types.h"
char get_f1(struct data* d);
char get_f2(struct data* d);

View File

@ -0,0 +1,5 @@
struct data {
char f1;
char f2;
char f3;
};

View File

@ -0,0 +1,25 @@
#pragma encoding(screencode_mixed)
#pragma var_model(zp)
#include "typedef_lib_types.h"
#include <typedef_lib_asm.h>
#include <print_lib_asm.h>
#include <stdio.h>
void main() {
clrscr();
fdata_t data1 = {1,2,3};
fdata_t data2 = {10,20,30};
printf("f1, data1 = %u\n", get_f1(&data1));
printf("f2, data2 = %u\n", get_f2(&data2));
printf("f1, data2 = %u\n", get_f1(&data2));
printf("f2, data1 = %u\n", get_f2(&data1));
// TODO ...
// printf("f1, data2 = %u\n", get_f1(&data));
// printf("f2, data1 = %u\n", get_f2(&data));
}

View File

@ -0,0 +1,22 @@
#pragma encoding(screencode_mixed)
#pragma var_model(local_zp)
#pragma asm_library
#pragma calling(__varcall)
#pragma var_model(zp)
#include "typedef_lib_types.h"
__export fdata_t data = {'a','b','c'};
char get_f1(fdata_t* f) {
return f->f1;
}
char get_f2(fdata_t* f) {
return f->f2;
}

View File

@ -0,0 +1,4 @@
#include "typedef_lib_types.h"
char get_f1(fdata_t* f);
char get_f2(fdata_t* f);

View File

@ -0,0 +1,13 @@
typedef struct {
char f1;
char f2;
char f3;
} fdata_t;
typedef unsigned char uint8;
typedef unsigned int uint16;
typedef signed char sint8;
typedef signed int sint16;
typedef unsigned long uint32;
typedef signed long sint32;

View File

@ -0,0 +1,16 @@
#pragma encoding(screencode_mixed)
#pragma var_model(zp)
#include "typedef_lib_types.h"
#include <typedef_lib_asm.h>
#include <print_lib_asm.h>
#include <stdio.h>
void main() {
clrscr();
printf("get(1) = %s", get(1));
}

View File

@ -0,0 +1,29 @@
#pragma encoding(screencode_mixed)
#pragma var_model(zp)
#pragma asm_library
#pragma calling(__stackcall)
#pragma asm_export(clrscr)
#pragma asm_export(gotoxy)
#pragma asm_export(wherex, wherey)
#pragma asm_export(screensize, screensizex, screensizey, cputln )
#pragma asm_export(cputcxy, cputs, cputsxy, textcolor, bgcolor, bordercolor )
#pragma asm_export(kbhit, cursor, scroll )
#pragma asm_export(screenlayer1, screenlayer2)
#pragma asm_export(cpeekc, cpeekcxy)
#pragma calling(__stackcall)
#pragma asm_export(printf_str)
#pragma asm_export(printf_uint, printf_sint)
#pragma asm_export(printf_ulong, printf_slong)
#pragma asm_export(printf_uchar, printf_schar)
#pragma calling(__stackcall)
#pragma asm_export(cputc)
#pragma calling(__phicall)
#include <conio.h>
#include <printf.h>

View File

@ -0,0 +1,12 @@
#pragma encoding(screencode_mixed)
#pragma asm_library
#pragma calling(__varcall)
#pragma asm_export(get)
#include "typedef_lib.h"
char* get(char n) {
return soa.text[n];
}

View File

@ -0,0 +1,5 @@
#include "typedef_lib_types.h"
__export soa_t soa = {
{ "test", "test2" }
};

View File

@ -0,0 +1,4 @@
typedef struct {
char *text[2];
} soa_t;

View File

@ -0,0 +1,42 @@
/*
Generate a calculation library that:
- Add and subtract 2 chars, using the functions plus and min.
These functions are exported and are called through zero-page.
The compiler automatically compiles exported functions using the __varcall
calling convention.
- Multiply a char by 2, through the multiply function.
The multiply function is internally to the library, and therefore,
will be optimized following the current calling convention.
Internal functions following the __phicall calling convention,
when compiled with uplift, the parameters to this function will be
uplifted to A, X or Y registers, including local variables etc.
- Validate the resulting calc_lib.asm and calc_lib_asm.h files.
*/
#pragma encoding(screencode_mixed)
#pragma var_model(zp)
#pragma asm_library
#pragma calling(__varcall)
#pragma asm_export(plus, min)
#pragma calling(__phicall)
// Compiled using __varcall calling convention.
char plus(char a, char b) {
char d = multiply(a);
return a + b + d;
}
// Compiled using __varcall calling convention.
char min(char a, char b) {
return a - b;
}
// Compiled using __phicall calling convention.
char multiply(char d) {
return d * 2;
}

View File

@ -1,7 +1,7 @@
#pragma encoding(screencode_mixed) #pragma encoding(screencode_mixed)
#pragma var_model(zp) #pragma var_model(zp)
#include "calc_asm.h" #include "calc_lib_asm.h"
#include <stdio.h> #include <stdio.h>
#include <printf.h> #include <printf.h>

View File

@ -1,22 +0,0 @@
#pragma encoding(screencode_mixed)
#pragma var_model(zp)
#pragma asm_library
#pragma var_model(local_mem)
#pragma calling(__varcall)
#pragma asm_export(plus, min)
char internal(char d) {
return d * 2;
}
char plus(char a, char b) {
char d = internal(a);
return a + b + d;
}
char min(char a, char b) {
return a - b;
}

View File

@ -0,0 +1,43 @@
/*
Generate a calculation library that:
- Defines an exported library function plus_min to do some calculation.
This function parameters are allocated on zero-page, following the __varcall
calling convention.
- Define two internal functions plus and min.
These functions are internally to the library, and therefore,
will be optimized following the current calling convention.
Internal functions following the __phicall calling convention,
when compiled with uplift, the parameters to this function will be
uplifted to A, X or Y registers, including local variables etc.
- Validate the resulting calc_lib.asm and calc_lib_asm.h files.
*/
#pragma encoding(screencode_mixed)
#pragma var_model(zp)
#pragma asm_library
#pragma calling(__varcall)
#pragma asm_export(plus_min)
#pragma calling(__phicall)
// Compiled using __varcall calling convention.
char plus_min(char a, char p, char m) {
char pr = plus(a,p);
char mr = min(pr,m);
return mr;
}
// Compiled using __phicall calling convention.
char plus(char a, char b) {
return a+b;
}
// Compiled using __phicall calling convention.
char min(char a, char b) {
return a-b;
}

View File

@ -1,7 +1,7 @@
#pragma encoding(screencode_mixed) #pragma encoding(screencode_mixed)
#pragma var_model(zp) #pragma var_model(zp)
#include "calc_asm.h" #include "calc_lib_asm.h"
__export char r; __export char r;

View File

@ -1,19 +0,0 @@
#pragma encoding(screencode_mixed)
#pragma var_model(zp)
#pragma asm_library
#pragma asm_export(plus_min)
char plus(char a, char b) {
return a+b;
}
char min(char a, char b) {
return a-b;
}
char plus_min(char a, char p, char m) {
char pr = plus(a,p);
char mr = min(pr,m);
return mr;
}

View File

@ -0,0 +1,38 @@
/*
Generate a calculation library that is implemented through main memory allocation:
- Defines an exported library function plus_min to do some calculation.
This function parameters are allocated on main memory, following the __varcall
calling convention.
- Define two internal functions plus and min.
These functions are internally to the library, and therefore,
will be optimized following the current calling convention.
Internal functions following the __phicall calling convention,
when compiled with uplift, the parameters to this function will be
uplifted to A, X or Y registers, including local variables etc.
- Validate the resulting calc_lib.asm and calc_lib_asm.h files.
*/
#pragma encoding(screencode_mixed)
#pragma var_model(mem)
#pragma asm_library
#pragma calling(__varcall)
#pragma asm_export(plus_min)
#pragma calling(__phicall)
char plus(char a, char b) {
return a+b;
}
char min(char a, char b) {
return a-b;
}
char plus_min(char a, char p, char m) {
char pr = plus(a,p);
char mr = min(pr,m);
return mr;
}

View File

@ -1,7 +1,7 @@
#pragma encoding(screencode_mixed) #pragma encoding(screencode_mixed)
#pragma var_model(zp) #pragma var_model(zp)
#include "calc_asm.h" #include "calc_lib_asm.h"
#include <stdio.h> #include <stdio.h>
#include <printf.h> #include <printf.h>

View File

@ -1,21 +0,0 @@
#pragma encoding(screencode_mixed)
#pragma var_model(mem)
#pragma asm_library
#pragma calling(__varcall)
#pragma asm_export(plus_min)
char plus(char a, char b) {
return a+b;
}
char min(char a, char b) {
return a-b;
}
char plus_min(char a, char p, char m) {
char pr = plus(a,p);
char mr = min(pr,m);
return mr;
}

View File

@ -0,0 +1,36 @@
/*
Generate a calculation library that is implemented through zero-page allocation:
- No function is exported using #pragma asm_export, so ALL functions are
exported in the library!
- The 3 exported functions do some calculations.
The function parameters are allocated on zero-page, following the __varcall
calling convention.
- Validate the resulting calc_lib.asm and calc_lib_asm.h files.
*/
#pragma encoding(screencode_mixed)
#pragma var_model(zp)
#pragma asm_library
#pragma calling(__varcall)
#pragma asm_export(plus1, plus2, plus3)
#pragma calling(__phicall)
char plus1(char d) {
d = d + 1;
return d;
}
char plus2(char d) {
d = d + 2;
return plus1(d);
}
char plus3(char d) {
d = d + 3;
return plus2(d);
}

View File

@ -1,28 +0,0 @@
#pragma encoding(screencode_mixed)
#pragma var_model(zp)
#pragma asm_library
#pragma calling(__varcall)
char plus1(char d) {
d = d + 1;
return d;
}
char plus2(char d) {
d = d + 2;
return plus1(d);
}
char plus3(char d) {
d = d + 3;
return plus2(d);
}
// char plus4(char d) {
// return d+4;
// }
// char plus5(char d) {
// return d+5;
// }

View File

@ -2,9 +2,9 @@
#pragma var_model(zp) #pragma var_model(zp)
#pragma asm_library #pragma asm_library
#pragma calling(__varcall) #pragma calling(__varcall)
#pragma asm_export(plus, min, check) #pragma asm_export(plus, min, check)
#pragma calling(__phicall)
char plus(char a, char b) { char plus(char a, char b) {
return a+b; return a+b;

View File

@ -1,7 +1,7 @@
#pragma encoding(screencode_mixed) #pragma encoding(screencode_mixed)
#pragma var_model(zp) #pragma var_model(zp)
#include "calc_asm.h" #include "calc_lib_asm.h"
__export char r; // Ensure that r does not get deleted by the optimizer by exporting it. __export char r; // Ensure that r does not get deleted by the optimizer by exporting it.

View File

@ -1,17 +1,18 @@
#pragma encoding(screencode_mixed) #pragma encoding(screencode_mixed)
#pragma var_model(zp) #pragma var_model(zp)
#include <plus_asm.h> #include <plus_lib_asm.h>
#include <min_asm.h> #include <min_lib_asm.h>
#include <print_asm.h> #include <print_lib_asm.h>
#include <stdio.h> #include <stdio.h>
__export char r; // Ensure that r does not get deleted by the optimizer by exporting it. char r = 3;
void main() { void main() {
r = plus(r, 2); r = plus(r, 2);
r = min(r, 1); r = min(r, 1);
clrscr();
printf("r = %u", r); printf("r = %u", r);
} }

View File

@ -3,8 +3,8 @@
#pragma asm_library #pragma asm_library
#pragma calling(__varcall) #pragma calling(__varcall)
#pragma asm_export(get_x)
#pragma var_model(zp) #pragma calling(__phicall)
struct data { struct data {
char x1; char x1;

View File

@ -3,20 +3,16 @@
#pragma asm_library #pragma asm_library
#pragma calling(__varcall) #pragma calling(__varcall)
#pragma asm_export(get_y)
#pragma calling(__phicall)
#pragma var_model(zp) typedef struct {
struct data {
char y1; char y1;
char y2; char y2;
char y3; char y3;
}; } data_t;
struct data y = {128,129,130}; data_t y = {128,129,130};
// The plus functions
char get_y(char i) { char get_y(char i) {

View File

@ -1,9 +1,9 @@
#pragma encoding(screencode_mixed) #pragma encoding(screencode_mixed)
#pragma var_model(zp) #pragma var_model(zp)
#include <cx_asm.h> #include <cx_lib_asm.h>
#include <cy_asm.h> #include <cy_lib_asm.h>
#include <print_asm.h> #include <print_lib_asm.h>
#include <stdio.h> #include <stdio.h>
@ -14,5 +14,5 @@ void main() {
clrscr(); clrscr();
printf("x = %u\n", get_x(1)); printf("x = %u\n", get_x(1));
printf("y = %u\n", get_y(1)); printf("y = %u\n", get_y(2));
} }

View File

@ -0,0 +1,29 @@
#pragma encoding(screencode_mixed)
#pragma var_model(zp)
#pragma asm_library
#pragma calling(__stackcall)
#pragma asm_export(clrscr)
#pragma asm_export(gotoxy)
#pragma asm_export(wherex, wherey)
#pragma asm_export(screensize, screensizex, screensizey, cputln )
#pragma asm_export(cputcxy, cputs, cputsxy, textcolor, bgcolor, bordercolor )
#pragma asm_export(kbhit, cursor, scroll )
#pragma asm_export(screenlayer1, screenlayer2)
#pragma asm_export(cpeekc, cpeekcxy)
#pragma calling(__stackcall)
#pragma asm_export(printf_str)
#pragma asm_export(printf_uint, printf_sint)
#pragma asm_export(printf_ulong, printf_slong)
#pragma asm_export(printf_uchar, printf_schar)
#pragma calling(__stackcall)
#pragma asm_export(cputc)
#pragma calling(__phicall)
#include <conio.h>
#include <printf.h>

View File

@ -1,10 +1,10 @@
#pragma encoding(screencode_mixed) #pragma encoding(screencode_mixed)
#pragma var_model(zp) #pragma var_model(zp)
#include <print_asm.h> #include <print_lib_asm.h>
#include <plus_asm.h> #include <plus_lib_asm.h>
#include <min_asm.h> #include <min_lib_asm.h>
#include <printf.h> #include <printf.h>
@ -14,7 +14,10 @@ void main() {
clrscr(); clrscr();
r = 10; r = 10;
r = plus(r, 2); r = plus(r, 2);
r = min(r, 1);
r = plus(r, 30);
r = plus(r, 11);
r = plus(r, min(r, 40));
printf("main r = %u\n", r); printf("main r = %u\n", r);
r = min(r, 1);
} }

View File

@ -1,7 +1,7 @@
#pragma encoding(screencode_mixed) #pragma encoding(screencode_mixed)
#pragma var_model(zp) #pragma var_model(zp)
#include <print_asm.h> #include <print_lib_asm.h>
#pragma asm_library #pragma asm_library
#pragma calling(__varcall) #pragma calling(__varcall)

View File

@ -1,7 +1,7 @@
#pragma encoding(screencode_mixed) #pragma encoding(screencode_mixed)
#pragma var_model(zp) #pragma var_model(zp)
#include <print_asm.h> #include <print_lib_asm.h>
#pragma asm_library #pragma asm_library
#pragma calling(__varcall) #pragma calling(__varcall)

View File

@ -1,37 +1,29 @@
#pragma encoding(screencode_mixed) #pragma encoding(screencode_mixed)
#pragma var_model(zp) #pragma var_model(zp)
#pragma struct_model(classic)
#pragma asm_library #pragma asm_library
#pragma calling(__varcall)
#pragma calling(__stackcall)
#pragma asm_export(cputc)
#pragma calling(__varcall) #pragma calling(__varcall)
#pragma asm_export(clrscr) #pragma asm_export(clrscr)
#pragma asm_export(gotoxy) #pragma asm_export(gotoxy)
#pragma asm_export(wherex, wherey) #pragma asm_export(wherex, wherey)
#pragma asm_export(screensize, screensizex, screensizey, cputln) #pragma asm_export(screensize, screensizex, screensizey, cputln )
#pragma asm_export(cputcxy, cputs, cputsxy, textcolor, bgcolor, bordercolor) #pragma asm_export(cputcxy, cputs, cputsxy, textcolor, bgcolor, bordercolor )
#pragma asm_export(kbhit, cursor, scroll, cscroll) #pragma asm_export(kbhit, cursor, scroll )
#pragma asm_export(screenlayer1, screenlayer2) #pragma asm_export(screenlayer1, screenlayer2)
#pragma asm_export(cpeekc, cpeekcxy) #pragma asm_export(cpeekc, cpeekcxy)
#pragma asm_export(plus)
#pragma calling(__varcall)
#pragma asm_export(printf_str)
#pragma asm_export(printf_uint, printf_sint)
#pragma asm_export(printf_ulong, printf_slong)
#pragma asm_export(printf_uchar, printf_schar)
#pragma calling(__stackcall)
#pragma asm_export(cputc)
#pragma calling(__phicall) #pragma calling(__phicall)
#include <conio.h> #include <conio.h>
#include <stdlib.h>
#include <printf.h> #include <printf.h>
__export char color = 10;
char plus(char a, char p) {
char r = a + p;
color = r;
printf("color = %02u\n", r);
return r;
}