1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-11-23 23:32:55 +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. */
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 */
AsmDataNumeric.Type type;
/** The ASM specifying how many elements to fill. */
String sizeAsm;
/** The literal integer number of elements. */
int size;
int numElements;
/** The fill value. */
String fillValue;
/** The string encoding used in any char/string value */
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.sizeAsm = sizeAsm;
this.size = size;
this.totalSizeBytesAsm = totalSizeBytesAsm;
this.numElements = numElements;
this.fillValue = fillValue;
this.encoding = encoding;
}
@ -67,12 +67,12 @@ public class AsmDataChunk {
return type;
}
String getSizeAsm() {
return sizeAsm;
String getTotalSizeBytesAsm() {
return totalSizeBytesAsm;
}
public int getSize() {
return size;
public int getNumElements() {
return numElements;
}
String getFillValue() {
@ -116,8 +116,8 @@ public class AsmDataChunk {
elements.add(new AsmDataNumericElement(type, value, encoding));
}
public void addDataFilled(AsmDataNumeric.Type type, String sizeAsm, int size, String fillValue, Set<ConstantString.Encoding> encoding) {
elements.add(new AsmDataFilledElement(type, sizeAsm, size, fillValue, encoding));
public void addDataFilled(AsmDataNumeric.Type type, String totalSizeBytesAsm, int numElements, String fillValue, Set<ConstantString.Encoding> encoding) {
elements.add(new AsmDataFilledElement(type, totalSizeBytesAsm, numElements, fillValue, encoding));
}
public void addDataString(String string, Set<ConstantString.Encoding> encoding) {
@ -148,7 +148,7 @@ public class AsmDataChunk {
}
AsmDataFilledElement filledElement = (AsmDataFilledElement) element;
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
} else if(element instanceof AsmDataStringElement) {
if(currentNumericElements!=null && currentNumericElements.size() > 0) {

View File

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

View File

@ -139,10 +139,10 @@ public class AsmProgram {
*
* @param label The label 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) {
addLine(new AsmDataFill(label, type, sizeAsm, size, fillValue));
public void addDataFilled(String label, AsmDataNumeric.Type type, String totalSizeBytesAsm, int numElements, String fillValue) {
addLine(new AsmDataFill(label, type, totalSizeBytesAsm, numElements, fillValue));
}
/**

View File

@ -456,51 +456,9 @@ public class Pass4CodeGeneration {
addChunkData(asmDataChunk, constantValue, constantVar.getType(), scopeRef);
asmDataChunk.addToAsm(asmName, asm);
} else if(constantValue instanceof ConstantArrayFilled) {
ConstantArrayFilled constantArrayFilled = (ConstantArrayFilled) constantValue;
ConstantValue arraySize = constantArrayFilled.getSize();
// ensure encoding is good
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));
}
AsmDataChunk asmDataChunk = new AsmDataChunk();
addChunkData(asmDataChunk, constantValue, constantVar.getType(), scopeRef);
asmDataChunk.addToAsm(asmName, asm);
} else if(constantValue instanceof ConstantArrayKickAsm) {
ConstantArrayKickAsm kickAsm = (ConstantArrayKickAsm) constantValue;
SymbolType type = constantVar.getType();
@ -602,8 +560,31 @@ public class Pass4CodeGeneration {
SymbolType elementType = constTypeArray.getElementType();
SymbolType dataType = value.getType(program.getScope());
int dataSize = 0;
if(dataType.equals(SymbolType.STRING)) {
int dataNumElements = 0;
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 {
ConstantLiteral literal = value.calculateLiteral(getScope());
if(literal instanceof ConstantString) {
@ -613,23 +594,24 @@ public class Pass4CodeGeneration {
if(((ConstantString) literal).isZeroTerminated()) {
dataChunk.addDataNumeric(AsmDataNumeric.Type.BYTE, "0", null);
}
dataSize = ((ConstantString) literal).getStringLength();
dataNumElements = ((ConstantString) literal).getStringLength();
}
} catch(ConstantNotLiteral e) {
// can't calculate literal value, so it is not data - just return
}
} else {
// Assume we have a ConstantArrayList
ConstantArrayList constantArrayList = (ConstantArrayList) value;
// Output each element to the chunk
for(ConstantValue element : constantArrayList.getElements()) {
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)
Integer declaredSize = getArrayDeclaredSize(valueType);
if(declaredSize != null && declaredSize > dataSize) {
int padding = declaredSize - dataSize;
if(declaredSize != null && declaredSize > dataNumElements) {
int padding = declaredSize - dataNumElements;
ConstantValue zeroValue = ZeroConstantValues.zeroValue(elementType, program.getScope());
if(zeroValue instanceof ConstantInteger) {
dataChunk.addDataFilled(getNumericType(elementType), AsmFormat.getAsmNumber(padding), padding, AsmFormat.getAsmConstant(program, zeroValue, 99, scopeRef), getEncoding(zeroValue));