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. */
|
/** 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) {
|
||||||
|
@ -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();
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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));
|
||||||
|
Loading…
Reference in New Issue
Block a user