1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-06-02 00:41:42 +00:00

Merge branch 'fix-inline-function-asm-code-blocks-using-constants' into 'master'

Draft: #628 - Inline functions now can contain asm fragments.

See merge request camelot/kickc!28
This commit is contained in:
Sven Van de Velde 2024-01-30 07:45:10 +00:00
commit 37a9788a10

View File

@ -947,11 +947,47 @@ public class Pass4CodeGeneration {
}
}
}
/* author: sven.van.de.velde@telenet.be - 2023-03-21
The following logic ensures that inlined asm{} blocks placed in inline functions()
are replacing the used C constants or variables with the inlined version
of these C constants or variables.
During pass1, in the functions inlineStatement() and execute() in the Pass1ProcedureInline.c,
the asm fragment gets scanned for referenced constants or variables and the
referenced constant names get updated with the modified inlined referenced constant names.
These modified reference names are then used here in the asm generation, to scan the asm fragment,
of which the source is the bare, parsed antlr source, and really directly in the cut/pasted source
search for any constant or variable in operand1 and replace with the inlined reference
constant or variable name using the Operand1 structure.
This is the only pragmatic way I saw possible.
However, this section gets called during coalescing many, many times and
slows the compiler. However, such solution requires a complete redesign and cannot
just be put in scope to add this fix. So I hope that this change is acceptable.
*/
for (AsmLine asmLine : currentChunk.getLines()) {
if (asmLine instanceof AsmInstruction) {
AsmInstruction asmInstruction = (AsmInstruction) asmLine;
Map<String, SymbolRef> referenced = statementAsm.getReferenced();
for(String reference : referenced.keySet()) {
String operand = asmInstruction.getOperand1();
if(operand != null) {
String replace = referenced.get(reference).getLocalName();
if(operand.startsWith(replace)) {
} else {
if(operand.contains(reference)) {
operand = operand.replaceAll(reference, replace);
asmInstruction.setOperand1(operand);
}
}
}
}
}
}
} else if (statement instanceof StatementKickAsm) {
StatementKickAsm statementKasm = (StatementKickAsm) statement;
addKickAsm(asm, statementKasm);
AsmChunk currentChunk = asm.getCurrentChunk();
if (statementKasm.getDeclaredClobber() != null) {
asm.getCurrentChunk().setClobberOverwrite(statementKasm.getDeclaredClobber());
currentChunk.setClobberOverwrite(statementKasm.getDeclaredClobber());
}
} else if (statement instanceof StatementCallPointer) {
throw new InternalError("Statement not supported " + statement);