1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-11-27 19:50:10 +00:00

Moved filled arrays to addDataChunk()

This commit is contained in:
jespergravgaard 2019-09-13 11:56:05 +02:00
parent 8b441f6814
commit d0a9d81abf
4 changed files with 62 additions and 75 deletions

View File

@ -44,21 +44,21 @@ public class AsmDataChunk {
/** A number of identical numerical data elements. */ /** A number of identical numerical data elements. */
public static class AsmDataFilledElement implements AsmDataElement { public static class AsmDataFilledElement implements AsmDataElement {
/** The ASM specifying how the total size in bytes - in ASM-format. */
String totalSizeBytesAsm;
/** The type of the element */ /** The type of the element */
AsmDataNumeric.Type type; AsmDataNumeric.Type type;
/** The ASM specifying how many elements to fill. */
String sizeAsm;
/** The literal integer number of elements. */ /** The literal integer number of elements. */
int size; int numElements;
/** The fill value. */ /** The fill value. */
String fillValue; String fillValue;
/** The string encoding used in any char/string value */ /** The string encoding used in any char/string value */
Set<ConstantString.Encoding> encoding; Set<ConstantString.Encoding> encoding;
AsmDataFilledElement(AsmDataNumeric.Type type, String sizeAsm, int size, String fillValue, Set<ConstantString.Encoding> encoding) { AsmDataFilledElement(AsmDataNumeric.Type type, String totalSizeBytesAsm, int numElements, String fillValue, Set<ConstantString.Encoding> encoding) {
this.type = type; this.type = type;
this.sizeAsm = sizeAsm; this.totalSizeBytesAsm = totalSizeBytesAsm;
this.size = size; this.numElements = numElements;
this.fillValue = fillValue; this.fillValue = fillValue;
this.encoding = encoding; this.encoding = encoding;
} }
@ -67,12 +67,12 @@ public class AsmDataChunk {
return type; return type;
} }
String getSizeAsm() { String getTotalSizeBytesAsm() {
return sizeAsm; return totalSizeBytesAsm;
} }
public int getSize() { public int getNumElements() {
return size; return numElements;
} }
String getFillValue() { String getFillValue() {
@ -116,8 +116,8 @@ public class AsmDataChunk {
elements.add(new AsmDataNumericElement(type, value, encoding)); elements.add(new AsmDataNumericElement(type, value, encoding));
} }
public void addDataFilled(AsmDataNumeric.Type type, String sizeAsm, int size, String fillValue, Set<ConstantString.Encoding> encoding) { public void addDataFilled(AsmDataNumeric.Type type, String totalSizeBytesAsm, int numElements, String fillValue, Set<ConstantString.Encoding> encoding) {
elements.add(new AsmDataFilledElement(type, sizeAsm, size, fillValue, encoding)); elements.add(new AsmDataFilledElement(type, totalSizeBytesAsm, numElements, fillValue, encoding));
} }
public void addDataString(String string, Set<ConstantString.Encoding> encoding) { public void addDataString(String string, Set<ConstantString.Encoding> encoding) {
@ -148,7 +148,7 @@ public class AsmDataChunk {
} }
AsmDataFilledElement filledElement = (AsmDataFilledElement) element; AsmDataFilledElement filledElement = (AsmDataFilledElement) element;
asm.ensureEncoding(filledElement.getEncoding()); asm.ensureEncoding(filledElement.getEncoding());
asm.addDataFilled(label, filledElement.getType(), filledElement.getSizeAsm(), filledElement.getSize(), filledElement.getFillValue()); asm.addDataFilled(label, filledElement.getType(), filledElement.getTotalSizeBytesAsm(), filledElement.getNumElements(), filledElement.getFillValue());
label = null; // Only output label once label = null; // Only output label once
} else if(element instanceof AsmDataStringElement) { } else if(element instanceof AsmDataStringElement) {
if(currentNumericElements!=null && currentNumericElements.size() > 0) { if(currentNumericElements!=null && currentNumericElements.size() > 0) {

View File

@ -4,18 +4,23 @@ package dk.camelot64.kickc.asm;
public class AsmDataFill implements AsmLine { public class AsmDataFill implements AsmLine {
private String label; private String label;
/** The calculation of the total number of bytes in ASM-format */
private String totalByteSizeAsm;
/** The type of value being filled with. */
private AsmDataNumeric.Type type; private AsmDataNumeric.Type type;
private String sizeAsm; /** The number of elements*/
private int size; private int numElements;
/** The value to fill with in ASM-format */
private String fillValue; private String fillValue;
private int index; private int index;
public AsmDataFill(String label, AsmDataNumeric.Type type, String sizeAsm, int size, String fillValue) { public AsmDataFill(String label, AsmDataNumeric.Type type, String totalByteSizeAsm, int numElements, String fillValue) {
this.label = label; this.label = label;
this.type = type; this.type = type;
this.sizeAsm = sizeAsm; this.totalByteSizeAsm = totalByteSizeAsm;
this.size = size; this.numElements = numElements;
this.fillValue = fillValue; this.fillValue = fillValue;
} }
@ -25,7 +30,7 @@ public class AsmDataFill implements AsmLine {
@Override @Override
public int getLineBytes() { public int getLineBytes() {
return size * getElementBytes(); return numElements * getElementBytes();
} }
@Override @Override
@ -40,7 +45,7 @@ public class AsmDataFill implements AsmLine {
asm.append(label + ": "); asm.append(label + ": ");
} }
asm.append(".fill "); asm.append(".fill ");
asm.append(sizeAsm); asm.append(totalByteSizeAsm);
asm.append(", "); asm.append(", ");
asm.append(fillValue); asm.append(fillValue);
return asm.toString(); return asm.toString();

View File

@ -139,10 +139,10 @@ public class AsmProgram {
* *
* @param label The label of the data * @param label The label of the data
* @param type The type of the data * @param type The type of the data
* @param size The size of data to fill * @param numElements The size of data to fill
*/ */
public void addDataFilled(String label, AsmDataNumeric.Type type, String sizeAsm, int size, String fillValue) { public void addDataFilled(String label, AsmDataNumeric.Type type, String totalSizeBytesAsm, int numElements, String fillValue) {
addLine(new AsmDataFill(label, type, sizeAsm, size, fillValue)); addLine(new AsmDataFill(label, type, totalSizeBytesAsm, numElements, fillValue));
} }
/** /**

View File

@ -456,51 +456,9 @@ public class Pass4CodeGeneration {
addChunkData(asmDataChunk, constantValue, constantVar.getType(), scopeRef); addChunkData(asmDataChunk, constantValue, constantVar.getType(), scopeRef);
asmDataChunk.addToAsm(asmName, asm); asmDataChunk.addToAsm(asmName, asm);
} else if(constantValue instanceof ConstantArrayFilled) { } else if(constantValue instanceof ConstantArrayFilled) {
ConstantArrayFilled constantArrayFilled = (ConstantArrayFilled) constantValue; AsmDataChunk asmDataChunk = new AsmDataChunk();
ConstantValue arraySize = constantArrayFilled.getSize(); addChunkData(asmDataChunk, constantValue, constantVar.getType(), scopeRef);
// ensure encoding is good asmDataChunk.addToAsm(asmName, asm);
ensureEncoding(asm, arraySize);
ConstantLiteral arraySizeConst = arraySize.calculateLiteral(getScope());
if(!(arraySizeConst instanceof ConstantInteger)) {
throw new Pass2SsaAssertion.AssertionFailed("Error! Array size is not constant integer " + constantVar.toString(program));
}
int size = ((ConstantInteger) arraySizeConst).getInteger().intValue();
if(SymbolType.BYTE.equals(constantArrayFilled.getElementType())) {
String asmSize = AsmFormat.getAsmConstant(program, arraySize, 99, scopeRef);
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(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(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(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(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(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(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(AsmFormat.asmFix(asmName), AsmDataNumeric.Type.WORD, asmSize, size, "0");
added.add(asmName);
} else {
throw new InternalError("Unhandled constant array element type " + constantArrayFilled.toString(program));
}
} else if(constantValue instanceof ConstantArrayKickAsm) { } else if(constantValue instanceof ConstantArrayKickAsm) {
ConstantArrayKickAsm kickAsm = (ConstantArrayKickAsm) constantValue; ConstantArrayKickAsm kickAsm = (ConstantArrayKickAsm) constantValue;
SymbolType type = constantVar.getType(); SymbolType type = constantVar.getType();
@ -602,8 +560,31 @@ public class Pass4CodeGeneration {
SymbolType elementType = constTypeArray.getElementType(); SymbolType elementType = constTypeArray.getElementType();
SymbolType dataType = value.getType(program.getScope()); SymbolType dataType = value.getType(program.getScope());
int dataSize = 0; int dataNumElements = 0;
if(dataType.equals(SymbolType.STRING)) { if(value instanceof ConstantArrayFilled) {
ConstantArrayFilled constantArrayFilled = (ConstantArrayFilled) value;
ConstantValue arraySize = constantArrayFilled.getSize();
ConstantLiteral arraySizeConst = arraySize.calculateLiteral(getScope());
if(!(arraySizeConst instanceof ConstantInteger)) {
throw new Pass2SsaAssertion.AssertionFailed("Error! Array size is not constant integer " + arraySize.toString(program));
}
dataNumElements = ((ConstantInteger) arraySizeConst).getInteger().intValue();
int elementSizeBytes = elementType.getSizeBytes();
String totalSizeBytesAsm;
if(elementSizeBytes>1) {
totalSizeBytesAsm = AsmFormat.getAsmConstant(program, new ConstantBinary(new ConstantInteger((long)elementSizeBytes, SymbolType.NUMBER), Operators.MULTIPLY, arraySize), 99, scopeRef);
} else {
totalSizeBytesAsm = AsmFormat.getAsmConstant(program, arraySize, 99, scopeRef);
}
if(elementType instanceof SymbolTypeIntegerFixed || elementType instanceof SymbolTypePointer) {
// Use an ASM type in the fill that matches the element type
dataChunk.addDataFilled(getNumericType(elementType), totalSizeBytesAsm, dataNumElements, "0", null);
} else {
// Complex fill type - calculate byte size and use that
int totalSizeBytes = elementSizeBytes*dataNumElements;
dataChunk.addDataFilled(AsmDataNumeric.Type.BYTE, totalSizeBytesAsm, totalSizeBytes, "0", null);
}
} else if(dataType.equals(SymbolType.STRING)) {
try { try {
ConstantLiteral literal = value.calculateLiteral(getScope()); ConstantLiteral literal = value.calculateLiteral(getScope());
if(literal instanceof ConstantString) { if(literal instanceof ConstantString) {
@ -613,23 +594,24 @@ public class Pass4CodeGeneration {
if(((ConstantString) literal).isZeroTerminated()) { if(((ConstantString) literal).isZeroTerminated()) {
dataChunk.addDataNumeric(AsmDataNumeric.Type.BYTE, "0", null); dataChunk.addDataNumeric(AsmDataNumeric.Type.BYTE, "0", null);
} }
dataSize = ((ConstantString) literal).getStringLength(); dataNumElements = ((ConstantString) literal).getStringLength();
} }
} catch(ConstantNotLiteral e) { } catch(ConstantNotLiteral e) {
// can't calculate literal value, so it is not data - just return // can't calculate literal value, so it is not data - just return
} }
} else { } else {
// Assume we have a ConstantArrayList
ConstantArrayList constantArrayList = (ConstantArrayList) value; ConstantArrayList constantArrayList = (ConstantArrayList) value;
// Output each element to the chunk // Output each element to the chunk
for(ConstantValue element : constantArrayList.getElements()) { for(ConstantValue element : constantArrayList.getElements()) {
addChunkData(dataChunk, element, elementType, scopeRef); addChunkData(dataChunk, element, elementType, scopeRef);
} }
dataSize = constantArrayList.getElements().size(); dataNumElements = constantArrayList.getElements().size();
} }
// Pad output to match declared size (if larger than the data list) // Pad output to match declared size (if larger than the data list)
Integer declaredSize = getArrayDeclaredSize(valueType); Integer declaredSize = getArrayDeclaredSize(valueType);
if(declaredSize != null && declaredSize > dataSize) { if(declaredSize != null && declaredSize > dataNumElements) {
int padding = declaredSize - dataSize; int padding = declaredSize - dataNumElements;
ConstantValue zeroValue = ZeroConstantValues.zeroValue(elementType, program.getScope()); ConstantValue zeroValue = ZeroConstantValues.zeroValue(elementType, program.getScope());
if(zeroValue instanceof ConstantInteger) { if(zeroValue instanceof ConstantInteger) {
dataChunk.addDataFilled(getNumericType(elementType), AsmFormat.getAsmNumber(padding), padding, AsmFormat.getAsmConstant(program, zeroValue, 99, scopeRef), getEncoding(zeroValue)); dataChunk.addDataFilled(getNumericType(elementType), AsmFormat.getAsmNumber(padding), padding, AsmFormat.getAsmConstant(program, zeroValue, 99, scopeRef), getEncoding(zeroValue));