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:
parent
8b441f6814
commit
d0a9d81abf
@ -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) {
|
||||
|
@ -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();
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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 {
|
||||
} 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));
|
||||
|
Loading…
Reference in New Issue
Block a user