1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-02-06 13:31:05 +00:00

Centralized and optimized ASM name fixing.

This commit is contained in:
jespergravgaard 2019-08-25 13:35:30 +02:00
parent 87268abc2a
commit 26e96d085a
5 changed files with 57 additions and 38 deletions

View File

@ -271,22 +271,40 @@ public class AsmFormat {
*/
static String getAsmParamName(ScopeRef varScopeRef, String asmName, ScopeRef codeScopeRef) {
if(!varScopeRef.equals(codeScopeRef) && varScopeRef.getFullName().length() > 0) {
String param = varScopeRef.getFullName() + "." + asmName
.replace('@', 'b')
.replace(':', '_')
.replace("#", "_")
.replace("$", "_");
return param;
return asmFix(varScopeRef.getFullName() + "." + asmName);
} else {
String param = asmName
.replace('@', 'b')
.replace(':', '_')
.replace("#", "_")
.replace("$", "_");
return param;
return asmFix(asmName);
}
}
/**
* Fix characters in an ASM parameter/label name. Handles '@:$#'
* @param source The source string
* @return The fixed string
*/
public static String asmFix(String source) {
StringBuilder result = new StringBuilder();
char[] sourceChars = source.toCharArray();
for(char sourceChar : sourceChars) {
char resultChar;
switch(sourceChar) {
case '@':
resultChar = 'b';
break;
case ':':
case '#':
case '$':
resultChar = '_';
break;
default:
resultChar = sourceChar;
}
result.append(resultChar);
}
return result.toString();
}
/**
* Get the ASM parameter for a specific bound variable
*

View File

@ -95,7 +95,7 @@ public class AsmFragmentInstance {
boolean constantValueZp = SymbolType.BYTE.equals(boundConst.getType(program.getScope()));
return new AsmParameter(constantValueAsm, constantValueZp);
} else if(boundValue instanceof Label) {
String param = ((Label) boundValue).getLocalName().replace('@', 'b').replace(':', '_').replace("$", "_");
String param = AsmFormat.asmFix(((Label) boundValue).getLocalName());
return new AsmParameter(param, false);
} else {
throw new RuntimeException("Bound Value Type not implemented " + boundValue);

View File

@ -203,9 +203,9 @@ public class AsmFragmentInstanceSpecFactory {
String destinationLabel;
if(destinationBlock.hasPhiBlock()) {
destinationLabel =
(destinationBlock.getLabel().getLocalName() +
AsmFormat.asmFix(destinationBlock.getLabel().getLocalName() +
"_from_" +
block.getLabel().getLocalName()).replace('@', 'b').replace(':', '_');
block.getLabel().getLocalName());
} else {
destinationLabel = destination.getLocalName();
}

View File

@ -147,7 +147,7 @@ public class Pass4CodeGeneration {
generateSignatureComments(asm, procedure);
}
// Start the new scope
asm.addScopeBegin(block.getLabel().getFullName().replace('@', 'b').replace(':', '_'));
asm.addScopeBegin(AsmFormat.asmFix(block.getLabel().getFullName()));
// Add all ZP labels for the scope
addConstants(asm, currentScope);
addZpLabels(asm, currentScope);
@ -166,7 +166,7 @@ public class Pass4CodeGeneration {
} else {
// Generate label for block inside procedure
asm.startChunk(currentScope, null, block.getLabel().getFullName());
asm.addLabel(block.getLabel().getLocalName().replace('@', 'b').replace(':', '_'));
asm.addLabel(AsmFormat.asmFix(block.getLabel().getLocalName()));
}
// Generate statements
genStatements(asm, block);
@ -177,14 +177,14 @@ public class Pass4CodeGeneration {
PhiTransitions.PhiTransition transition = getTransitions(defaultSuccessor).getTransition(block);
if(!transitionIsGenerated(transition)) {
genBlockPhiTransition(asm, block, defaultSuccessor, defaultSuccessor.getScope());
String label = defaultSuccessor.getLabel().getLocalName().replace('@', 'b').replace(':', '_');
String label = AsmFormat.asmFix(defaultSuccessor.getLabel().getLocalName());
asm.addInstruction("JMP", AsmAddressingMode.ABS, label, false);
} else {
String label = (defaultSuccessor.getLabel().getLocalName() + "_from_" + block.getLabel().getLocalName()).replace('@', 'b').replace(':', '_');
String label = AsmFormat.asmFix(defaultSuccessor.getLabel().getLocalName() + "_from_" + block.getLabel().getLocalName());
asm.addInstruction("JMP", AsmAddressingMode.ABS, label, false);
}
} else {
String label = defaultSuccessor.getLabel().getLocalName().replace('@', 'b').replace(':', '_');
String label = AsmFormat.asmFix(defaultSuccessor.getLabel().getLocalName());
asm.addInstruction("JMP", AsmAddressingMode.ABS, label, false);
}
}
@ -334,19 +334,19 @@ public class Pass4CodeGeneration {
String asmConstant = AsmFormat.getAsmConstant(program, constantVar.getValue(), 99, scopeRef);
if(constantVar.getType() instanceof SymbolTypePointer) {
// Must use a label for pointers
asm.addLabelDecl(asmName.replace("#", "_").replace("$", "_"), asmConstant);
asm.addLabelDecl(AsmFormat.asmFix(asmName), asmConstant);
} else if(SymbolType.isInteger(constantVar.getType()) && constantVar.getRef().getScopeDepth() > 0) {
// Use label for integers referenced in other scope - to allow cross-scope referencing
if(useLabelForConst(scopeRef, constantVar)) {
// Use label for integers referenced in other scope - to allow cross-scope referencing
asm.addLabelDecl(asmName.replace("#", "_").replace("$", "_"), asmConstant);
asm.addLabelDecl(AsmFormat.asmFix(asmName), asmConstant);
} else {
// Use constant for constant integers not referenced outside scope
asm.addConstant(asmName.replace("#", "_").replace("$", "_"), asmConstant);
asm.addConstant(AsmFormat.asmFix(asmName), asmConstant);
}
} else {
// Use constant otherwise
asm.addConstant(asmName.replace("#", "_").replace("$", "_"), asmConstant);
asm.addConstant(AsmFormat.asmFix(asmName), asmConstant);
}
}
}
@ -510,36 +510,36 @@ public class Pass4CodeGeneration {
int size = ((ConstantInteger) arraySizeConst).getInteger().intValue();
if(SymbolType.BYTE.equals(constantArrayFilled.getElementType())) {
String asmSize = AsmFormat.getAsmConstant(program, arraySize, 99, scopeRef);
asm.addDataFilled(asmName.replace("#", "_").replace("$", "_"), AsmDataNumeric.Type.BYTE, asmSize, size, "0");
asm.addDataFilled(AsmFormat.asmFix(asmName), AsmDataNumeric.Type.BYTE, asmSize, size, "0");
added.add(asmName);
} else if(SymbolType.SBYTE.equals(constantArrayFilled.getElementType())) {
String asmSize = AsmFormat.getAsmConstant(program, arraySize, 99, scopeRef);
asm.addDataFilled(asmName.replace("#", "_").replace("$", "_"), AsmDataNumeric.Type.BYTE, asmSize, size, "0");
asm.addDataFilled(AsmFormat.asmFix(asmName), AsmDataNumeric.Type.BYTE, asmSize, size, "0");
added.add(asmName);
} else if(SymbolType.WORD.equals(constantArrayFilled.getElementType())) {
String asmSize = AsmFormat.getAsmConstant(program, new ConstantBinary(new ConstantInteger(2L), Operators.MULTIPLY, arraySize), 99, scopeRef);
asm.addDataFilled(asmName.replace("#", "_").replace("$", "_"), AsmDataNumeric.Type.WORD, asmSize, size, "0");
asm.addDataFilled(AsmFormat.asmFix(asmName), AsmDataNumeric.Type.WORD, asmSize, size, "0");
added.add(asmName);
} else if(SymbolType.SWORD.equals(constantArrayFilled.getElementType())) {
String asmSize = AsmFormat.getAsmConstant(program, new ConstantBinary(new ConstantInteger(2L), Operators.MULTIPLY, arraySize), 99, scopeRef);
asm.addDataFilled(asmName.replace("#", "_").replace("$", "_"), AsmDataNumeric.Type.WORD, asmSize, size, "0");
asm.addDataFilled(AsmFormat.asmFix(asmName), AsmDataNumeric.Type.WORD, asmSize, size, "0");
added.add(asmName);
} else if(SymbolType.DWORD.equals(constantArrayFilled.getElementType())) {
String asmSize = AsmFormat.getAsmConstant(program, new ConstantBinary(new ConstantInteger(4L), Operators.MULTIPLY, arraySize), 99, scopeRef);
asm.addDataFilled(asmName.replace("#", "_").replace("$", "_"), AsmDataNumeric.Type.DWORD, asmSize, size, "0");
asm.addDataFilled(AsmFormat.asmFix(asmName), AsmDataNumeric.Type.DWORD, asmSize, size, "0");
added.add(asmName);
} else if(SymbolType.SDWORD.equals(constantArrayFilled.getElementType())) {
String asmSize = AsmFormat.getAsmConstant(program, new ConstantBinary(new ConstantInteger(4L), Operators.MULTIPLY, arraySize), 99, scopeRef);
asm.addDataFilled(asmName.replace("#", "_").replace("$", "_"), AsmDataNumeric.Type.DWORD, asmSize, size, "0");
asm.addDataFilled(AsmFormat.asmFix(asmName), AsmDataNumeric.Type.DWORD, asmSize, size, "0");
added.add(asmName);
} else if(constantArrayFilled.getElementType() instanceof SymbolTypePointer) {
String asmSize = AsmFormat.getAsmConstant(program, new ConstantBinary(new ConstantInteger(2L), Operators.MULTIPLY, arraySize), 99, scopeRef);
asm.addDataFilled(asmName.replace("#", "_").replace("$", "_"), AsmDataNumeric.Type.WORD, asmSize, size, "0");
asm.addDataFilled(AsmFormat.asmFix(asmName), AsmDataNumeric.Type.WORD, asmSize, size, "0");
added.add(asmName);
} else if(constantArrayFilled.getElementType() instanceof SymbolTypeStruct) {
SymbolTypeStruct structElementType = (SymbolTypeStruct) constantArrayFilled.getElementType();
String asmSize = AsmFormat.getAsmConstant(program, new ConstantBinary(new ConstantInteger((long) structElementType.getSizeBytes()), Operators.MULTIPLY, arraySize), 99, scopeRef);
asm.addDataFilled(asmName.replace("#", "_").replace("$", "_"), AsmDataNumeric.Type.WORD, asmSize, size, "0");
asm.addDataFilled(AsmFormat.asmFix(asmName), AsmDataNumeric.Type.WORD, asmSize, size, "0");
added.add(asmName);
} else {
throw new InternalError("Unhandled constant array element type " + constantArrayFilled.toString(program));
@ -559,7 +559,7 @@ public class Pass4CodeGeneration {
}
}
}
asm.addDataKickAsm(asmName.replace("#", "_").replace("$", "_"), bytes, kickAsm.getKickAsmCode());
asm.addDataKickAsm(AsmFormat.asmFix(asmName), bytes, kickAsm.getKickAsmCode());
} else {
try {
ConstantLiteral literal = constantValue.calculateLiteral(getScope());
@ -567,7 +567,7 @@ public class Pass4CodeGeneration {
// Ensure encoding is good
ensureEncoding(asm, constantValue);
String asmConstant = AsmFormat.getAsmConstant(program, constantValue, 99, scopeRef);
asm.addDataString(asmName.replace("#", "_").replace("$", "_"), asmConstant);
asm.addDataString(AsmFormat.asmFix(asmName), asmConstant);
if(((ConstantString) literal).isZeroTerminated()) {
asm.addDataNumeric(null, AsmDataNumeric.Type.BYTE, Collections.singletonList(AsmFormat.getAsmNumber(0L)));
}
@ -628,7 +628,7 @@ public class Pass4CodeGeneration {
// Add any comments
generateComments(asm, scopeVar.getComments());
// Add the label declaration
asm.addLabelDecl(asmName.replace("#", "_").replace("$", "_"), registerZp.getZp());
asm.addLabelDecl(AsmFormat.asmFix(asmName), registerZp.getZp());
added.add(asmName);
}
}
@ -949,7 +949,7 @@ public class Pass4CodeGeneration {
PhiTransitions.PhiTransition transition = transitions.getTransition(fromBlock);
if(!transitionIsGenerated(transition) && toBlock.getLabel().equals(fromBlock.getConditionalSuccessor())) {
genBlockPhiTransition(asm, fromBlock, toBlock, toBlock.getScope());
asm.addInstruction("JMP", AsmAddressingMode.ABS, toBlock.getLabel().getLocalName().replace('@', 'b').replace(':', '_'), false);
asm.addInstruction("JMP", AsmAddressingMode.ABS, AsmFormat.asmFix(toBlock.getLabel().getLocalName()), false);
}
}
}
@ -980,7 +980,7 @@ public class Pass4CodeGeneration {
asm.startChunk(scope, toFirstStatement.getIndex(), chunkSrc);
asm.getCurrentChunk().setPhiTransitionId(transition.getTransitionId());
for(ControlFlowBlock fBlock : transition.getFromBlocks()) {
asm.addLabel((toBlock.getLabel().getLocalName() + "_from_" + fBlock.getLabel().getLocalName()).replace('@', 'b').replace(':', '_'));
asm.addLabel(AsmFormat.asmFix(toBlock.getLabel().getLocalName() + "_from_" + fBlock.getLabel().getLocalName()));
}
List<PhiTransitions.PhiTransition.PhiAssignment> assignments = transition.getAssignments();
for(PhiTransitions.PhiTransition.PhiAssignment assignment : assignments) {

View File

@ -1,6 +1,7 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.asm.*;
import dk.camelot64.kickc.fragment.AsmFormat;
import dk.camelot64.kickc.model.CompileError;
import dk.camelot64.kickc.model.Program;
import kickass.KickAssembler;
@ -145,7 +146,7 @@ public class Pass5FixLongBranches extends Pass5AsmOptimization {
getLog().append("Fixing long branch [" + idx + "] " + asmLine.toString() + " to " + inverseType.getMnemnonic());
String branchDest = asmInstruction.getParameter();
asmInstruction.setType(inverseType);
String newLabel = ("!" + branchDest).replace("$","_");
String newLabel = AsmFormat.asmFix("!" + branchDest);
asmInstruction.setParameter(newLabel+"+");
AsmInstructionType jmpType = AsmInstructionSet.getInstructionType("jmp", AsmAddressingMode.ABS, false);
AsmInstruction jmpInstruction = new AsmInstruction(jmpType, branchDest);