/*
Генератор кода для языка программирования
Объектно-ориентированный продвинутый векторный транслятор
Copyright © 2021, 2024 Малик Разработчик
Это свободная программа: вы можете перераспространять ее и/или изменять
ее на условиях Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она будет полезной,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Стандартной
общественной лицензии GNU.
Вы должны были получить копию Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<https://www.gnu.org/licenses/>.
*/
package ru.malik.elaborarer.avtoo.generator;
import avt.io.*;
import avt.lang.array.*;
import avt.util.*;
import platform.independent.filesystem.*;
import platform.independent.streamformat.*;
import ru.malik.elaborarer.avtoo.compiler.StringArray;
import ru.malik.elaborarer.avtoo.lang.*;
public class AssemblerSourceGenerator(CodeGenerator, AVTOOConstants, AVTOORecompilable, AVTOOService)
{
/*<fold флаги формирования сигнатуры типа>*/
protected static final int NORM = AssemblerElementWriter.NORM;
protected static final int WEAK = AssemblerElementWriter.WEAK;
protected static final int STACK = AssemblerElementWriter.STACK;
/*</fold>*/
/*<fold длина буфера для копирования ресурсов>*/
protected static final int COPY_BUFFER_LENGTH = 0x8000;
/*</fold>*/
protected static boolean isTypeCastAvailable(int kindBaseOfSrc, int lengthOfSrc, int kindBaseOfNew, int lengthOfNew) {
return
(kindBaseOfSrc != kindBaseOfNew || lengthOfSrc != lengthOfNew) &&
(lengthOfSrc > 1 || lengthOfNew > 1 || (kindBaseOfSrc != BYTE || kindBaseOfNew != SHORT && kindBaseOfNew != INT) && (kindBaseOfSrc != SHORT || kindBaseOfNew != INT))
;
}
protected static int getNeedRegisterTypeKind(Node node) {
if(node != null) do switch(node.instruction)
{
default:
return 0;
case SWAP:
case THROW:
case REF_EQ:
case REF_NE:
case INSTANCEOF:
case REF_IS_NULL:
case REF_IS_OBJECT:
case NEW_ARRAY_MULTI:
return REF;
case BRANCH:
case NEW_ARRAY_MONO:
return INT;
case DUP1:
case DUP2:
case DUP1X1:
case DUP1X2:
case TEST_EQZ:
case TEST_NEZ:
case O_BIT_OR:
case O_BIT_AND:
case O_BIT_XOR:
case O_BIT_NOT:
case O_SCAL_NEG:
case O_SCAL_MUL:
case O_SCAL_DIV:
case O_SCAL_DIVU:
case O_SCAL_REM:
case O_SCAL_REMU:
case O_SCAL_ADD:
case O_SCAL_SUB:
case O_SCAL_EQ:
case O_SCAL_NE:
case O_SCAL_GT:
case O_SCAL_GE:
case O_SCAL_LT:
case O_SCAL_LE:
case O_VECT_LUP:
case O_VECT_UUP:
case O_VECT_PCK:
case O_VECT_NEG:
case O_VECT_MUL:
case O_VECT_DIV:
case O_VECT_ADD:
case O_VECT_SUB:
case O_VECT_EQ:
case O_VECT_NE:
case O_VECT_GT:
case O_VECT_GE:
case O_VECT_LT:
case O_VECT_LE:
case O_VECT_HMUL:
case O_VECT_HMULU:
case O_VECT_SADD:
case O_VECT_SADDU:
case O_VECT_SSUB:
case O_VECT_SSUBU:
return ((Type) node.operand1).kind;
case WRITE_COMPONENT:
int kind = ((Type) node.operand1).kind;
return kind == REF ? 0 : kind;
case CAST_TO:
return ((Type) node.operand2).kind;
case WRITE_FIELD:
return ((TypedMember) node.operand1).type.kind;
case WRITE_SPECIAL:
Property property = (Property) node.operand1;
return !property.hasIndex() && property.writeMember instanceof Field ? property.type.kind : 0;
case WRITE_PROPERTY:
Property property = (Property) node.operand1;
Callable synthetic = property.writeSynthetic;
return !property.hasIndex() && (synthetic.serviceIndex & synthetic.virtualIndex) < 0 && property.writeMember instanceof Field ? property.type.kind : 0;
case NEW_VECTOR:
return ((PrimitiveType) node.operand1).vectorBaseKind;
case READ_FIELD:
return node.operand2 == null ? REF : 0;
case READ_SPECIAL:
Property property = (Property) node.operand1;
return !property.hasIndex() && property.readMember instanceof Field && node.operand2 == null ? REF : 0;
case READ_PROPERTY:
Property property = (Property) node.operand1;
Callable synthetic = property.readSynthetic;
return !property.hasIndex() && (synthetic.serviceIndex & synthetic.virtualIndex) < 0 && property.readMember instanceof Field && node.operand2 == null ? REF : 0;
case READ_COMPONENT:
return node.operand2 == null ? INT : REF;
case O_SCAL_SHL:
case O_SCAL_SHR:
case O_SCAL_SHRU:
case O_VECT_SHL:
case O_VECT_SHR:
case O_VECT_SHRU:
case READ_ELEMENT:
return node.operand2 == null ? INT : ((Type) node.operand1).kind;
case STORE_STATIC:
return node.operand2 != null ? 0 : ((Field) node.operand1).type.kind;
case STORE_LOCAL:
case DECLARE_WITH:
case DECLARE_LOCAL:
TableItem operand = node.operand2;
return operand instanceof Constant ? 0 : (operand instanceof Type ? (Type) operand : ((Local) node.operand1).type).kind;
case RETURN:
case METHOD_LEAVE:
return node.parentCode.parentCallable.type.kind;
case JUMP:
if(node == (node = node.jumpDefault)) return 0;
} while(true);
return 0;
}
protected final RealStorage fldRealStorage;
protected final DoubleStorage fldDoubleStorage;
protected final Double2Storage fldDouble2Storage;
protected final Double4Storage fldDouble4Storage;
protected final Double8Storage fldDouble8Storage;
protected final FloatStorage fldFloatStorage;
protected final Float2Storage fldFloat2Storage;
protected final Float4Storage fldFloat4Storage;
protected final Float8Storage fldFloat8Storage;
protected final Byte2Storage fldByte2Storage;
protected final Byte4Storage fldByte4Storage;
protected final Byte8Storage fldByte8Storage;
protected final Short2Storage fldShort2Storage;
protected final Short4Storage fldShort4Storage;
protected final Short8Storage fldShort8Storage;
protected final Int2Storage fldInt2Storage;
protected final Int4Storage fldInt4Storage;
protected final Int8Storage fldInt8Storage;
protected final LongStorage fldLongStorage;
protected final Long2Storage fldLong2Storage;
protected final Long4Storage fldLong4Storage;
protected final Long8Storage fldLong8Storage;
protected final StringStorage fldStringStorage;
protected final StringStorage fldDebugInfoSources;
protected final StringStorage fldDebugInfoStrings;
protected final Hashtable fldResourcesTable;
protected final StringArray fldResourcesArray;
private AssemblerElementWriter fldGlobalWriter;
private String fldOverwritten;
private final boolean fldReflect;
private final String fldDestinationName;
private final Hashtable fldSourcesTable;
private final StringArray fldSourcesArray;
public (int pointerSize, boolean reflect, String destinationName): super(pointerSize, false) {
fldRealStorage = new RealStorage();
fldDoubleStorage = new DoubleStorage();
fldDouble2Storage = new Double2Storage();
fldDouble4Storage = new Double4Storage();
fldDouble8Storage = new Double8Storage();
fldFloatStorage = new FloatStorage();
fldFloat2Storage = new Float2Storage();
fldFloat4Storage = new Float4Storage();
fldFloat8Storage = new Float8Storage();
fldByte2Storage = new Byte2Storage();
fldByte4Storage = new Byte4Storage();
fldByte8Storage = new Byte8Storage();
fldShort2Storage = new Short2Storage();
fldShort4Storage = new Short4Storage();
fldShort8Storage = new Short8Storage();
fldInt2Storage = new Int2Storage();
fldInt4Storage = new Int4Storage();
fldInt8Storage = new Int8Storage();
fldLongStorage = new LongStorage();
fldLong2Storage = new Long2Storage();
fldLong4Storage = new Long4Storage();
fldLong8Storage = new Long8Storage();
fldStringStorage = new StringStorage();
fldDebugInfoSources = new StringStorage();
fldDebugInfoStrings = new StringStorage();
fldResourcesTable = new Hashtable();
fldResourcesArray = new StringArray();
fldReflect = reflect;
fldDestinationName = destinationName;
fldSourcesTable = new Hashtable();
fldSourcesArray = new StringArray();
}
public void compile() throws IOException, CompilerException {
/* -- предыдущие стадии -- */
super.compile();
/* 8. Стадия выгрузки данных */
LibraryArray libraries = libraries;
int llength = libraries.length;
for(int lindex = 0; lindex < llength; lindex++)
{
Library library = libraries[lindex];
findSourcesIn(library);
findResourcesIn(library);
}
if(fldReflect) for(ClassTypeArray classes = classes, int tindex = classes.length; tindex-- > 0; )
{
ClassType type = classes[tindex];
if(type.isCompilable()) for(int mindex = type.length; mindex-- > 0; )
{
Member member = type[mindex];
if(!member.isStatic())
{
if(member instanceof Field)
{
((Field) member).type.makeCompilable();
continue;
}
if(member instanceof Callable)
{
Callable method = (Callable) member;
method.type.makeCompilable();
for(ArgumentArray arguments = method.arguments, int aindex = arguments.length; aindex-- > 0; ) arguments[aindex].type.makeCompilable();
}
}
}
}
byte[] buffer = new byte[COPY_BUFFER_LENGTH];
String destinationName = fldDestinationName;
destinationName = destinationName == null || destinationName.isEmpty() ? PROGRAMME_DESTINATION_PATH : (PROGRAMME_DESTINATION_PATH + ".") + destinationName;
Library project = project;
FileSystem fileSystem = project.fileSystem;
String destinationPath = fldOverwritten = prepareDestinationPath(fileSystem, project.directoryPath + destinationName);
for(StringArray array = fldSourcesArray, Hashtable table = fldSourcesTable, int length = array.length, int index = 0; index < length; index++)
{
String writerRelativePath = array[index];
String readerRelativePath = (ASSEMBLER_SOURCE_PATH + "/") + writerRelativePath;
Library library = (Library) table[writerRelativePath];
createImmediateDirectories(fileSystem, destinationPath, writerRelativePath);
ByteReader reader = library.fileSystem.openFileForRead(library.directoryPath + readerRelativePath);
try
{
ByteWriter writer = fileSystem.createFile(destinationPath + writerRelativePath);
try
{
int blength = 0;
do if((blength = reader.read(buffer)) > 0)
{
writer.write(buffer, 0, blength);
} while(blength >= COPY_BUFFER_LENGTH);
writer.flush();
} finally
{
writer.close();
}
} finally
{
reader.close();
}
}
for(StringArray array = fldResourcesArray, Hashtable table = fldResourcesTable, int length = array.length, int index = 0; index < length; index++)
{
ResourceLocation location = (ResourceLocation) table[array[index]];
String readerRelativePath = location.relativePath;
Library library = location.library;
char[] path = ("rsrc" + readerRelativePath.substring(readerRelativePath.indexOf('/'))).toCharArray();
int boundA = Array.indexOf('/', path, 0, 0);
int boundB = Array.lastIndexOf('/', path, Int.MAX_VALUE, 0);
for(int pindex = boundA; (pindex = Array.indexOf('/', path, pindex + 1, 0)) > boundA && pindex < boundB; ) path[pindex] = '.';
String writerRelativePath = location.destinationPath = new String(path);
createImmediateDirectories(fileSystem, destinationPath, writerRelativePath);
ByteReader reader = library.fileSystem.openFileForRead(library.directoryPath + readerRelativePath);
try
{
ByteWriter writer = fileSystem.createFile(destinationPath + writerRelativePath);
try
{
int blength = 0;
do if((blength = reader.read(buffer)) > 0)
{
writer.write(buffer, 0, blength);
} while(blength >= COPY_BUFFER_LENGTH);
writer.flush();
} finally
{
writer.close();
}
} finally
{
reader.close();
}
}
fileSystem.createDirectory(destinationPath + "code");
fileSystem.createDirectory(destinationPath + "data");
AssemblerSourcePrintStream output = newAssemblerSourcePrintStream();
if(output == null)
{
output = new AssemblerSourcePrintStream();
}
with((DataEncoder) output)
{
StringBuilder filePath = new StringBuilder();
for(
PackageArray packages = packages, int plength = packages.length, Package pack = plength <= 0 ? null : packages[0], Package next,
int pindex = 0; pindex < plength && (next = ++pindex >= plength ? null : packages[pindex]) == next; pack = next
)
{
String name = pack.fasmFileName;
String codePath = (new StringBuilder() + destinationPath + "code/" + name + '/').toString();
String dataPath = (new StringBuilder() + destinationPath + "data/" + name + '/').toString();
fileSystem.createDirectory(codePath.substring(0, codePath.length - 1));
fileSystem.createDirectory(dataPath.substring(0, dataPath.length - 1));
{
generatePackageData(pack, next, output);
ByteWriter writer = fileSystem.createFile(dataPath + "!package.inc");
try
{
saveToOutputStream(writer);
writer.flush();
} finally
{
writer.close();
}
clear();
}
for(int tlength = pack.length, int tindex = 0; tindex < tlength; tindex++)
{
Type type = pack[tindex];
if(type instanceof PrimitiveType)
{
generatePrimitiveData((PrimitiveType) type, output);
filePath + dataPath + type.fasmFileName + ".inc";
ByteWriter writer = fileSystem.createFile(filePath.toString());
try
{
saveToOutputStream(writer);
writer.flush();
} finally
{
writer.close();
}
clear();
filePath.clear();
continue;
}
if(type instanceof ClassType && type.isCompilable())
{
ClassType clas = (ClassType) type;
{
generateClassData(clas, output);
filePath + dataPath + type.fasmFileName + ".inc";
ByteWriter writer = fileSystem.createFile(filePath.toString());
try
{
saveToOutputStream(writer);
writer.flush();
} finally
{
writer.close();
}
clear();
filePath.clear();
}
if(!(clas instanceof ArrayType) || !clas.getSuperclassType().isArray())
{
generateClassCode(clas, output);
filePath + codePath + type.fasmFileName + ".inc";
ByteWriter writer = fileSystem.createFile(filePath.toString());
try
{
if(clas.hasNativeCallables())
{
filePath.clear();
Library library = pack.parentLibrary;
filePath + library.directoryPath + (ASSEMBLER_SOURCE_PATH + "/code/") + pack.fasmFileName + '/' + clas.fasmFileName + ".inc";
ByteReader reader = library.fileSystem.openFileForRead(filePath.toString());
try
{
int blength = 0;
do if((blength = reader.read(buffer)) > 0)
{
writer.write(buffer, 0, blength);
} while(blength >= COPY_BUFFER_LENGTH);
} finally
{
reader.close();
}
}
saveToOutputStream(writer);
writer.flush();
} finally
{
writer.close();
}
clear();
filePath.clear();
}
}
}
}
createImmediateDirectories(fileSystem, destinationPath, "const/");
{
generateConstants(output);
ByteWriter writer = fileSystem.createFile(destinationPath + "const/prog.inc");
try
{
saveToOutputStream(writer);
writer.flush();
} finally
{
writer.close();
}
clear();
}
createImmediateDirectories(fileSystem, destinationPath, "dbgi/");
{
generateDebugInfoEntries(output);
ByteWriter writer = fileSystem.createFile(destinationPath + "dbgi/entries.inc");
try
{
saveToOutputStream(writer);
writer.flush();
} finally
{
writer.close();
}
clear();
}
{
generateDebugInfoSources(output);
ByteWriter writer = fileSystem.createFile(destinationPath + "dbgi/sources.inc");
try
{
saveToOutputStream(writer);
writer.flush();
} finally
{
writer.close();
}
clear();
}
{
generateDebugInfoStrings(output);
ByteWriter writer = fileSystem.createFile(destinationPath + "dbgi/strings.inc");
try
{
saveToOutputStream(writer);
writer.flush();
} finally
{
writer.close();
}
clear();
}
{
generateProgramme(output);
ByteWriter writer = fileSystem.createFile(destinationPath + "programme.asm");
try
{
saveToOutputStream(writer);
writer.flush();
} finally
{
writer.close();
}
}
}
}
public final String overwritten { read = fldOverwritten }
public final boolean reflect { read = fldReflect }
public final String destinationName { read = fldDestinationName }
protected void afterConstruction() {
super.afterConstruction();
AssemblerElementWriter writer = newAssemblerElementWriter();
if(writer == null) writer = new AssemblerElementWriter();
fldGlobalWriter = writer;
}
protected void findResourcesIn(Library library) throws IOException {
with(library.fileSystem, library.directoryPath)
{
if(isObjectExists(operator +(TEXT_SOURCE_MAIN_PATH)))
{
findResourcesIn(library, TEXT_SOURCE_MAIN_PATH + "/");
return;
}
if(isObjectExists(operator +(TEXT_SOURCE_ALTERNATIVE_PATH)))
{
findResourcesIn(library, TEXT_SOURCE_ALTERNATIVE_PATH + "/");
}
}
}
protected void findResourcesIn(Library library, String relativePath) throws IOException {
with(fldResourcesArray, fldResourcesTable, library.fileSystem.findFirst(library.directoryPath + relativePath))
{
try
{
do
{
String name = name;
if(!".".equals(name) && !"..".equals(name))
{
if(directory)
{
findResourcesIn(library, (new StringBuilder() + relativePath + name + '/').toString());
}
else if(!isTypeSourceFileName(name))
{
String path = relativePath.substring(relativePath.indexOf('/')).replaceAll('.', '/') + name;
if(!containsKey(path)) append(path);
operator []=(path, new ResourceLocation(library, relativePath + name));
}
}
} while(findNext());
} finally
{
close();
}
}
}
protected void generatePackageData(Package pack, Package next, AssemblerSourcePrintStream output) {
AssemblerElementWriter writer = getAssemblerElementWriter();
boolean is64bits = pointerSize == BITS64;
int tcount = 0;
int tlength = pack.length;
char[] operandA = new char[0x0100];
char[] operandB = new char[0x0020];
char[] intZero = writer.set(new char[0x0020]).writeInt(0).get();
char[] longZero = writer.set(new char[0x0020]).writeLong(0).get();
CharArray[] operands = new CharArray[4];
String di = is64bits ? "dq" : "dd";
String specialCanonicalName = pack.specialCanonicalName;
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(int tindex = 0; tindex < tlength; tindex++) if(pack[tindex].isCompilable()) tcount++;
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printHeader("; <fold ");
output.print(specialCanonicalName == null || specialCanonicalName.isEmpty() ? package.getResourceString("comment.system-package") : specialCanonicalName);
output.print(" — ");
output.print(package.getResourceString("comment.data.package"));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printlnInstruction("package", pack.fasmFullName);
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = writer.set(operandA).writeInt(pack.attributes).get();
operands[1] = writer.set(operandB).writeInt(fldStringStorage.indexAcquire(pack.specialSimpleName)).get();
operands[2] = intZero;
operands[3] = intZero;
output.printlnInstruction("dd", operands, 0, 4);
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = intZero;
operands[1] = intZero;
operands[2] = intZero;
operands[3] = writer.set(operandA).writeInt(tcount).get();
output.printlnInstruction("dd", operands, 0, 4);
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = intZero;
operands[1] = intZero;
operands[2] = intZero;
operands[3] = intZero;
output.printlnInstruction("dd", operands, 0, 4);
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = intZero;
operands[1] = intZero;
operands[2] = intZero;
operands[3] = "-.this+.$type$";
output.printlnInstruction("dd", operands, 0, 4);
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = intZero;
operands[1] = intZero;
operands[2] = intZero;
operands[3] = intZero;
output.printlnInstruction("dd", operands, 0, 4);
output.printlnInstruction("dd", operands, 0, 4);
/* -------------------------------------------------------------------------------------------------------------------------------- */
if(is64bits)
{
operands[0] = longZero;
operands[1] = longZero;
operands[2] = (next == null ? writer.set(operandA).writeLong(0) : writer.set(operandA).writeString("-.this+").writeString(next.fasmFullName)).get();
operands[3] = longZero;
output.printlnInstruction("dq", operands, 0, 2);
output.printlnInstruction("dq", operands, 2, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = longZero;
operands[1] = longZero;
output.printlnInstruction("dq", operands, 0, 2);
} else
{
output.printlnInstruction("dd", operands, 0, 4);
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = intZero;
operands[1] = intZero;
operands[2] = (next == null ? writer.set(operandA).writeInt(0) : writer.set(operandA).writeString("-.this+").writeString(next.fasmFullName)).get();
operands[3] = intZero;
output.printlnInstruction("dd", operands, 0, 4);
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = longZero;
operands[1] = longZero;
output.printlnInstruction("dq", operands, 0, 2);
output.printlnInstruction("dq", operands, 0, 2);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = intZero;
operands[1] = intZero;
operands[2] = intZero;
operands[3] = "-.this+.$iend$";
output.printlnInstruction("dd", operands, 0, 4);
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = longZero;
operands[1] = longZero;
output.printlnInstruction("dq", operands, 0, 2);
output.printlnInstruction("dq", operands, 0, 2);
output.printlnInstruction("dq", operands, 0, 2);
output.printlnInstruction("dq", operands, 0, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printLabel(".$type$");
for(int tindex = 0; tindex < tlength; tindex++)
{
Type type = pack[tindex];
if(type.isCompilable())
{
writer.set(operandA).writeString("-.$type$+").writeString(type.fasmFullName).trim();
output.printlnInstruction(di, operandA);
}
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printlnLabel(".$iend$");
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
protected void generatePrimitiveData(PrimitiveType type, AssemblerSourcePrintStream output) {
AssemblerElementWriter writer = getAssemblerElementWriter();
boolean is64bits = pointerSize == BITS64;
char[] operandA = new char[0x0100];
char[] operandB = new char[0x0020];
char[] operandC = new char[0x0020];
char[] intZero = writer.set(new char[0x0020]).writeInt(0).get();
char[] longZero = writer.set(new char[0x0020]).writeLong(0).get();
CharArray[] operands = new CharArray[4];
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printHeader("; <fold ");
output.print(type.specialCanonicalName);
output.print(" — ");
output.print(package.getResourceString("comment.data.type"));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printlnInstruction("class", type.fasmFullName);
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = writer.set(operandA).writeInt(type.attributes).get();
operands[1] = writer.set(operandB).writeInt(fldStringStorage.indexAcquire(type.specialSimpleName)).get();
operands[2] = writer.set(operandC).writeInt(type.fieldWidth).get();
operands[3] = intZero;
output.printlnInstruction("dd", operands, 0, 4);
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = intZero;
operands[1] = intZero;
operands[2] = intZero;
operands[3] = intZero;
output.printlnInstruction("dd", operands, 0, 4);
output.printlnInstruction("dd", operands, 0, 4);
output.printlnInstruction("dd", operands, 0, 4);
output.printlnInstruction("dd", operands, 0, 4);
output.printlnInstruction("dd", operands, 0, 4);
/* -------------------------------------------------------------------------------------------------------------------------------- */
if(is64bits)
{
operands[0] = longZero;
operands[1] = longZero;
operands[2] = writer.set(operandA).writeString("-.this+").writeString(type.parentPackage.fasmFullName).get();
operands[3] = longZero;
output.printlnInstruction("dq", operands, 0, 2);
output.printlnInstruction("dq", operands, 2, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = longZero;
operands[1] = longZero;
output.printlnInstruction("dq", operands, 0, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printlnInstruction("dq", longZero);
} else
{
output.printlnInstruction("dd", operands, 0, 4);
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = intZero;
operands[1] = intZero;
operands[2] = writer.set(operandA).writeString("-.this+").writeString(type.parentPackage.fasmFullName).get();
operands[3] = intZero;
output.printlnInstruction("dd", operands, 0, 4);
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = longZero;
operands[1] = longZero;
output.printlnInstruction("dq", operands, 0, 2);
output.printlnInstruction("dq", operands, 0, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = intZero;
operands[1] = intZero;
output.printlnInstruction("dd", operands, 0, 2);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = writer.set(operandA).writeInt(type.kind).get();
operands[1] = "-.this+.$iend$";
output.printlnInstruction("dd", operands, 0, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = longZero;
operands[1] = longZero;
output.printlnInstruction("dq", operands, 0, 2);
output.printlnInstruction("dq", operands, 0, 2);
output.printlnInstruction("dq", operands, 0, 2);
output.printlnInstruction("dq", operands, 0, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printlnLabel(".$iend$");
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
protected void generateClassData(ClassType type, AssemblerSourcePrintStream output) {
boolean is64bits = pointerSize == BITS64;
boolean isReflect = fldReflect;
boolean isService = false;
boolean isStruct = false;
boolean isHelper = type.isHelper();
boolean isClass = !isHelper && (type.isClass() || (isStruct = type.isStruct()) || (isService = type.isService()) && !type.isAbstract());
int tlength = type.length;
ClassType superclass = type.getSuperclassType();
Type component = !(type instanceof ArrayType) ? null : ((ArrayType) type).componentType;
/* -------------------------------------------------------------------------------------------------------------------------------- */
Field[] rfld = null;
if(isClass)
{
int length = 0;
ClassType curr = type;
do
{
for(int clength = curr.length, int cindex = 0; cindex < clength; cindex++)
{
Member member = curr[cindex];
if(member instanceof Field && !member.isStatic())
{
Field field = (Field) member;
String name = member.specialSimpleName;
if(!field.type.isPrimitive() && name != null && !name.isEmpty())
{
if(rfld == null)
{
rfld = new Field[0xff];
}
else if(rfld.length == length)
{
Array.copy(rfld, 0, rfld = new Field[length << 1 | 1], 0, length);
}
rfld[length++] = field;
}
}
}
} while((curr = curr.getSuperclassType()) != null);
if(length > 0) rfld.length = length;
}
Callable[] virt = !isClass ? null : type.virtualCallables();
Callable[] srvc = !isService ? null : type.serviceCallables();
if(virt != null && virt.length <= 0) virt = null;
if(srvc != null && srvc.length <= 0) srvc = null;
ClassType[] impl = null;
ClassType[] serv = null;
{
int slength = type.getSuperservicesLength();
if(isClass)
{
int length = 0;
for(int sindex = isService ? -1 : 0; sindex < slength; sindex++)
{
ClassType superservice = sindex < 0 ? type : type.getSuperserviceTypeAt(sindex);
if(
superclass == null || !superclass.isSuperservice(superservice) ||
!superservice.isInterface() && !superclass.hasOverriddingMembersFor(superservice, true) && type.hasOverriddingMembersFor(superservice, false)
)
{
if(impl == null) impl = new ClassType[slength + 1];
impl[length++] = superservice;
}
}
if(length > 0) impl.length = length;
}
if(!isHelper)
{
int length = 0;
for(int sindex = 0; sindex < slength; sindex++)
{
ClassType superservice = type.getSuperserviceTypeAt(sindex);
if(serv == null) serv = new ClassType[slength];
serv[length++] = superservice;
}
}
}
Field[] sfld = null;
if(isStruct)
{
int length = 0;
ClassType curr = type;
do
{
for(int clength = curr.length, int cindex = 0; cindex < clength; cindex++)
{
Member member = curr[cindex];
if(member instanceof Field && !member.isStatic())
{
Field field = (Field) member;
String name = member.specialSimpleName;
if(field.type instanceof ReferenceType && name != null && !name.isEmpty())
{
if(sfld == null)
{
sfld = new Field[0xff];
}
else if(sfld.length == length)
{
Array.copy(sfld, 0, sfld = new Field[length << 1 | 1], 0, length);
}
sfld[length++] = field;
}
}
}
} while((curr = curr.getSuperclassType()) != null && curr.isStruct());
if(length > 0) sfld.length = length;
}
int[] dmai = null;
Field[] globals = isStruct ? null : new Field[tlength];
Field[] structs = !isStruct ? null : new Field[tlength];
Field[] instances = isHelper || isService ? null : new Field[tlength];
Field[] dfld = null;
Property[] dprp = null;
Callable[] dmth = null;
ArgumentArrayStorage astore = null;
{
int ilength = 0;
int slength = 0;
int glength = 0;
int flength = 0;
int mlength = 0;
int plength = 0;
for(int tindex = 0; tindex < tlength; tindex++)
{
Member member = type[tindex];
if(member.isStatic())
{
if(globals != null && member instanceof Field) globals[glength++] = (Field) member;
continue;
}
if(member instanceof Field)
{
Field field = (Field) member;
String name = member.specialSimpleName;
boolean hasName = name != null && !name.isEmpty();
if(instances != null && (!isStruct || hasName && !field.type.isPrimitive()))
{
instances[ilength++] = field;
}
if(structs != null && hasName)
{
structs[slength++] = field;
}
if(isReflect && !isStruct)
{
if(dfld == null) dfld = new Field[tlength];
dfld[flength++] = field;
}
continue;
}
if(isReflect && !isStruct)
{
if(member instanceof Property)
{
if(dprp == null) dprp = new Property[tlength];
dprp[plength++] = (Property) member;
continue;
}
if(member instanceof Callable)
{
if(dmth == null)
{
dmai = new int[tlength];
dmth = new Callable[tlength];
astore = new ArgumentArrayStorage();
}
Callable method = (Callable) member;
dmai[mlength] = astore.indexAcquire(method.arguments);
dmth[mlength++] = method;
}
}
}
if(instances != null) instances.length = ilength;
if(structs != null) structs.length = slength;
if(globals != null) globals.length = glength;
if(flength > 0) dfld.length = flength;
if(plength > 0) dprp.length = plength;
if(mlength > 0) dmth.length = mlength;
}
Callable defc = isHelper ? null : (isService ? superclass : !isStruct ? type : getClassType(PACKNAME_LANG + "." + TYPENAME_STRUCT)).getChildCallable(SPECNAME_INST_INIT, (Type[]) null);
/* -------------------------------------------------------------------------------------------------------------------------------- */
AssemblerElementWriter writer = getAssemblerElementWriter();
char[] operandA = new char[0x2000];
char[] operandB = new char[0x0100];
char[] operandC = new char[0x0100];
char[] operandD = new char[0x2000];
char[] intZero = writer.set(new char[0x0020]).writeInt(0).get();
char[] longZero = writer.set(new char[0x0020]).writeLong(0).get();
CharArray[] operands = new CharArray[8];
String di = is64bits ? "dq" : "dd";
String source = type.outputPath;
String fasmFullName = type.fasmFullName;
String specialCanonicalName = type.specialCanonicalName;
StringStorage strings = fldDebugInfoStrings;
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printHeader("; <fold ");
output.print(specialCanonicalName);
output.print(" — ");
output.print(package.getResourceString("comment.data.type"));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printlnInstruction("class", fasmFullName);
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = writer.set(operandA).writeInt(type.attributes).get();
operands[1] = writer.set(operandB).writeInt(fldStringStorage.indexAcquire(type.specialSimpleName)).get();
operands[2] = writer.set(operandC).writeInt(type.instanceSize).get();
operands[3] = writer.set(operandD).writeInt(type.structSize).get();
output.printlnInstruction("dd", operands, 0, 4);
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = writer.set(operandA).writeInt(rfld == null ? 0 : rfld.length).get();
operands[1] = writer.set(operandB).writeInt(virt == null ? 0 : virt.length).get();
operands[2] = writer.set(operandC).writeInt(impl == null ? 0 : impl.length).get();
operands[3] = writer.set(operandD).writeInt(serv == null ? 0 : serv.length).get();
output.printlnInstruction("dd", operands, 0, 4);
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = writer.set(operandA).writeInt(sfld == null ? 0 : sfld.length).get();
operands[1] = writer.set(operandB).writeInt(dfld == null ? 0 : dfld.length).get();
operands[2] = writer.set(operandC).writeInt(dmth == null ? 0 : dmth.length).get();
operands[3] = writer.set(operandD).writeInt(dprp == null ? 0 : dprp.length).get();
output.printlnInstruction("dd", operands, 0, 4);
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = rfld != null ? (CharArray) "-.this+.$rfld$" : intZero;
operands[1] = virt != null ? (CharArray) "-.this+.$virt$" : intZero;
operands[2] = impl != null ? (CharArray) "-.this+.$impl$" : intZero;
operands[3] = serv != null ? (CharArray) "-.this+.$serv$" : intZero;
output.printlnInstruction("dd", operands, 0, 4);
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = sfld != null ? (CharArray) "-.this+.$sfld$" : intZero;
operands[1] = dfld != null ? (CharArray) "-.this+.$dfld$" : intZero;
operands[2] = dmth != null ? (CharArray) "-.this+.$dmth$" : intZero;
operands[3] = dprp != null ? (CharArray) "-.this+.$dprp$" : intZero;
output.printlnInstruction("dd", operands, 0, 4);
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = writer.set(operandA).writeInt(defc == null ? 0 : defc.attributes).get();
operands[1] = intZero;
operands[2] = intZero;
operands[3] = intZero;
output.printlnInstruction("dd", operands, 0, 4);
/* -------------------------------------------------------------------------------------------------------------------------------- */
if(isHelper)
{
superclass = type.getHelperForType();
}
if(is64bits)
{
operands[0] = (superclass == null ? writer.set(operandA).writeLong(0) : writer.set(operandA).writeString("-.this+").writeString(superclass.fasmFullName)).get();
operands[1] = (component == null ? writer.set(operandB).writeLong(0) : writer.set(operandB).writeString("-.this+").writeString(component.fasmFullName)).get();
operands[2] = writer.set(operandC).writeString("-.this+").writeString(type.parentPackage.fasmFullName).get();
operands[3] = (defc == null ? writer.set(operandD).writeLong(0) : writer.set(operandD).writeString("-.this+").writeString(defc.fasmFullName)).get();
output.printlnInstruction("dq", operands, 0, 2);
output.printlnInstruction("dq", operands, 2, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = longZero;
operands[1] = longZero;
output.printlnInstruction("dq", operands, 0, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
writer.set(operandA).writeString("-.this+dbgi$isrc").writeLabel(fldDebugInfoSources.indexAcquire(type.outputPath)).trim();
output.printlnInstruction("dq", operandA);
} else
{
operands[0] = intZero;
operands[1] = intZero;
operands[2] = intZero;
operands[3] = intZero;
output.printlnInstruction("dd", operands, 0, 4);
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = (superclass == null ? writer.set(operandA).writeInt(0) : writer.set(operandA).writeString("-.this+").writeString(superclass.fasmFullName)).get();
operands[1] = (component == null ? writer.set(operandB).writeInt(0) : writer.set(operandB).writeString("-.this+").writeString(component.fasmFullName)).get();
operands[2] = writer.set(operandC).writeString("-.this+").writeString(type.parentPackage.fasmFullName).get();
operands[3] = (defc == null ? writer.set(operandD).writeInt(0) : writer.set(operandD).writeString("-.this+").writeString(defc.fasmFullName)).get();
output.printlnInstruction("dd", operands, 0, 4);
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = longZero;
operands[1] = longZero;
output.printlnInstruction("dq", operands, 0, 2);
output.printlnInstruction("dq", operands, 0, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = writer.set(operandA).writeString("-.this+dbgi$isrc").writeLabel(fldDebugInfoSources.indexAcquire(type.outputPath)).get();
operands[1] = intZero;
output.printlnInstruction("dd", operands, 0, 2);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = intZero;
operands[1] = "-.this+.$iend$";
output.printlnInstruction("dd", operands, 0, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = longZero;
operands[1] = longZero;
output.printlnInstruction("dq", operands, 0, 2);
output.printlnInstruction("dq", operands, 0, 2);
output.printlnInstruction("dq", operands, 0, 2);
output.printlnInstruction("dq", operands, 0, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
if(rfld != null) for(output.printLabel(".$rfld$"), int length = rfld.length, int limit = length + (length & 1), int index = 0; index < limit; index++)
{
output.printlnInstruction("dd", index >= length ? (CharArray) intZero : rfld[index].fasmFullName);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
if(virt != null) for(output.printLabel(".$virt$"), int length = virt.length, int index = 0; index < length; index++)
{
writer.set(operandA).writeString("-.$virt$+").writeString(virt[index].fasmFullName).trim();
output.printlnInstruction(di, operandA);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
if(impl != null) for(output.printLabel(".$impl$"), int length = impl.length, int index = 0; index < length; index++)
{
String implements = impl[index].fasmFullName;
operands[0] = writer.set(operandA).writeString("-.$impl$+").writeString(fasmFullName).writeString("$$impl$$").writeString(implements).get();
operands[1] = writer.set(operandB).writeString("-.$impl$+").writeString(implements).get();
output.printlnInstruction(di, operands, 0, 2);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
if(serv != null) for(output.printLabel(".$serv$"), int length = serv.length, int index = 0; index < length; index++)
{
writer.set(operandA).writeString("-.$serv$+").writeString(serv[index].fasmFullName).trim();
output.printlnInstruction(di, operandA);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
if(sfld != null) for(output.printLabel(".$sfld$"), int length = sfld.length, int index = 0; index < length; index++)
{
Field field = sfld[index];
String name = field.specialSimpleName;
strings.indexAcquire(name);
operands[0] = writer.set(operandA).writeInt(field.attributes).get();
operands[1] = name;
operands[2] = field.type.fasmFullName;
operands[3] = writer.set(operandB).writeInt(field.capacity).get();
operands[4] = field.fasmFullName;
output.printlnInstruction("dsfld", operands, 0, 5);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
if(dfld != null) for(output.printLabel(".$dfld$"), int length = dfld.length, int index = 0; index < length; index++)
{
Field field = dfld[index];
String name = field.specialSimpleName;
strings.indexAcquire(name);
operands[0] = writer.set(operandA).writeInt(field.attributes).get();
operands[1] = name;
operands[2] = field.type.fasmFullName;
operands[3] = field.fasmFullName;
output.printlnInstruction("dfild", operands, 0, 4);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
if(dmth != null) for(output.printLabel(".$dmth$"), int length = dmth.length, int index = 0; index < length; index++)
{
Callable method = dmth[index];
String name = method.specialSimpleName;
ArgumentArray arguments = method.arguments;
int nlength = name.length - 1;
boolean isSpecial = nlength > 0 && name[0] == '<' && name[nlength] == '>';
strings.indexAcquire(name);
operands[0] = writer.set(operandA).writeInt(method.attributes | arguments.length << 0x10).get();
operands[1] = !isSpecial ? (CharArray) name : writer.set(operandB).writeString(name, 1, nlength).get();
operands[2] = method.type.fasmFullName;
operands[3] = method.fasmFullName;
operands[4] = writer.set(operandC).writeLabel(dmai[index]).get();
output.printlnInstruction(isSpecial ? "dmeths" : "dmeth", operands, 0, 5);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
if(dprp != null) for(output.printLabel(".$dprp$"), int length = dprp.length, int index = 0; index < length; index++)
{
Method method;
Property property = dprp[index];
String name = property.specialSimpleName;
strings.indexAcquire(name);
operands[0] = writer.set(operandA).writeInt(property.attributes).get();
operands[1] = name;
operands[2] = property.type.fasmFullName;
operands[3] = (method = property.readSynthetic) == null ? ".$dprp$" : method.fasmFullName;
operands[4] = (method = property.writeSynthetic) == null ? ".$dprp$" : method.fasmFullName;
operands[5] = (method = property.storedSynthetic) == null ? ".$dprp$" : method.fasmFullName;
output.printlnInstruction("dprop", operands, 0, 6);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(int alength = astore == null ? 0 : astore.length, int aindex = 0; aindex < alength; aindex++)
{
output.printLabel(writer.set(operandA).writeLabel(aindex).get());
for(ArgumentArray arguments = astore[aindex], int length = arguments.length, int index = 0; index < length; index++)
{
writer.set(operandA).writeChar('-').writeLabel(aindex).writeChar('+').writeString(arguments[index].type.fasmFullName).trim();
output.printlnInstruction(di, operandA);
}
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printlnLabel(".$iend$");
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
/* -------------------------------------------------------------------------------------------------------------------------------- */
if(globals != null)
{
char[][] fasmNums = new char[][] { operandA, operandB, operandC, operandD, new char[0x0020], new char[0x0020], new char[0x0020], new char[0x0020] };
strings = fldStringStorage;
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printHeader("; <fold ");
output.print(specialCanonicalName);
output.print(" — ");
output.print(package.getResourceString("comment.field.static"));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(int length = globals.length, int index = 0; index < length; index++)
{
Field global = globals[index];
String gname = global.fasmFullName;
Constant gvalue = global.value;
Type gtype = global.type;
if(!global.isFinal() || gvalue == null)
{
operands[0] = gname;
operands[1] = gtype.fasmSimpleName;
output.printlnInstruction("glob", operands, 0, 2);
if(gvalue == null)
{
if(!(gtype instanceof PrimitiveType))
{
output.printlnInstruction(di, "null");
continue;
}
PrimitiveType prim = (PrimitiveType) gtype;
int vlength = prim.vectorLength;
switch(prim.kind)
{
case BYTE2:
case BYTE4:
case BYTE8:
Array.fill(operands, 0, vlength, writer.set(operandA).writeByte(0).get());
output.printlnInstruction("db", operands, 0, vlength);
continue;
case SHORT2:
case SHORT4:
case SHORT8:
Array.fill(operands, 0, vlength, writer.set(operandA).writeShort(0).get());
output.printlnInstruction("dw", operands, 0, vlength);
continue;
case INT2:
case INT4:
case INT8:
case FLOAT:
case FLOAT2:
case FLOAT4:
case FLOAT8:
Array.fill(operands, 0, vlength, writer.set(operandA).writeInt(0).get());
output.printlnInstruction("dd", operands, 0, vlength);
continue;
case LONG:
case LONG2:
case LONG4:
case LONG8:
case DOUBLE:
case DOUBLE2:
case DOUBLE4:
case DOUBLE8:
Array.fill(operands, 0, vlength, writer.set(operandA).writeLong(0).get());
output.printlnInstruction("dq", operands, 0, vlength);
continue;
case REAL:
Array.fill(operands, 0, 5, writer.set(operandA).writeShort(0).get());
output.printlnInstruction("dw", operands, 0, 5);
continue;
default:
output.printlnInstruction("dd", intZero);
continue;
}
}
PrimitiveType prim = (PrimitiveType) gtype;
int vlength = prim.vectorLength;
switch(prim.kind)
{
case BYTE2:
case BYTE4:
case BYTE8:
for(byte8 value = gvalue.asByte8(), int vindex = 0; vindex < vlength; vindex++)
{
writer.set(fasmNums[vindex]).writeByte(value[vindex]).trim();
}
output.printlnInstruction("db", fasmNums, 0, vlength);
continue;
case SHORT2:
case SHORT4:
case SHORT8:
for(short8 value = gvalue.asShort8(), int vindex = 0; vindex < vlength; vindex++)
{
writer.set(fasmNums[vindex]).writeShort(value[vindex]).trim();
}
output.printlnInstruction("dw", fasmNums, 0, vlength);
continue;
case INT2:
case INT4:
case INT8:
for(int8 value = gvalue.asInt8(), int vindex = 0; vindex < vlength; vindex++)
{
writer.set(fasmNums[vindex]).writeInt(value[vindex]).trim();
}
output.printlnInstruction("dd", fasmNums, 0, vlength);
continue;
case LONG:
case LONG2:
case LONG4:
case LONG8:
for(long8 value = gvalue.asLong8(), int vindex = 0; vindex < vlength; vindex++)
{
writer.set(fasmNums[vindex]).writeLong(value[vindex]).trim();
}
output.printlnInstruction("dq", fasmNums, 0, vlength);
continue;
case FLOAT:
case FLOAT2:
case FLOAT4:
case FLOAT8:
for(int8 value = Float8.toInt8Bits(gvalue.asFloat8()), int vindex = 0; vindex < vlength; vindex++)
{
writer.set(fasmNums[vindex]).writeInt(value[vindex]).trim();
}
output.printlnInstruction("dd", fasmNums, 0, vlength);
continue;
case DOUBLE:
case DOUBLE2:
case DOUBLE4:
case DOUBLE8:
for(long8 value = Double8.toLong8Bits(gvalue.asDouble8()), int vindex = 0; vindex < vlength; vindex++)
{
writer.set(fasmNums[vindex]).writeLong(value[vindex]).trim();
}
output.printlnInstruction("dq", fasmNums, 0, vlength);
continue;
case REAL:
for(short8 value = Long2.toShort8Bits(Real.toLong2Bits(gvalue.asReal())), int vindex = 0; vindex < 5; vindex++)
{
writer.set(fasmNums[vindex]).writeShort(value[vindex]).trim();
}
output.printlnInstruction("dw", fasmNums, 0, 5);
continue;
default:
{
writer.set(fasmNums[0]).writeInt(gvalue.asInt()).trim();
}
output.printlnInstruction("dd", fasmNums, 0, 1);
continue;
}
}
if(gvalue.isNull())
{
operands[0] = gname;
operands[1] = "null";
output.printlnInstruction("iconst", operands, 0, 2);
continue;
}
if(gvalue.isReflective())
{
operands[0] = gname;
operands[1] = ((RequiredReflectItem) gvalue.asObject()).fasmFullName;
output.printlnInstruction("oconst", operands, 0, 2);
continue;
}
if(gvalue.isString())
{
operands[0] = gname;
operands[1] = writer.set(operandA).writeInt(strings.indexAcquire((String) gvalue.asObject())).get();
output.printlnInstruction("sconst", operands, 0, 2);
continue;
}
if(gvalue.isBoolean())
{
operands[0] = gname;
operands[1] = gvalue.asBoolean() ? "true" : "false";
output.printlnInstruction("iconst", operands, 0, 2);
continue;
}
switch(gtype.kind)
{
case REAL:
writer.set(operandA).writeString(gname).writeString(" at cons$e+").writeDecimal(fldRealStorage.indexAcquire(gvalue.asReal()) * 10).trim();
break;
case DOUBLE:
writer.set(operandA).writeString(gname).writeString(" at cons$d+").writeOffset(fldDoubleStorage.indexAcquire(gvalue.asDouble()) << 4).trim();
break;
case DOUBLE2:
writer.set(operandA).writeString(gname).writeString(" at cons$d2+").writeOffset(fldDouble2Storage.indexAcquire(gvalue.asDouble2()) << 4).trim();
break;
case DOUBLE4:
writer.set(operandA).writeString(gname).writeString(" at cons$d4+").writeOffset(fldDouble4Storage.indexAcquire(gvalue.asDouble4()) << 5).trim();
break;
case DOUBLE8:
writer.set(operandA).writeString(gname).writeString(" at cons$d8+").writeOffset(fldDouble8Storage.indexAcquire(gvalue.asDouble8()) << 6).trim();
break;
case FLOAT:
writer.set(operandA).writeString(gname).writeString(" at cons$f+").writeOffset(fldFloatStorage.indexAcquire(gvalue.asFloat()) << 4).trim();
break;
case FLOAT2:
writer.set(operandA).writeString(gname).writeString(" at cons$f2+").writeOffset(fldFloat2Storage.indexAcquire(gvalue.asFloat2()) << 4).trim();
break;
case FLOAT4:
writer.set(operandA).writeString(gname).writeString(" at cons$f4+").writeOffset(fldFloat4Storage.indexAcquire(gvalue.asFloat4()) << 4).trim();
break;
case FLOAT8:
writer.set(operandA).writeString(gname).writeString(" at cons$f8+").writeOffset(fldFloat8Storage.indexAcquire(gvalue.asFloat8()) << 5).trim();
break;
case BYTE2:
writer.set(operandA).writeString(gname).writeString(" at cons$b2+").writeOffset(fldByte2Storage.indexAcquire(gvalue.asByte2()) << 4).trim();
break;
case BYTE4:
writer.set(operandA).writeString(gname).writeString(" at cons$b4+").writeOffset(fldByte4Storage.indexAcquire(gvalue.asByte4()) << 4).trim();
break;
case BYTE8:
writer.set(operandA).writeString(gname).writeString(" at cons$b8+").writeOffset(fldByte8Storage.indexAcquire(gvalue.asByte8()) << 4).trim();
break;
case SHORT2:
writer.set(operandA).writeString(gname).writeString(" at cons$s2+").writeOffset(fldShort2Storage.indexAcquire(gvalue.asShort2()) << 4).trim();
break;
case SHORT4:
writer.set(operandA).writeString(gname).writeString(" at cons$s4+").writeOffset(fldShort4Storage.indexAcquire(gvalue.asShort4()) << 4).trim();
break;
case SHORT8:
writer.set(operandA).writeString(gname).writeString(" at cons$s8+").writeOffset(fldShort8Storage.indexAcquire(gvalue.asShort8()) << 4).trim();
break;
case INT2:
writer.set(operandA).writeString(gname).writeString(" at cons$i2+").writeOffset(fldInt2Storage.indexAcquire(gvalue.asInt2()) << 4).trim();
break;
case INT4:
writer.set(operandA).writeString(gname).writeString(" at cons$i4+").writeOffset(fldInt4Storage.indexAcquire(gvalue.asInt4()) << 4).trim();
break;
case INT8:
writer.set(operandA).writeString(gname).writeString(" at cons$i8+").writeOffset(fldInt8Storage.indexAcquire(gvalue.asInt8()) << 5).trim();
break;
case LONG:
writer.set(operandA).writeString(gname).writeString(" at cons$l+").writeOffset(fldLongStorage.indexAcquire(gvalue.asLong()) << 3).trim();
break;
case LONG2:
writer.set(operandA).writeString(gname).writeString(" at cons$l2+").writeOffset(fldLong2Storage.indexAcquire(gvalue.asLong2()) << 4).trim();
break;
case LONG4:
writer.set(operandA).writeString(gname).writeString(" at cons$l4+").writeOffset(fldLong4Storage.indexAcquire(gvalue.asLong4()) << 5).trim();
break;
case LONG8:
writer.set(operandA).writeString(gname).writeString(" at cons$l8+").writeOffset(fldLong8Storage.indexAcquire(gvalue.asLong8()) << 6).trim();
break;
default:
int value = gvalue.asInt();
operands[0] = gname;
operands[1] = (value >= 0 ? writer.set(operandA).writeInt(value) : writer.set(operandA).writeChar('-').writeInt(-value)).get();
output.printlnInstruction("iconst", operands, 0, 2);
continue;
}
output.printlnInstruction("label", operandA);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printlnInstruction("separator_d");
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
if(instances != null)
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printHeader("; <fold ");
output.print(specialCanonicalName);
output.print(" — ");
output.print(package.getResourceString("comment.field.instance"));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(int length = instances.length, int index = 0; index < length; index++)
{
Field field = instances[index];
operands[0] = writer.set(operandA).writeInt(field.instanceOffset).get();
operands[1] = field.fasmFullName;
output.printlnInstruction("field", operands, 0, 2);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
if(structs != null)
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printHeader("; <fold ");
output.print(specialCanonicalName);
output.print(" — ");
output.print(package.getResourceString("comment.field.struct"));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(int length = structs.length, int index = 0; index < length; index++)
{
Field field = structs[index];
operands[0] = writer.set(operandA).writeInt(field.structOffset).get();
operands[1] = writer.set(operandB).writeString(field.fasmFullName).writeString(".struct").get();
output.printlnInstruction("field", operands, 0, 2);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
if(virt != null)
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printHeader("; <fold ");
output.print(specialCanonicalName);
output.print(" — ");
output.print(package.getResourceString("comment.index.virtual"));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(int length = virt.length, int index = 0; index < length; index++)
{
Callable callable = virt[index];
if(callable.parentType == type)
{
operands[0] = writer.set(operandA).writeInt(index).get();
operands[1] = callable.fasmFullName;
output.printlnInstruction("idxvirt", operands, 0, 2);
}
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
if(srvc != null)
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printHeader("; <fold ");
output.print(specialCanonicalName);
output.print(" — ");
output.print(package.getResourceString("comment.index.service"));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(int length = srvc.length, int index = 0; index < length; index++)
{
Callable callable = srvc[index];
if(callable.parentType == type)
{
operands[0] = writer.set(operandA).writeInt(index).get();
operands[1] = callable.fasmFullName;
output.printlnInstruction("idxserv", operands, 0, 2);
}
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
}
protected void generateClassCode(ClassType type, AssemblerSourcePrintStream output) {
String specialCanonicalName = type.specialCanonicalName;
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printHeader("; <fold ");
output.print(specialCanonicalName);
output.print(" — ");
output.print(package.getResourceString("comment.code.compiled"));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(boolean isNone = true, int length = type.length, int index = 0; index < length; index++)
{
Member member = type[index];
if(member instanceof Callable)
{
Callable method = (Callable) member;
if(!method.isNative())
{
if(isNone)
{
isNone = false;
} else
{
output.println();
}
generateCallableCode(method, output);
}
}
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
if(!type.isHelper() && (type.isClass() || type.isStruct() || type.isService() && !type.isAbstract()))
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printHeader("; <fold ");
output.print(specialCanonicalName);
output.print(" — ");
output.print(package.getResourceString("comment.implementors"));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(ClassType superclass = type.getSuperclassType(), boolean isNone = true, int length = type.getSuperservicesLength(), int index = type.isService() ? -1 : 0; index < length; index++)
{
ClassType superservice = index < 0 ? type : type.getSuperserviceTypeAt(index);
if(
superclass == null || !superclass.isSuperservice(superservice) ||
!superservice.isInterface() && !superclass.hasOverriddingMembersFor(superservice, true) && type.hasOverriddingMembersFor(superservice, false)
)
{
if(isNone)
{
isNone = false;
} else
{
output.println();
}
generateImplementorCode(type, superservice, output);
}
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
}
protected void generateCallableCode(Callable callable, AssemblerSourcePrintStream output) {
AssemblerElementWriter writer = getAssemblerElementWriter();
char[] mnemonic = new char[0x0010];
char[] operandA = new char[0x2000];
char[] operandB = new char[0x0100];
char[][] labels = null;
CharArray[] operands = new CharArray[3];
Code code = callable.code;
Source source = callable.source;
String outputPath = callable.parentType.outputPath;
String fasmFullName = callable.fasmFullName;
ArgumentArray arguments = callable.arguments;
Local thisArgument = arguments.thisArgument;
boolean isInstance = thisArgument != null;
int alength = arguments.length;
/* -------------------------------------------------------------------------------------------------------------------------------- */
{
Type type = callable.type;
boolean isVoid = type.isVoid();
output.printHeader("if(used ");
output.print(fasmFullName);
output.print(") ; <fold ");
if(!isVoid)
{
output.print("returns ");
output.print(type.specialCanonicalName);
}
if(callable instanceof Method)
{
Method method = (Method) callable;
for(int length = method.getThrowablesLength(), int index = 0; index < length; index++)
{
output.print(index > 0 ? ", " : isVoid ? "throws " : ", throws ");
output.print(method.getThrowableTypeAt(index).specialCanonicalName);
}
}
output.println(">");
output.increaseMargin();
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
label0: if(code == null)
{
/* заголовок абстрактного метода */
operands[0] = fasmFullName;
operands[1] = "\\";
output.printlnInstruction("method", operands, 0, !isInstance && alength <= 0 ? 1 : 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(operands[2] = "\\", int alimit = alength - 1, int aindex = isInstance ? -1 : 0; aindex < alength; aindex++)
{
Local argument = aindex < 0 ? thisArgument : arguments[aindex];
operands[0] = argument.fasmSimpleName;
operands[1] = argument.type.fasmSimpleName;
output.printlnContinuation(operands, 0, aindex >= alimit ? 2 : 3);
}
} else
{
Node node;
int instruction;
int clength = code.length;
if(!callable.isInterrupt())
{
/* критерии кусков кода, не создающих стаковый кадр */
if(
(
callable.isStatic() && callable.arguments.length <= 0
) && (
clength > 2 &&
code[0].instruction == METHOD_ENTER &&
(
(instruction = (node = code[1]).instruction) == LOAD_CONST && !((Constant) node.operand1).isString() ||
instruction == LOAD_STATIC
) &&
code[2].instruction == METHOD_LEAVE
)
)
{
/* заголовок куска кода */
output.printlnInstruction("proc", fasmFullName);
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(ObjectArray lines = !(source instanceof TextSource) ? null : ((TextSource) source).lines, int cindex = 0; cindex < clength; cindex++)
{
/* метки */
int label = (node = code[cindex]).debugIndex;
if(label >= 0)
{
if(outputPath != null)
{
int line = (int) node.location;
if(line >= 0)
{
/* строка текстового исходного кода */
writer.set(operandA).writeDecimal(line + 1).trim();
output.printHeader("; ");
output.print(outputPath);
output.print("[");
output.print(operandA);
output.print("]");
if(lines != null && line < lines.length)
{
output.print(": ");
output.print(lines[line].toString().trim());
}
output.println();
}
}
output.printLabel(writer.set(operandA).writeLabel('D', label).get());
}
if((label = node.labelIndex) >= 0)
{
output.printLabel(writer.set(operandA).writeLabel('L', label).get());
}
/* инструкции */
switch(node.instruction)
{
case LOAD_CONST:
Constant value = (Constant) node.operand1;
constantToFasmString(value, operandA);
writer.set(mnemonic).writeString("load").writeSignature(value.type, STACK).writeString("_g").trim();
output.printlnInstruction(mnemonic, operandA);
break;
case LOAD_STATIC:
Field global = (Field) node.operand1;
writer.set(mnemonic).writeString("load").writeSignature(global.type, STACK).writeString("_g").trim();
writer.set(operandA).writeChar('[').writeString(global.fasmFullName).writeChar(']').trim();
output.printlnInstruction(mnemonic, operandA);
break;
case METHOD_LEAVE:
output.printlnInstruction("ret");
output.printlnInstruction("end_proc");
break label0;
}
}
}
/* критерии кода быстрого метода */
if(
(
clength > 1 &&
code[0].instruction == METHOD_ENTER &&
code[1].instruction == METHOD_LEAVE
) || (
clength > 2 &&
code[0].instruction == METHOD_ENTER &&
(
(instruction = (node = code[1]).instruction) == LOAD_CONST && !((Constant) node.operand1).isString() ||
instruction == READ_FIELD && node.operand2 != null ||
instruction == LOAD_LOCAL
) &&
code[2].instruction == METHOD_LEAVE
) || (
clength > 4 &&
code[0].instruction == METHOD_ENTER &&
(
(instruction = code[1].instruction) == LOAD_LOCAL ||
instruction == LOAD_STATIC
) && (
(instruction = (node = code[2]).instruction) == LOAD_CONST && !((Constant) node.operand1).isString() ||
instruction == READ_FIELD && node.operand2 != null ||
instruction == LOAD_LOCAL
) &&
code[3].instruction == WRITE_FIELD &&
code[4].instruction == METHOD_LEAVE
)
)
{
/* заголовок быстрого метода */
operands[0] = fasmFullName;
operands[1] = "\\";
output.printlnInstruction("fast", operands, 0, !isInstance && alength <= 0 ? 1 : 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(operands[2] = "\\", int alimit = alength - 1, int aindex = isInstance ? -1 : 0; aindex < alength; aindex++)
{
Local argument = aindex < 0 ? thisArgument : arguments[aindex];
operands[0] = argument.fasmSimpleName;
operands[1] = argument.type.fasmSimpleName;
output.printlnContinuation(operands, 0, aindex >= alimit ? 2 : 3);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(
TypedItem reference = null, ObjectArray lines = !(source instanceof TextSource) ? null : ((TextSource) source).lines, node = clength <= 0 ? null : code[0], Node next,
int cindex = 0; (next = ++cindex >= clength ? null : code[cindex]) == next; node = next
)
{
/* метки */
int label = node.debugIndex;
if(label >= 0)
{
if(outputPath != null)
{
int line = (int) node.location;
if(line >= 0)
{
/* строка текстового исходного кода */
writer.set(operandA).writeDecimal(line + 1).trim();
output.printHeader("; ");
output.print(outputPath);
output.print("[");
output.print(operandA);
output.print("]");
if(lines != null && line < lines.length)
{
output.print(": ");
output.print(lines[line].toString().trim());
}
output.println();
}
}
output.printLabel(writer.set(operandA).writeLabel('D', label).get());
}
if((label = node.labelIndex) >= 0)
{
output.printLabel(writer.set(operandA).writeLabel('L', label).get());
}
/* инструкции */
switch(node.instruction)
{
case METHOD_ENTER:
output.printlnInstruction("fenter");
break;
case LOAD_CONST:
Constant value = (Constant) node.operand1;
constantToFasmString(value, operandA);
writer.set(mnemonic).writeString("load").writeSignature(value.type, next.instruction == WRITE_FIELD ? WEAK | STACK : STACK).writeString("_g").trim();
output.printlnInstruction(mnemonic, operandA);
break;
case LOAD_LOCAL:
if(cindex == 2 && next.instruction != METHOD_LEAVE)
{
reference = (Local) node.operand1;
break;
}
Local local = (Local) node.operand1;
Type ltype = (Type) node.operand2;
if(ltype == null) ltype = local.type;
writer.set(mnemonic).writeString("load").writeSignature(ltype, next.instruction == WRITE_FIELD ? WEAK | STACK : STACK).writeString("_l").trim();
output.printlnInstruction(mnemonic, local.fasmSimpleName);
break;
case LOAD_STATIC:
reference = (Field) node.operand1;
break;
case READ_FIELD:
Field field = (Field) node.operand1;
TypedItem item = (TypedItem) node.operand2;
Type type = field.type;
String suffix = additionalToFasmString(item, operandA);
writer.set(mnemonic).writeString(field.parentType.isStruct() && type.isPrimitive() ? "frdsf" : "frdif").writeSignature(
type, next.instruction == WRITE_FIELD ? WEAK : NORM
).writeString(suffix).trim();
operands[0] = field.fasmFullName;
operands[1] = operandA;
output.printlnInstruction(mnemonic, operands, 0, 2);
if(next.instruction == METHOD_LEAVE && item instanceof Local)
{
reference = item;
output.printlnInstruction("frelease_o", item.fasmSimpleName);
}
break;
case WRITE_FIELD:
Field field = (Field) node.operand1;
Type type = field.type;
String suffix = additionalToFasmString(reference, operandA);
writer.set(mnemonic).writeString(field.parentType.isStruct() && type.isPrimitive() ? "fwrsf" : "fwrif").writeSignature(type, WEAK).writeString(suffix).trim();
operands[0] = field.fasmFullName;
operands[1] = operandA;
output.printlnInstruction(mnemonic, operands, 0, 2);
break;
case METHOD_LEAVE:
for(int aindex = thisArgument != null ? -1 : 0; aindex < alength; aindex++)
{
Local argument = aindex < 0 ? thisArgument : arguments[aindex];
if(argument != reference) switch(argument.type.kind)
{
case INT8:
case LONG4:
case FLOAT8:
case DOUBLE4:
output.printlnInstruction("fcltag_y", argument.fasmSimpleName);
break;
case LONG8:
case DOUBLE8:
output.printlnInstruction("fcltag_z", argument.fasmSimpleName);
break;
case REF:
String name = argument.fasmSimpleName;
output.printlnInstruction("frelease", name);
output.printlnInstruction("fcltag_x", name);
}
}
output.printlnInstruction("fleave");
break label0;
}
}
}
}
/* заголовок нормального метода */
operands[0] = fasmFullName;
operands[1] = "\\";
output.printlnInstruction("method", operands, 0, !isInstance && alength <= 0 ? 1 : 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(operands[2] = "\\", int alimit = alength - 1, int aindex = isInstance ? -1 : 0; aindex < alength; aindex++)
{
Local argument = aindex < 0 ? thisArgument : arguments[aindex];
operands[0] = argument.fasmSimpleName;
operands[1] = argument.type.fasmSimpleName;
output.printlnContinuation(operands, 0, aindex >= alimit ? 2 : 3);
}
/* локальные переменные */
Hashtable mainTable = new Hashtable();
Hashtable refsTable = new Hashtable();
{
StringArray mainArray = new StringArray();
StringArray refsArray = new StringArray();
with(code.locals) for(int length = length, int index = 0; index < length; index++) with(operator [](index)) if(!isConstant())
{
Type type = type;
String name = fasmSimpleName;
if(!mainTable.containsKey(name))
{
mainArray.append(name);
mainTable[name] = type;
}
else if(!refsTable.containsKey(name))
{
Type prev = (Type) mainTable[name];
if(prev.isPrimitive())
{
if(type.isPrimitive())
{
if(prev.fieldWidth < type.fieldWidth) mainTable[name] = type;
} else
{
refsArray.append(name);
refsTable[name] = type;
}
} else
{
if(type.isPrimitive())
{
refsArray.append(name);
refsTable[name] = prev;
mainTable[name] = type;
}
}
}
else if(type.isPrimitive() && ((Type) mainTable[name]).fieldWidth < type.fieldWidth)
{
mainTable[name] = type;
}
}
for(operands[2] = "\\", boolean mainUse = true, int length = mainArray.length, int limit = refsArray.length + length - 1, int index = 0; index <= limit; index++)
{
if(index == length) mainUse = false;
String name = mainUse ? mainArray[index] : refsArray[index - length];
Type type = (Type) (mainUse ? mainTable : refsTable)[name];
operands[0] = mainUse ? name : (CharArray) writer.set(operandA).writeChar('$').writeString(name).get();
operands[1] = type.fasmSimpleName;
if(index <= 0)
{
output.printlnInstruction("loc", operands, 0, index < limit ? 3 : 2);
continue;
}
output.printlnContinuation(operands, 0, index < limit ? 3 : 2);
}
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(
boolean anonymus = false, ObjectArray lines = !(source instanceof TextSource) ? null : ((TextSource) source).lines, node = clength <= 0 ? null : code[0], Node next,
int cindex = 0; cindex < clength && (next = ++cindex >= clength ? null : code[cindex]) == next; node = next
)
{
Node jumpIsTrue = node.jumpIsTrue;
Node jumpIsFalse = node.jumpIsFalse;
boolean isConditionalJump = jumpIsTrue != null && jumpIsFalse != null;
int kindOfResultType = isConditionalJump ? BOOLEAN : getNeedRegisterTypeKind(next);
/* метки */
int label = node.debugIndex;
if(label >= 0)
{
if(outputPath != null)
{
int line = (int) node.location;
if(line >= 0)
{
/* строка текстового исходного кода */
writer.set(operandA).writeDecimal(line + 1).trim();
output.printHeader("; ");
output.print(outputPath);
output.print("[");
output.print(operandA);
output.print("]");
if(lines != null && line < lines.length)
{
output.print(": ");
output.print(lines[line].toString().trim());
}
output.println();
}
}
output.printLabel(writer.set(operandA).writeLabel('D', label).get());
}
if((label = node.labelIndex) >= 0)
{
output.printLabel(writer.set(operandA).writeLabel('L', label).get());
}
/* инструкции */
labelConj:
{
labelPop:
{
int kindOfPushType = BOOLEAN;
labelPush:
{
switch(node.instruction)
{
case END:
case BEGIN:
case BOUND:
continue;
case INSTANCEOF:
output.printlnInstruction("instof", ((ClassType) node.operand1).fasmFullName);
break;
case BRANCH:
int jlength = node.getJumpCasesLength();
if(jlength > 0)
{
if(labels == null) with((labels = new char[0x0009][0x0020])[8])
{
length = 1;
operator []=(0, '\\');
}
int min = node.getJumpCaseValueAt(0);
int max = min;
for(int jindex = 1; jindex < jlength; jindex++)
{
int cur = node.getJumpCaseValueAt(jindex);
if(min > cur) min = cur;
if(max < cur) max = cur;
}
Node jumpDefault = node.jumpDefault;
if(((long) max - min + 1 << 2) + 48 > ((long) jlength + 1) * 10)
{
operands[0] = writer.set(operandA).writeLabel(jumpDefault).get();
operands[1] = "\\";
output.printlnInstruction("switch_l", operands, 0, 2);
with(labels[2])
{
length = 1;
operator []=(0, '\\');
}
for(int jindex = 0; jindex < jlength; )
{
int jvalue = node.getJumpCaseValueAt(jindex);
Node target = node.getJumpCaseNodeAt(jindex);
writer.set(labels[0]).writeInt(jvalue).trim();
writer.set(labels[1]).writeLabel(target).trim();
output.printlnContinuation(labels, 0, ++jindex < jlength ? 3 : 2);
}
continue;
}
operands[0] = writer.set(operandA).writeLabel(jumpDefault).get();
operands[1] = writer.set(operandB).writeInt(min).get();
operands[2] = "\\";
output.printlnInstruction("switch_t", operands, 0, 3);
jlength = max - min + 1;
for(int jvalue = min, int jindex = 0; jindex < jlength; jvalue++, jindex++)
{
int jlower = jindex & 7;
Node target = node.getJumpCase(jvalue);
writer.set(labels[jlower++]).writeLabel(target == null ? jumpDefault : target).trim();
if(jvalue == max)
{
output.printlnContinuation(labels, 0, jlower);
continue;
}
if(jlower == 8)
{
output.printlnContinuation(labels, 0, 9);
}
}
continue;
}
/* падение через */
case JUMP:
case RETURN:
writer.set(operandA).writeLabel(node.jumpDefault).trim();
output.printlnInstruction("jmp", operandA);
continue;
case THROW:
output.printlnInstruction("throw");
continue;
case INVOKE_FINALLY:
writer.set(operandA).writeLabel((Node) node.reference1).trim();
output.printlnInstruction("invfin", operandA);
break labelPop;
case CLINIT_TRY_LOCK:
output.printlnInstruction("citrlock", ((ReflectItem) node.operand1).fasmFullName);
break;
case CLINIT_UNLOCK:
output.printlnInstruction("ciunlock", ((ReflectItem) node.operand1).fasmFullName);
continue;
case FINALLY_ENTER:
output.printlnInstruction("finenter");
continue;
case FINALLY_LEAVE:
output.printlnInstruction("finleave");
continue;
case MONITOR_ENTER:
output.printlnInstruction("monenter");
continue;
case MONITOR_LEAVE:
output.printlnInstruction("monleave");
continue;
case METHOD_ENTER:
writer.set(operandA).writeOffset(((Int) node.reference1).intValue).trim();
output.printlnInstruction(callable.isInterrupt() ? "ienter" : "menter", operandA);
continue;
case METHOD_LEAVE:
output.printlnInstruction(callable.isInterrupt() ? "ileave" : "mleave");
continue;
case LOAD_CONST:
Constant value = (Constant) node.operand1;
Type type = value.type;
if(value.isString())
{
writer.set(operandA).writeOffset(fldStringStorage.indexAcquire((String) value.asObject())).trim();
output.printlnInstruction("loadstr", operandA);
kindOfPushType = REF;
break labelPush;
}
constantToFasmString(value, operandA);
writer.set(mnemonic).writeString("load").writeSignature(type, node.weak ? WEAK | STACK : STACK).writeString("_g").trim();
output.printlnInstruction(mnemonic, operandA);
kindOfPushType = type.kind;
break labelPush;
case LOAD_LOCAL:
Local local = (Local) node.operand1;
Type type = (Type) node.operand2;
String name = local.fasmSimpleName;
if(type == null) type = local.type;
writer.set(mnemonic).writeString("load").writeSignature(type, node.weak ? WEAK | STACK : STACK).writeString("_l").trim();
operands[0] = type.isPrimitive() || !refsTable.containsKey(name) ? name : (CharArray) writer.set(operandA).writeChar('$').writeString(name).get();
output.printlnInstruction(mnemonic, operands, 0, 1);
kindOfPushType = type.kind;
break;
case LOAD_INTERRUPT:
output.printlnInstruction("loadint", ((ReflectItem) node.operand1).fasmFullName);
kindOfPushType = pointerSize == BITS64 ? LONG : INT;
break labelPush;
case LOAD_STATIC:
Field global = (Field) node.operand1;
Type type = global.type;
writer.set(mnemonic).writeString("load").writeSignature(type, node.weak ? WEAK | STACK : STACK).writeString("_g").trim();
writer.set(operandA).writeChar('[').writeString(global.fasmFullName).writeChar(']').trim();
output.printlnInstruction(mnemonic, operandA);
kindOfPushType = type.kind;
break;
case READ_ELEMENT:
PrimitiveType type = (PrimitiveType) node.operand1;
Constant index = (Constant) node.operand2;
if(index == null)
{
writer.set(mnemonic).writeString("rdve").writeSignature(type, NORM).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("rdve").writeSignature(type, NORM).writeString("_c").trim();
writer.set(operandA).writeDecimal(index.asInt()).trim();
output.printlnInstruction(mnemonic, operandA);
kindOfPushType = type.vectorBaseKind;
break labelPush;
case READ_COMPONENT:
Type type = (Type) node.operand1;
TypedItem item = (TypedItem) node.operand2;
if(item == null)
{
writer.set(mnemonic).writeString("rdac").writeSignature(type, NORM).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
break labelConj;
}
String suffix = additionalToFasmString(item, operandA, refsTable);
writer.set(mnemonic).writeString("rdac").writeSignature(type, NORM).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
kindOfPushType = type.kind;
break;
case READ_FIELD:
Field field = (Field) node.operand1;
TypedItem item = (TypedItem) node.operand2;
Type type = field.type;
String suffix = additionalToFasmString(item, operandA, refsTable);
writer.set(mnemonic).writeString(field.parentType.isStruct() && type.isPrimitive() ? "rdsf" : "rdif").writeSignature(type, NORM).writeString(suffix).trim();
operands[0] = field.fasmFullName;
operands[1] = operandA;
output.printlnInstruction(mnemonic, operands, 0, item == null ? 1 : 2);
kindOfPushType = type.kind;
break;
case READ_SPECIAL:
Property property = (Property) node.operand1;
TypedItem item = (TypedItem) node.operand2;
Callable synthetic = property.readSynthetic;
if(!property.hasIndex())
{
TypedMember member = property.readMember;
if(member instanceof Field)
{
Field field = (Field) member;
Type type = field.type;
String suffix = additionalToFasmString(item, operandA, refsTable);
writer.set(mnemonic).writeString(field.parentType.isStruct() && type.isPrimitive() ? "rdsf" : "rdif").writeSignature(type, NORM).writeString(suffix).trim();
operands[0] = field.fasmFullName;
operands[1] = operandA;
output.printlnInstruction(mnemonic, operands, 0, item == null ? 1 : 2);
kindOfPushType = type.kind;
break;
}
if(member instanceof Callable)
{
if(item != null)
{
String suffix = additionalToFasmString(item, operandA, refsTable);
writer.set(mnemonic).writeString("load").writeSignature(item.type, STACK).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
output.printlnInstruction("tpushr");
}
Callable method = (Callable) member;
if(method.serviceIndex < 0)
{
output.printlnInstruction(method.virtualIndex < 0 ? "invspec" : "invvirt", method.fasmFullName);
} else
{
operands[0] = method.parentType.fasmFullName;
operands[1] = writer.set(operandA).writeString(method.fasmSimpleName).writeString(method.arguments.toFasmString()).get();
output.printlnInstruction("invserv", operands, 0, 2);
}
kindOfPushType = method.type.kind;
break;
}
}
if(item != null)
{
String suffix = additionalToFasmString(item, operandA, refsTable);
writer.set(mnemonic).writeString("load").writeSignature(item.type, STACK).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
output.printlnInstruction("tpushr");
}
output.printlnInstruction("invspec", synthetic.fasmFullName);
kindOfPushType = synthetic.type.kind;
break;
case READ_PROPERTY:
Property property = (Property) node.operand1;
TypedItem item = (TypedItem) node.operand2;
Callable synthetic = property.readSynthetic;
int sindex = synthetic.serviceIndex;
int vindex = synthetic.virtualIndex;
if(!property.hasIndex() && (sindex & vindex) < 0)
{
TypedMember member = property.readMember;
if(member instanceof Field)
{
Field field = (Field) member;
Type type = field.type;
String suffix = additionalToFasmString(item, operandA, refsTable);
writer.set(mnemonic).writeString(field.parentType.isStruct() && type.isPrimitive() ? "rdsf" : "rdif").writeSignature(type, NORM).writeString(suffix).trim();
operands[0] = field.fasmFullName;
operands[1] = operandA;
output.printlnInstruction(mnemonic, operands, 0, item == null ? 1 : 2);
kindOfPushType = type.kind;
break;
}
if(member instanceof Callable)
{
if(item != null)
{
String suffix = additionalToFasmString(item, operandA, refsTable);
writer.set(mnemonic).writeString("load").writeSignature(item.type, STACK).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
output.printlnInstruction("tpushr");
}
Callable method = (Callable) member;
if(method.serviceIndex < 0)
{
output.printlnInstruction(method.virtualIndex < 0 ? "invspec" : "invvirt", method.fasmFullName);
} else
{
operands[0] = method.parentType.fasmFullName;
operands[1] = writer.set(operandA).writeString(method.fasmSimpleName).writeString(method.arguments.toFasmString()).get();
output.printlnInstruction("invserv", operands, 0, 2);
}
kindOfPushType = method.type.kind;
break;
}
}
if(item != null)
{
String suffix = additionalToFasmString(item, operandA, refsTable);
writer.set(mnemonic).writeString("load").writeSignature(item.type, STACK).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
output.printlnInstruction("tpushr");
}
if(sindex < 0)
{
output.printlnInstruction(vindex < 0 ? "invspec" : "invvirt", synthetic.fasmFullName);
} else
{
operands[0] = synthetic.parentType.fasmFullName;
operands[1] = writer.set(operandA).writeString(synthetic.fasmSimpleName).writeString(synthetic.arguments.toFasmString()).get();
output.printlnInstruction("invserv", operands, 0, 2);
}
kindOfPushType = synthetic.type.kind;
break;
case SWAP:
writer.set(mnemonic).writeString("tswap").writeSignature((Type) node.operand1, STACK).writeString("_p").trim();
output.printlnInstruction(mnemonic);
continue;
case DUP1:
writer.set(mnemonic).writeString("tdup1").writeSignature((Type) node.operand1, STACK).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
break labelConj;
case DUP1X1:
writer.set(mnemonic).writeString("tdup1x1").writeSignature((Type) node.operand1, STACK).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
break labelConj;
case DUP1X2:
writer.set(mnemonic).writeString("tdup1x2").writeSignature((Type) node.operand1, STACK).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
break labelConj;
case DUP2:
writer.set(mnemonic).writeString("tdup2").writeSignature((Type) node.operand1, STACK).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
break labelConj;
case INVOKE_STATIC:
Callable method = (Callable) node.operand1;
Type type = method.type;
output.printlnInstruction("invstat", method.fasmFullName);
if(type.isVoid())
{
break labelPop;
}
if(node.weak)
{
writer.set(mnemonic).writeString("release").writeSignature(type, STACK).trim();
output.printlnInstruction(mnemonic);
break labelPop;
}
kindOfPushType = type.kind;
break;
case INVOKE_SPECIAL:
Callable method = (Callable) node.operand1;
Type type = method.type;
output.printlnInstruction("invspec", method.fasmFullName);
if(type.isVoid())
{
break labelPop;
}
if(node.weak)
{
writer.set(mnemonic).writeString("release").writeSignature(type, STACK).trim();
output.printlnInstruction(mnemonic);
break labelPop;
}
kindOfPushType = type.kind;
break;
case INVOKE_VIRTUAL:
Callable method = (Callable) node.operand1;
Type type = method.type;
output.printlnInstruction(method.virtualIndex < 0 ? "invspec" : "invvirt", method.fasmFullName);
if(type.isVoid())
{
break labelPop;
}
if(node.weak)
{
writer.set(mnemonic).writeString("release").writeSignature(type, STACK).trim();
output.printlnInstruction(mnemonic);
break labelPop;
}
kindOfPushType = type.kind;
break;
case INVOKE_SERVICE:
Callable method = (Callable) node.operand1;
Type type = method.type;
if(method.serviceIndex < 0)
{
output.printlnInstruction(method.virtualIndex < 0 ? "invspec" : "invvirt", method.fasmFullName);
} else
{
operands[0] = method.parentType.fasmFullName;
operands[1] = writer.set(operandA).writeString(method.fasmSimpleName).writeString(method.arguments.toFasmString()).get();
output.printlnInstruction("invserv", operands, 0, 2);
}
if(type.isVoid())
{
break labelPop;
}
if(node.weak)
{
writer.set(mnemonic).writeString("release").writeSignature(type, STACK).trim();
output.printlnInstruction(mnemonic);
break labelPop;
}
kindOfPushType = type.kind;
break;
case NEW_VECTOR:
writer.set(mnemonic).writeString("newv").writeSignature((PrimitiveType) node.operand1, NORM).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
case NEW_ARRAY:
operands[0] = ((ArrayType) node.operand1).fasmFullName;
operands[1] = writer.set(operandA).writeInt(((Constant) node.operand2).asInt()).get();
output.printlnInstruction("newa_c", operands, 0, 2);
kindOfPushType = REF;
break labelPush;
case NEW_ARRAY_MONO:
output.printlnInstruction("newa", ((ArrayType) node.operand1).fasmFullName);
kindOfPushType = REF;
break labelPush;
case NEW_ARRAY_MULTI:
output.printlnInstruction("newam", ((ArrayType) node.operand1).fasmFullName);
kindOfPushType = REF;
break labelPush;
case NEW_INSTANCE:
output.printlnInstruction("newi", ((ClassType) node.operand1).fasmFullName);
kindOfPushType = REF;
break labelPush;
case CAST_TO:
Type typeNew = (Type) node.operand1;
Type typeSrc = (Type) node.operand2;
if(!typeNew.isPrimitive())
{
output.printlnInstruction("castrto", typeNew.fasmFullName);
kindOfPushType = REF;
break labelPush;
}
int kindOfNew;
int kindOfSrc;
int lengthOfNew;
int lengthOfSrc;
int kindBaseOfNew;
int kindBaseOfSrc;
with((PrimitiveType) typeNew)
{
kindOfNew = kind;
lengthOfNew = vectorLength;
kindBaseOfNew = vectorBaseKind;
}
with((PrimitiveType) typeSrc)
{
kindOfSrc = kind;
lengthOfSrc = vectorLength;
kindBaseOfSrc = vectorBaseKind;
}
if(kindOfSrc == CHAR)
{
kindOfSrc = INT;
lengthOfSrc = 1;
kindBaseOfSrc = INT;
}
if(kindOfNew == CHAR)
{
switch(kindBaseOfSrc)
{
case CHAR:
break;
case BYTE:
case SHORT:
case INT:
if(lengthOfSrc > 1)
{
writer.set(mnemonic).writeString("cast").writeSignature(kindOfSrc, STACK).writeString("to").writeSignature(kindBaseOfSrc, NORM).trim();
output.printlnInstruction(mnemonic);
}
output.printlnInstruction("castitoc");
break;
default:
if(lengthOfSrc > 1)
{
writer.set(mnemonic).writeString("cast").writeSignature(kindOfSrc, STACK).writeString("to").writeSignature(kindBaseOfSrc, NORM).trim();
output.printlnInstruction(mnemonic);
}
writer.set(mnemonic).writeString("cast").writeSignature(kindBaseOfSrc, STACK).writeString("toi").trim();
output.printlnInstruction(mnemonic);
output.printlnInstruction("castitoc");
}
}
else if(lengthOfNew < lengthOfSrc)
{
int kindOfMid = kindBaseOfSrc | kindOfNew & 3;
int lengthOfMid = lengthOfNew;
int kindBaseOfMid = kindBaseOfSrc;
/* понижение длины вектора */
{
writer.set(mnemonic).writeString("cast").writeSignature(kindOfSrc, STACK).writeString("to").writeSignature(kindOfMid, NORM).trim();
output.printlnInstruction(mnemonic);
}
/* изменение типа элементов вектора */
if(isTypeCastAvailable(kindBaseOfMid, lengthOfMid, kindBaseOfNew, lengthOfNew))
{
writer.set(mnemonic).writeString("cast").writeSignature(kindOfMid, STACK).writeString("to").writeSignature(kindOfNew, NORM).trim();
output.printlnInstruction(mnemonic);
}
}
else if(lengthOfNew > lengthOfSrc)
{
int kindOfMid = kindBaseOfNew | kindOfSrc & 3;
int lengthOfMid = lengthOfSrc;
int kindBaseOfMid = kindBaseOfNew;
/* изменение типа элементов вектора */
if(isTypeCastAvailable(kindBaseOfSrc, lengthOfSrc, kindBaseOfMid, lengthOfMid))
{
writer.set(mnemonic).writeString("cast").writeSignature(kindOfSrc, STACK).writeString("to").writeSignature(kindOfMid, NORM).trim();
output.printlnInstruction(mnemonic);
}
/* повышение длины вектора */
{
writer.set(mnemonic).writeString("cast").writeSignature(kindOfMid, STACK).writeString("to").writeSignature(kindOfNew, NORM).trim();
output.printlnInstruction(mnemonic);
}
}
else
{
/* изменение типа элементов вектора */
if(isTypeCastAvailable(kindBaseOfSrc, lengthOfSrc, kindBaseOfNew, lengthOfNew))
{
writer.set(mnemonic).writeString("cast").writeSignature(kindOfSrc, STACK).writeString("to").writeSignature(kindOfNew, NORM).trim();
output.printlnInstruction(mnemonic);
}
}
kindOfPushType = kindOfNew;
break labelPush;
case INC_LOCAL:
Local local = (Local) node.operand1;
Type type = (Type) node.operand2;
if(type == null) type = local.type;
writer.set(mnemonic).writeString("inc").writeSignature(type, NORM).writeString("_l").trim();
output.printlnInstruction(mnemonic, local.fasmSimpleName);
continue;
case DEC_LOCAL:
Local local = (Local) node.operand1;
Type type = (Type) node.operand2;
if(type == null) type = local.type;
writer.set(mnemonic).writeString("dec").writeSignature(type, NORM).writeString("_l").trim();
output.printlnInstruction(mnemonic, local.fasmSimpleName);
continue;
case INC_PRED_LOAD_LOCAL:
Local local = (Local) node.operand1;
Type type = (Type) node.operand2;
if(type == null) type = local.type;
writer.set(mnemonic).writeString("incload").writeSignature(type, NORM).writeString("_l").trim();
output.printlnInstruction(mnemonic, local.fasmSimpleName);
kindOfPushType = type.kind;
break labelPush;
case DEC_PRED_LOAD_LOCAL:
Local local = (Local) node.operand1;
Type type = (Type) node.operand2;
if(type == null) type = local.type;
writer.set(mnemonic).writeString("decload").writeSignature(type, NORM).writeString("_l").trim();
output.printlnInstruction(mnemonic, local.fasmSimpleName);
kindOfPushType = type.kind;
break labelPush;
case INC_POST_LOAD_LOCAL:
Local local = (Local) node.operand1;
Type type = (Type) node.operand2;
if(type == null) type = local.type;
writer.set(mnemonic).writeString("loadinc").writeSignature(type, NORM).writeString("_l").trim();
output.printlnInstruction(mnemonic, local.fasmSimpleName);
kindOfPushType = type.kind;
break labelPush;
case DEC_POST_LOAD_LOCAL:
Local local = (Local) node.operand1;
Type type = (Type) node.operand2;
if(type == null) type = local.type;
writer.set(mnemonic).writeString("loaddec").writeSignature(type, NORM).writeString("_l").trim();
output.printlnInstruction(mnemonic, local.fasmSimpleName);
kindOfPushType = type.kind;
break labelPush;
case REF_EQ:
TypedItem item = (TypedItem) node.operand1;
String suffix = additionalToFasmString(item, operandB, refsTable);
if(isConditionalJump)
{
int order = node.order + 1;
if(jumpIsFalse.order == order)
{
writer.set(mnemonic).writeString(node.weak ? "jweq" : "jreq").writeString(suffix).trim();
operands[0] = writer.set(operandA).writeLabel(jumpIsTrue).get();
operands[1] = operandB;
output.printlnInstruction(mnemonic, operands, 0, item == null ? 1 : 2);
continue;
}
{
writer.set(mnemonic).writeString(node.weak ? "jwne" : "jrne").writeString(suffix).trim();
operands[0] = writer.set(operandA).writeLabel(jumpIsFalse).get();
operands[1] = operandB;
output.printlnInstruction(mnemonic, operands, 0, item == null ? 1 : 2);
}
if(jumpIsTrue.order != order)
{
writer.set(operandA).writeLabel(jumpIsTrue).trim();
output.printlnInstruction("jmp", operandA);
}
continue;
}
if(item == null)
{
output.printlnInstruction(kindOfResultType <= VOID ? "setreq_p" : "setreq");
continue;
}
writer.set(mnemonic).writeString(node.weak ? "setweq" : "setreq").writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandB);
break labelPush;
case REF_NE:
TypedItem item = (TypedItem) node.operand1;
String suffix = additionalToFasmString(item, operandB, refsTable);
if(isConditionalJump)
{
int order = node.order + 1;
if(jumpIsFalse.order == order)
{
writer.set(mnemonic).writeString(node.weak ? "jwne" : "jrne").writeString(suffix).trim();
operands[0] = writer.set(operandA).writeLabel(jumpIsTrue).get();
operands[1] = operandB;
output.printlnInstruction(mnemonic, operands, 0, item == null ? 1 : 2);
continue;
}
{
writer.set(mnemonic).writeString(node.weak ? "jweq" : "jreq").writeString(suffix).trim();
operands[0] = writer.set(operandA).writeLabel(jumpIsFalse).get();
operands[1] = operandB;
output.printlnInstruction(mnemonic, operands, 0, item == null ? 1 : 2);
}
if(jumpIsTrue.order != order)
{
writer.set(operandA).writeLabel(jumpIsTrue).trim();
output.printlnInstruction("jmp", operandA);
}
continue;
}
if(item == null)
{
output.printlnInstruction(kindOfResultType <= VOID ? "setrne_p" : "setrne");
continue;
}
writer.set(mnemonic).writeString(node.weak ? "setwne" : "setrne").writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandB);
break labelPush;
case REF_IS_NULL:
if(isConditionalJump)
{
int order = node.order + 1;
if(jumpIsFalse.order == order)
{
writer.set(operandA).writeLabel(jumpIsTrue).trim();
output.printlnInstruction(node.weak ? "jwisnull" : "jrisnull", operandA);
continue;
}
{
writer.set(operandA).writeLabel(jumpIsFalse).trim();
output.printlnInstruction(node.weak ? "jwisobj" : "jrisobj", operandA);
}
if(jumpIsTrue.order != order)
{
writer.set(operandA).writeLabel(jumpIsTrue).trim();
output.printlnInstruction("jmp", operandA);
}
continue;
}
output.printlnInstruction(node.weak ? "setwisnull" : "setrisnull");
break labelPush;
case REF_IS_OBJECT:
if(isConditionalJump)
{
int order = node.order + 1;
if(jumpIsFalse.order == order)
{
writer.set(operandA).writeLabel(jumpIsTrue).trim();
output.printlnInstruction(node.weak ? "jwisobj" : "jrisobj", operandA);
continue;
}
{
writer.set(operandA).writeLabel(jumpIsFalse).trim();
output.printlnInstruction(node.weak ? "jwisnull" : "jrisnull", operandA);
}
if(jumpIsTrue.order != order)
{
writer.set(operandA).writeLabel(jumpIsTrue).trim();
output.printlnInstruction("jmp", operandA);
}
continue;
}
output.printlnInstruction(node.weak ? "setwisobj" : "setrisobj");
break labelPush;
case TEST_EQZ:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandB, refsTable);
if(isConditionalJump)
{
int order = node.order + 1;
if(jumpIsFalse.order == order)
{
writer.set(mnemonic).writeString("jteq").writeSignature(type, STACK).writeString(suffix).trim();
operands[0] = writer.set(operandA).writeLabel(jumpIsTrue).get();
operands[1] = operandB;
output.printlnInstruction(mnemonic, operands, 0, item == null ? 1 : 2);
continue;
}
{
writer.set(mnemonic).writeString("jtne").writeSignature(type, STACK).writeString(suffix).trim();
operands[0] = writer.set(operandA).writeLabel(jumpIsFalse).get();
operands[1] = operandB;
output.printlnInstruction(mnemonic, operands, 0, item == null ? 1 : 2);
}
if(jumpIsTrue.order != order)
{
writer.set(operandA).writeLabel(jumpIsTrue).trim();
output.printlnInstruction("jmp", operandA);
}
continue;
}
if(item == null)
{
writer.set(mnemonic).writeString("setteq").writeSignature(type, STACK).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("setteq").writeSignature(type, STACK).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandB);
break labelPush;
case TEST_NEZ:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandB, refsTable);
if(isConditionalJump)
{
int order = node.order + 1;
if(jumpIsFalse.order == order)
{
writer.set(mnemonic).writeString("jtne").writeSignature(type, STACK).writeString(suffix).trim();
operands[0] = writer.set(operandA).writeLabel(jumpIsTrue).get();
operands[1] = operandB;
output.printlnInstruction(mnemonic, operands, 0, item == null ? 1 : 2);
continue;
}
{
writer.set(mnemonic).writeString("jteq").writeSignature(type, STACK).writeString(suffix).trim();
operands[0] = writer.set(operandA).writeLabel(jumpIsFalse).get();
operands[1] = operandB;
output.printlnInstruction(mnemonic, operands, 0, item == null ? 1 : 2);
}
if(jumpIsTrue.order != order)
{
writer.set(operandA).writeLabel(jumpIsTrue).trim();
output.printlnInstruction("jmp", operandA);
}
continue;
}
if(item == null)
{
writer.set(mnemonic).writeString("settne").writeSignature(type, STACK).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("settne").writeSignature(type, STACK).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandB);
break labelPush;
case O_BIT_NOT:
PrimitiveType type = (PrimitiveType) node.operand1;
writer.set(mnemonic).writeString("bnot").writeSignature(type, STACK).trim();
output.printlnInstruction(mnemonic);
kindOfPushType = type.kind;
break;
case O_BIT_AND:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandB, refsTable);
if(isConditionalJump)
{
int order = node.order + 1;
if(jumpIsFalse.order == order)
{
writer.set(mnemonic).writeString("jtne").writeSignature(type, STACK).writeString(suffix).trim();
operands[0] = writer.set(operandA).writeLabel(jumpIsTrue).get();
operands[1] = operandB;
output.printlnInstruction(mnemonic, operands, 0, item == null ? 1 : 2);
continue;
}
{
writer.set(mnemonic).writeString("jteq").writeSignature(type, STACK).writeString(suffix).trim();
operands[0] = writer.set(operandA).writeLabel(jumpIsFalse).get();
operands[1] = operandB;
output.printlnInstruction(mnemonic, operands, 0, item == null ? 1 : 2);
}
if(jumpIsTrue.order != order)
{
writer.set(operandA).writeLabel(jumpIsTrue).trim();
output.printlnInstruction("jmp", operandA);
}
continue;
}
if(item == null)
{
writer.set(mnemonic).writeString("band").writeSignature(type, STACK).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("band").writeSignature(type, STACK).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandB);
kindOfPushType = type.kind;
break labelPush;
case O_BIT_OR:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandA, refsTable);
if(item == null)
{
writer.set(mnemonic).writeString("bor").writeSignature(type, STACK).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
break labelConj;
}
writer.set(mnemonic).writeString("bor").writeSignature(type, STACK).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
kindOfPushType = type.kind;
break;
case O_BIT_XOR:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandA, refsTable);
if(item == null)
{
writer.set(mnemonic).writeString("bxor").writeSignature(type, STACK).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
break labelConj;
}
writer.set(mnemonic).writeString("bxor").writeSignature(type, STACK).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
kindOfPushType = type.kind;
break;
case O_SCAL_NEG:
PrimitiveType type = (PrimitiveType) node.operand1;
writer.set(mnemonic).writeString("sneg").writeSignature(type, STACK).trim();
output.printlnInstruction(mnemonic);
kindOfPushType = type.kind;
break labelPush;
case O_SCAL_MUL:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandA, refsTable);
if(item == null)
{
writer.set(mnemonic).writeString("smul").writeSignature(type, STACK).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("smul").writeSignature(type, STACK).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
kindOfPushType = type.kind;
break labelPush;
case O_SCAL_DIV:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandA, refsTable);
if(item == null)
{
writer.set(mnemonic).writeString("sdiv").writeSignature(type, STACK).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("sdiv").writeSignature(type, STACK).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
kindOfPushType = type.kind;
break labelPush;
case O_SCAL_DIVU:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandA, refsTable);
if(item == null)
{
writer.set(mnemonic).writeString("sdivu").writeSignature(type, STACK).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("sdivu").writeSignature(type, STACK).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
kindOfPushType = type.kind;
break labelPush;
case O_SCAL_REM:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandA, refsTable);
if(item == null)
{
writer.set(mnemonic).writeString("srem").writeSignature(type, STACK).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("srem").writeSignature(type, STACK).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
kindOfPushType = type.kind;
break labelPush;
case O_SCAL_REMU:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandA, refsTable);
if(item == null)
{
writer.set(mnemonic).writeString("sremu").writeSignature(type, STACK).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("sremu").writeSignature(type, STACK).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
kindOfPushType = type.kind;
break labelPush;
case O_SCAL_ADD:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandA, refsTable);
if(item == null)
{
writer.set(mnemonic).writeString("sadd").writeSignature(type, STACK).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("sadd").writeSignature(type, STACK).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
kindOfPushType = type.kind;
break labelPush;
case O_SCAL_SUB:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandA, refsTable);
if(item == null)
{
writer.set(mnemonic).writeString("ssub").writeSignature(type, STACK).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("ssub").writeSignature(type, STACK).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
kindOfPushType = type.kind;
break labelPush;
case O_SCAL_SHR:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandA, refsTable);
if(item == null)
{
writer.set(mnemonic).writeString("sshr").writeSignature(type, STACK).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("sshr").writeSignature(type, STACK).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
kindOfPushType = type.kind;
break labelPush;
case O_SCAL_SHRU:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandA, refsTable);
if(item == null)
{
writer.set(mnemonic).writeString("sshru").writeSignature(type, STACK).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("sshru").writeSignature(type, STACK).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
kindOfPushType = type.kind;
break labelPush;
case O_SCAL_SHL:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandA, refsTable);
if(item == null)
{
writer.set(mnemonic).writeString("sshl").writeSignature(type, STACK).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("sshl").writeSignature(type, STACK).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
kindOfPushType = type.kind;
break labelPush;
case O_SCAL_EQ:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandB, refsTable);
if(isConditionalJump)
{
int order = node.order + 1;
if(jumpIsFalse.order == order)
{
writer.set(mnemonic).writeString("jseq").writeSignature(type, STACK).writeString(suffix).trim();
operands[0] = writer.set(operandA).writeLabel(jumpIsTrue).get();
operands[1] = operandB;
output.printlnInstruction(mnemonic, operands, 0, item == null ? 1 : 2);
continue;
}
{
writer.set(mnemonic).writeString("jsne").writeSignature(type, STACK).writeString(suffix).trim();
operands[0] = writer.set(operandA).writeLabel(jumpIsFalse).get();
operands[1] = operandB;
output.printlnInstruction(mnemonic, operands, 0, item == null ? 1 : 2);
}
if(jumpIsTrue.order != order)
{
writer.set(operandA).writeLabel(jumpIsTrue).trim();
output.printlnInstruction("jmp", operandA);
}
continue;
}
if(item == null)
{
writer.set(mnemonic).writeString("setseq").writeSignature(type, STACK).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("setseq").writeSignature(type, STACK).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandB);
break labelPush;
case O_SCAL_NE:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandB, refsTable);
if(isConditionalJump)
{
int order = node.order + 1;
if(jumpIsFalse.order == order)
{
writer.set(mnemonic).writeString("jsne").writeSignature(type, STACK).writeString(suffix).trim();
operands[0] = writer.set(operandA).writeLabel(jumpIsTrue).get();
operands[1] = operandB;
output.printlnInstruction(mnemonic, operands, 0, item == null ? 1 : 2);
continue;
}
{
writer.set(mnemonic).writeString("jseq").writeSignature(type, STACK).writeString(suffix).trim();
operands[0] = writer.set(operandA).writeLabel(jumpIsFalse).get();
operands[1] = operandB;
output.printlnInstruction(mnemonic, operands, 0, item == null ? 1 : 2);
}
if(jumpIsTrue.order != order)
{
writer.set(operandA).writeLabel(jumpIsTrue).trim();
output.printlnInstruction("jmp", operandA);
}
continue;
}
if(item == null)
{
writer.set(mnemonic).writeString("setsne").writeSignature(type, STACK).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("setsne").writeSignature(type, STACK).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandB);
break labelPush;
case O_SCAL_GT:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandB, refsTable);
if(isConditionalJump)
{
int order = node.order + 1;
if(jumpIsFalse.order == order)
{
writer.set(mnemonic).writeString(type.isFloating() ? "jsgtl" : "jsgt").writeSignature(type, STACK).writeString(suffix).trim();
operands[0] = writer.set(operandA).writeLabel(jumpIsTrue).get();
operands[1] = operandB;
output.printlnInstruction(mnemonic, operands, 0, item == null ? 1 : 2);
continue;
}
{
writer.set(mnemonic).writeString(type.isFloating() ? "jslel" : "jsle").writeSignature(type, STACK).writeString(suffix).trim();
operands[0] = writer.set(operandA).writeLabel(jumpIsFalse).get();
operands[1] = operandB;
output.printlnInstruction(mnemonic, operands, 0, item == null ? 1 : 2);
}
if(jumpIsTrue.order != order)
{
writer.set(operandA).writeLabel(jumpIsTrue).trim();
output.printlnInstruction("jmp", operandA);
}
continue;
}
if(item == null)
{
writer.set(mnemonic).writeString("setsgt").writeSignature(type, STACK).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("setsgt").writeSignature(type, STACK).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandB);
break labelPush;
case O_SCAL_GE:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandB, refsTable);
if(isConditionalJump)
{
int order = node.order + 1;
if(jumpIsFalse.order == order)
{
writer.set(mnemonic).writeString(type.isFloating() ? "jsgel" : "jsge").writeSignature(type, STACK).writeString(suffix).trim();
operands[0] = writer.set(operandA).writeLabel(jumpIsTrue).get();
operands[1] = operandB;
output.printlnInstruction(mnemonic, operands, 0, item == null ? 1 : 2);
continue;
}
{
writer.set(mnemonic).writeString(type.isFloating() ? "jsltl" : "jslt").writeSignature(type, STACK).writeString(suffix).trim();
operands[0] = writer.set(operandA).writeLabel(jumpIsFalse).get();
operands[1] = operandB;
output.printlnInstruction(mnemonic, operands, 0, item == null ? 1 : 2);
}
if(jumpIsTrue.order != order)
{
writer.set(operandA).writeLabel(jumpIsTrue).trim();
output.printlnInstruction("jmp", operandA);
}
continue;
}
if(item == null)
{
writer.set(mnemonic).writeString("setsge").writeSignature(type, STACK).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("setsge").writeSignature(type, STACK).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandB);
break labelPush;
case O_SCAL_LT:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandB, refsTable);
if(isConditionalJump)
{
int order = node.order + 1;
if(jumpIsFalse.order == order)
{
writer.set(mnemonic).writeString(type.isFloating() ? "jsltg" : "jslt").writeSignature(type, STACK).writeString(suffix).trim();
operands[0] = writer.set(operandA).writeLabel(jumpIsTrue).get();
operands[1] = operandB;
output.printlnInstruction(mnemonic, operands, 0, item == null ? 1 : 2);
continue;
}
{
writer.set(mnemonic).writeString(type.isFloating() ? "jsgeg" : "jsge").writeSignature(type, STACK).writeString(suffix).trim();
operands[0] = writer.set(operandA).writeLabel(jumpIsFalse).get();
operands[1] = operandB;
output.printlnInstruction(mnemonic, operands, 0, item == null ? 1 : 2);
}
if(jumpIsTrue.order != order)
{
writer.set(operandA).writeLabel(jumpIsTrue).trim();
output.printlnInstruction("jmp", operandA);
}
continue;
}
if(item == null)
{
writer.set(mnemonic).writeString("setslt").writeSignature(type, STACK).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("setslt").writeSignature(type, STACK).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandB);
break labelPush;
case O_SCAL_LE:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandB, refsTable);
if(isConditionalJump)
{
int order = node.order + 1;
if(jumpIsFalse.order == order)
{
writer.set(mnemonic).writeString(type.isFloating() ? "jsleg" : "jsle").writeSignature(type, STACK).writeString(suffix).trim();
operands[0] = writer.set(operandA).writeLabel(jumpIsTrue).get();
operands[1] = operandB;
output.printlnInstruction(mnemonic, operands, 0, item == null ? 1 : 2);
continue;
}
{
writer.set(mnemonic).writeString(type.isFloating() ? "jsgtg" : "jsgt").writeSignature(type, STACK).writeString(suffix).trim();
operands[0] = writer.set(operandA).writeLabel(jumpIsFalse).get();
operands[1] = operandB;
output.printlnInstruction(mnemonic, operands, 0, item == null ? 1 : 2);
}
if(jumpIsTrue.order != order)
{
writer.set(operandA).writeLabel(jumpIsTrue).trim();
output.printlnInstruction("jmp", operandA);
}
continue;
}
if(item == null)
{
writer.set(mnemonic).writeString("setsle").writeSignature(type, STACK).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("setsle").writeSignature(type, STACK).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandB);
break labelPush;
case O_VECT_LUP:
PrimitiveType type = (PrimitiveType) node.operand1;
writer.set(mnemonic).writeString("vlup").writeSignature(type, NORM).trim();
output.printlnInstruction(mnemonic);
kindOfPushType = type.kind + (SHORT - BYTE);
break labelPush;
case O_VECT_UUP:
PrimitiveType type = (PrimitiveType) node.operand1;
writer.set(mnemonic).writeString("vuup").writeSignature(type, NORM).trim();
output.printlnInstruction(mnemonic);
kindOfPushType = type.kind + (SHORT - BYTE);
break labelPush;
case O_VECT_PCK:
PrimitiveType type = (PrimitiveType) node.operand1;
writer.set(mnemonic).writeString("vpck").writeSignature(type, NORM).trim();
output.printlnInstruction(mnemonic);
kindOfPushType = type.kind + (BYTE - SHORT);
break labelPush;
case O_VECT_NEG:
PrimitiveType type = (PrimitiveType) node.operand1;
writer.set(mnemonic).writeString("vneg").writeSignature(type, NORM).trim();
output.printlnInstruction(mnemonic);
kindOfPushType = type.kind;
break labelPush;
case O_VECT_MUL:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandA, refsTable);
if(item == null)
{
writer.set(mnemonic).writeString("vmul").writeSignature(type, NORM).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("vmul").writeSignature(type, NORM).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
kindOfPushType = type.kind;
break labelPush;
case O_VECT_DIV:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandA, refsTable);
if(item == null)
{
writer.set(mnemonic).writeString("vdiv").writeSignature(type, NORM).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("vdiv").writeSignature(type, NORM).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
kindOfPushType = type.isFloating() ? type.kind : DOUBLE | type.kind & 3;
break labelPush;
case O_VECT_ADD:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandA, refsTable);
if(item == null)
{
writer.set(mnemonic).writeString("vadd").writeSignature(type, NORM).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("vadd").writeSignature(type, NORM).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
kindOfPushType = type.kind;
break labelPush;
case O_VECT_SUB:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandA, refsTable);
if(item == null)
{
writer.set(mnemonic).writeString("vsub").writeSignature(type, NORM).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("vsub").writeSignature(type, NORM).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
kindOfPushType = type.kind;
break labelPush;
case O_VECT_SHR:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandA, refsTable);
if(item == null)
{
writer.set(mnemonic).writeString("vshr").writeSignature(type, NORM).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("vshr").writeSignature(type, NORM).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
kindOfPushType = type.kind;
break labelPush;
case O_VECT_SHRU:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandA, refsTable);
if(item == null)
{
writer.set(mnemonic).writeString("vshru").writeSignature(type, NORM).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("vshru").writeSignature(type, NORM).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
kindOfPushType = type.kind;
break labelPush;
case O_VECT_SHL:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandA, refsTable);
if(item == null)
{
writer.set(mnemonic).writeString("vshl").writeSignature(type, NORM).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("vshl").writeSignature(type, NORM).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
kindOfPushType = type.kind;
break labelPush;
case O_VECT_EQ:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandA, refsTable);
if(item == null)
{
writer.set(mnemonic).writeString("veq").writeSignature(type, NORM).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("veq").writeSignature(type, NORM).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
if((kindOfPushType = type.kind) >= DOUBLE && kindOfPushType <= DOUBLE8)
{
kindOfPushType += LONG - DOUBLE;
break labelPush;
}
if(kindOfPushType >= FLOAT && kindOfPushType <= FLOAT8) kindOfPushType += INT - FLOAT;
break labelPush;
case O_VECT_NE:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandA, refsTable);
if(item == null)
{
writer.set(mnemonic).writeString("vne").writeSignature(type, NORM).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("vne").writeSignature(type, NORM).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
if((kindOfPushType = type.kind) >= DOUBLE && kindOfPushType <= DOUBLE8)
{
kindOfPushType += LONG - DOUBLE;
break labelPush;
}
if(kindOfPushType >= FLOAT && kindOfPushType <= FLOAT8) kindOfPushType += INT - FLOAT;
break labelPush;
case O_VECT_GT:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandA, refsTable);
if(item == null)
{
writer.set(mnemonic).writeString("vgt").writeSignature(type, NORM).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("vgt").writeSignature(type, NORM).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
if((kindOfPushType = type.kind) >= DOUBLE && kindOfPushType <= DOUBLE8)
{
kindOfPushType += LONG - DOUBLE;
break labelPush;
}
if(kindOfPushType >= FLOAT && kindOfPushType <= FLOAT8) kindOfPushType += INT - FLOAT;
break labelPush;
case O_VECT_GE:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandA, refsTable);
if(item == null)
{
writer.set(mnemonic).writeString("vge").writeSignature(type, NORM).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("vge").writeSignature(type, NORM).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
if((kindOfPushType = type.kind) >= DOUBLE && kindOfPushType <= DOUBLE8)
{
kindOfPushType += LONG - DOUBLE;
break labelPush;
}
if(kindOfPushType >= FLOAT && kindOfPushType <= FLOAT8) kindOfPushType += INT - FLOAT;
break labelPush;
case O_VECT_LT:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandA, refsTable);
if(item == null)
{
writer.set(mnemonic).writeString("vlt").writeSignature(type, NORM).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("vlt").writeSignature(type, NORM).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
if((kindOfPushType = type.kind) >= DOUBLE && kindOfPushType <= DOUBLE8)
{
kindOfPushType += LONG - DOUBLE;
break labelPush;
}
if(kindOfPushType >= FLOAT && kindOfPushType <= FLOAT8) kindOfPushType += INT - FLOAT;
break labelPush;
case O_VECT_LE:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandA, refsTable);
if(item == null)
{
writer.set(mnemonic).writeString("vle").writeSignature(type, NORM).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("vle").writeSignature(type, NORM).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
if((kindOfPushType = type.kind) >= DOUBLE && kindOfPushType <= DOUBLE8)
{
kindOfPushType += LONG - DOUBLE;
break labelPush;
}
if(kindOfPushType >= FLOAT && kindOfPushType <= FLOAT8) kindOfPushType += INT - FLOAT;
break labelPush;
case O_VECT_HMUL:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandA, refsTable);
if(item == null)
{
writer.set(mnemonic).writeString("vhmul").writeSignature(type, NORM).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("vhmul").writeSignature(type, NORM).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
kindOfPushType = type.kind;
break labelPush;
case O_VECT_HMULU:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandA, refsTable);
if(item == null)
{
writer.set(mnemonic).writeString("vhmulu").writeSignature(type, NORM).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("vhmulu").writeSignature(type, NORM).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
kindOfPushType = type.kind;
break labelPush;
case O_VECT_SADD:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandA, refsTable);
if(item == null)
{
writer.set(mnemonic).writeString("vsadd").writeSignature(type, NORM).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("vsadd").writeSignature(type, NORM).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
kindOfPushType = type.kind;
break labelPush;
case O_VECT_SADDU:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandA, refsTable);
if(item == null)
{
writer.set(mnemonic).writeString("vsaddu").writeSignature(type, NORM).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("vsaddu").writeSignature(type, NORM).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
kindOfPushType = type.kind;
break labelPush;
case O_VECT_SSUB:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandA, refsTable);
if(item == null)
{
writer.set(mnemonic).writeString("vssub").writeSignature(type, NORM).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("vssub").writeSignature(type, NORM).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
kindOfPushType = type.kind;
break labelPush;
case O_VECT_SSUBU:
PrimitiveType type = (PrimitiveType) node.operand1;
TypedItem item = (TypedItem) node.operand2;
String suffix = additionalToFasmString(item, operandA, refsTable);
if(item == null)
{
writer.set(mnemonic).writeString("vssubu").writeSignature(type, NORM).writeString(kindOfResultType <= VOID ? "_p" : "").trim();
output.printlnInstruction(mnemonic);
continue;
}
writer.set(mnemonic).writeString("vssubu").writeSignature(type, NORM).writeString(suffix).trim();
output.printlnInstruction(mnemonic, operandA);
kindOfPushType = type.kind;
break labelPush;
case STORE_LOCAL:
Local local = (Local) node.operand1;
TableItem item = node.operand2;
Constant value = !(item instanceof Constant) ? null : (Constant) item;
String name = local.fasmSimpleName;
if(value == null)
{
Type type = item == null ? local.type : (Type) item;
writer.set(mnemonic).writeString("store").writeSignature(type, STACK).writeString("_l").trim();
operands[0] = type.isPrimitive() || !refsTable.containsKey(name) ? name : (CharArray) writer.set(operandA).writeChar('$').writeString(name).get();
output.printlnInstruction(mnemonic, operands, 0, 1);
break labelPop;
}
Type type = value.type;
constantToFasmString(value, operandB);
writer.set(mnemonic).writeString("store").writeSignature(type, STACK).writeString("_lc").trim();
operands[0] = type.isPrimitive() || !refsTable.containsKey(name) ? name : (CharArray) writer.set(operandA).writeChar('$').writeString(name).get();
operands[1] = operandB;
output.printlnInstruction(mnemonic, operands, 0, 2);
break labelPop;
case DECLARE_LOCAL:
case DECLARE_WITH:
Local local = (Local) node.operand1;
TableItem item = node.operand2;
Constant value = !(item instanceof Constant) ? null : (Constant) item;
String name = local.fasmSimpleName;
if(value == null)
{
Type type = item == null ? local.type : (Type) item;
writer.set(mnemonic).writeString("declare").writeSignature(type, STACK).trim();
operands[0] = type.isPrimitive() || !refsTable.containsKey(name) ? name : (CharArray) writer.set(operandA).writeChar('$').writeString(name).get();
output.printlnInstruction(mnemonic, operands, 0, 1);
break labelPop;
}
Type type = value.type;
constantToFasmString(value, operandB);
writer.set(mnemonic).writeString("declare").writeSignature(value.type, STACK).writeString("_c").trim();
operands[0] = type.isPrimitive() || !refsTable.containsKey(name) ? name : (CharArray) writer.set(operandA).writeChar('$').writeString(name).get();
operands[1] = operandB;
output.printlnInstruction(mnemonic, operands, 0, 2);
break labelPop;
case STORE_STATIC:
Field global = (Field) node.operand1;
Constant value = (Constant) node.operand2;
if(value == null)
{
writer.set(mnemonic).writeString("store").writeSignature(global.type, STACK).writeString("_g").trim();
writer.set(operandA).writeChar('[').writeString(global.fasmFullName).writeChar(']').trim();
output.printlnInstruction(mnemonic, operandA);
break labelPop;
}
constantToFasmString(value, operandB);
writer.set(mnemonic).writeString("store").writeSignature(global.type, STACK).writeString("_gc").trim();
operands[0] = writer.set(operandA).writeChar('[').writeString(global.fasmFullName).writeChar(']').get();
operands[1] = operandB;
output.printlnInstruction(mnemonic, operands, 0, 2);
break labelPop;
case WRITE_COMPONENT:
Type type = (Type) node.operand1;
writer.set(mnemonic).writeString("wrac").writeSignature(type, NORM).trim();
output.printlnInstruction(mnemonic);
break labelPop;
case WRITE_FIELD:
Field field = (Field) node.operand1;
Type type = field.type;
writer.set(mnemonic).writeString(field.parentType.isStruct() && type.isPrimitive() ? "wrsf" : "wrif").writeSignature(type, NORM).trim();
output.printlnInstruction(mnemonic, field.fasmFullName);
break labelPop;
case WRITE_SPECIAL:
Property property = (Property) node.operand1;
Callable synthetic = property.writeSynthetic;
if(!property.hasIndex())
{
TypedMember member = property.writeMember;
if(member instanceof Field)
{
Field field = (Field) member;
Type type = field.type;
writer.set(mnemonic).writeString(field.parentType.isStruct() && type.isPrimitive() ? "wrsf" : "wrif").writeSignature(type, NORM).trim();
output.printlnInstruction(mnemonic, field.fasmFullName);
break labelPop;
}
if(member instanceof Callable)
{
Callable method = (Callable) member;
if(method.serviceIndex < 0)
{
output.printlnInstruction(method.virtualIndex < 0 ? "invspec" : "invvirt", method.fasmFullName);
} else
{
operands[0] = method.parentType.fasmFullName;
operands[1] = writer.set(operandA).writeString(method.fasmSimpleName).writeString(method.arguments.toFasmString()).get();
output.printlnInstruction("invserv", operands, 0, 2);
}
break labelPop;
}
}
output.printlnInstruction("invspec", synthetic.fasmFullName);
break labelPop;
case WRITE_PROPERTY:
Property property = (Property) node.operand1;
Callable synthetic = property.writeSynthetic;
int sindex = synthetic.serviceIndex;
int vindex = synthetic.virtualIndex;
if(!property.hasIndex() && (sindex & vindex) < 0)
{
TypedMember member = property.writeMember;
if(member instanceof Field)
{
Field field = (Field) member;
Type type = field.type;
writer.set(mnemonic).writeString(field.parentType.isStruct() && type.isPrimitive() ? "wrsf" : "wrif").writeSignature(type, NORM).trim();
output.printlnInstruction(mnemonic, field.fasmFullName);
break labelPop;
}
if(member instanceof Callable)
{
Callable method = (Callable) member;
if(method.serviceIndex < 0)
{
output.printlnInstruction(method.virtualIndex < 0 ? "invspec" : "invvirt", method.fasmFullName);
} else
{
operands[0] = method.parentType.fasmFullName;
operands[1] = writer.set(operandA).writeString(method.fasmSimpleName).writeString(method.arguments.toFasmString()).get();
output.printlnInstruction("invserv", operands, 0, 2);
}
break labelPop;
}
}
if(sindex < 0)
{
output.printlnInstruction(vindex < 0 ? "invspec" : "invvirt", synthetic.fasmFullName);
} else
{
operands[0] = synthetic.parentType.fasmFullName;
operands[1] = writer.set(operandA).writeString(synthetic.fasmSimpleName).writeString(synthetic.arguments.toFasmString()).get();
output.printlnInstruction("invserv", operands, 0, 2);
}
break labelPop;
case EXCEPT_ENTER:
output.printlnInstruction("eenter");
continue;
case EXCEPT_TRY:
if(anonymus) output.printLabel(null);
operands[0] = writer.set(operandA).writeLabel((Node) node.reference1).get();
operands[1] = writer.set(operandB).writeLabel((Node) node.reference2).get();
operands[2] = "@F";
output.printlnInstruction("try", operands, 0, 3);
anonymus = true;
continue;
case EXCEPT_CATCH:
operands[0] = ((ClassType) node.reference2).fasmFullName;
operands[1] = writer.set(operandA).writeLabel((Node) node.reference1).get();
output.printlnInstruction("catch", operands, 0, 2);
continue;
case EXCEPT_FINALLY:
writer.set(operandA).writeLabel((Node) node.reference1).trim();
output.printlnInstruction("finally", operandA);
continue;
case EXCEPT_LEAVE:
if(anonymus) output.printLabel(null);
output.printlnInstruction("eleave");
continue;
}
if(isConditionalJump)
{
int order = node.order + 1;
if(jumpIsFalse.order == order)
{
writer.set(operandA).writeLabel(jumpIsTrue).trim();
output.printlnInstruction("jt", operandA);
continue;
}
{
writer.set(operandA).writeLabel(jumpIsFalse).trim();
output.printlnInstruction("jf", operandA);
}
if(jumpIsTrue.order != order)
{
writer.set(operandA).writeLabel(jumpIsTrue).trim();
output.printlnInstruction("jmp", operandA);
}
continue;
}
}
if(kindOfResultType <= VOID)
{
writer.set(mnemonic).writeString("tpush").writeSignature(kindOfPushType, STACK).trim();
output.printlnInstruction(mnemonic);
}
continue;
}
if(kindOfResultType > VOID)
{
writer.set(mnemonic).writeString("tpop").writeSignature(kindOfResultType, STACK).trim();
output.printlnInstruction(mnemonic);
}
}
if(isConditionalJump)
{
int order = node.order + 1;
if(jumpIsFalse.order == order)
{
writer.set(operandA).writeLabel(jumpIsTrue).trim();
output.printlnInstruction("jt", operandA);
continue;
}
{
writer.set(operandA).writeLabel(jumpIsFalse).trim();
output.printlnInstruction("jf", operandA);
}
if(jumpIsTrue.order != order)
{
writer.set(operandA).writeLabel(jumpIsTrue).trim();
output.printlnInstruction("jmp", operandA);
}
}
}
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("end if ; </fold>");
}
protected void generateImplementorCode(ClassType type, ClassType superservice, AssemblerSourcePrintStream output) {
AssemblerElementWriter writer = getAssemblerElementWriter();
char[] operandA = new char[0x0020];
CharArray[] operands = new CharArray[2];
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printHeader("; <fold ");
output.print(superservice.specialCanonicalName);
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = type.fasmFullName;
operands[1] = superservice.fasmFullName;
output.printlnInstruction("impl", operands, 0, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(Callable[] methods = superservice.serviceCallables(), int length = methods == null ? 0 : methods.length, int index = 0; index < length; index++)
{
Callable method = (Callable) methods[index].overridesIn(type, Method.TYPE | Method.SUPERTYPES);
output.printlnInstruction(method.virtualIndex < 0 ? "jmpspec" : "jmpvirt", method.fasmFullName);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
protected void generateConstants(AssemblerSourcePrintStream output) {
AssemblerElementWriter writer = getAssemblerElementWriter();
char[] operandA = new char[0x0020];
char[][] fasmNums = new char[0x0010][0x0020];
CharArray[] operands = new CharArray[2];
Object[] commdata = new String[1];
String commstring = package.getResourceString("comment.constants.type");
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printHeader("; <fold ");
output.print(package.getResourceString("comment.constants.programme"));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
{
commdata[0] = "real";
output.printHeader("; <fold ");
output.print(String.format(commstring, commdata));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = "e";
operands[1] = writer.set(operandA).writeByte(0x04).get();
output.printlnInstruction("cons", operands, 0, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(RealStorage storage = fldRealStorage, int slength = storage.length, int sindex = 0; sindex < slength; sindex++)
{
for(short8 value = Long2.toShort8Bits(Real.toLong2Bits(storage[sindex])), int vindex = 0; vindex < 5; vindex++)
{
writer.set(fasmNums[vindex]).writeShort(value[vindex]).trim();
}
output.printlnInstruction("dw", fasmNums, 0, 5);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
commdata[0] = "double";
output.printHeader("; <fold ");
output.print(String.format(commstring, commdata));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = "d";
operands[1] = writer.set(operandA).writeByte(0x10).get();
output.printlnInstruction("cons", operands, 0, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(DoubleStorage storage = fldDoubleStorage, int slength = storage.length, int sindex = 0; sindex < slength; sindex++)
{
{
writer.set(fasmNums[0]).writeLong(Double.toLongBits(storage[sindex])).trim();
}
{
writer.set(fasmNums[1]).writeDecimal(0).trim();
}
output.printlnInstruction("dq", fasmNums, 0, 2);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
commdata[0] = "double2";
output.printHeader("; <fold ");
output.print(String.format(commstring, commdata));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = "d2";
operands[1] = writer.set(operandA).writeByte(0x10).get();
output.printlnInstruction("cons", operands, 0, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(Double2Storage storage = fldDouble2Storage, int slength = storage.length, int sindex = 0; sindex < slength; sindex++)
{
for(long2 value = Double2.toLong2Bits(storage[sindex]), int vindex = 0; vindex < 2; vindex++)
{
writer.set(fasmNums[vindex]).writeLong(value[vindex]).trim();
}
output.printlnInstruction("dq", fasmNums, 0, 2);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
commdata[0] = "double4";
output.printHeader("; <fold ");
output.print(String.format(commstring, commdata));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = "d4";
operands[1] = writer.set(operandA).writeByte(0x20).get();
output.printlnInstruction("cons", operands, 0, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(Double4Storage storage = fldDouble4Storage, int slength = storage.length, int sindex = 0; sindex < slength; sindex++)
{
for(long4 value = Double4.toLong4Bits(storage[sindex]), int vindex = 0; vindex < 4; vindex++)
{
writer.set(fasmNums[vindex]).writeLong(value[vindex]).trim();
}
output.printlnInstruction("dq", fasmNums, 0, 4);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
commdata[0] = "double8";
output.printHeader("; <fold ");
output.print(String.format(commstring, commdata));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = "d8";
operands[1] = writer.set(operandA).writeByte(0x40).get();
output.printlnInstruction("cons", operands, 0, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(Double8Storage storage = fldDouble8Storage, int slength = storage.length, int sindex = 0; sindex < slength; sindex++)
{
for(long8 value = Double8.toLong8Bits(storage[sindex]), int vindex = 0; vindex < 8; vindex++)
{
writer.set(fasmNums[vindex]).writeLong(value[vindex]).trim();
}
output.printlnInstruction("dq", fasmNums, 0, 8);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
commdata[0] = "float";
output.printHeader("; <fold ");
output.print(String.format(commstring, commdata));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = "f";
operands[1] = writer.set(operandA).writeByte(0x10).get();
output.printlnInstruction("cons", operands, 0, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(FloatStorage storage = fldFloatStorage, int slength = storage.length, int sindex = 0; sindex < slength; sindex++)
{
{
writer.set(fasmNums[0]).writeInt(Float.toIntBits(storage[sindex])).trim();
}
for(int vindex = 1; vindex < 4; vindex++)
{
writer.set(fasmNums[vindex]).writeDecimal(0).trim();
}
output.printlnInstruction("dd", fasmNums, 0, 4);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
commdata[0] = "float2";
output.printHeader("; <fold ");
output.print(String.format(commstring, commdata));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = "f2";
operands[1] = writer.set(operandA).writeByte(0x10).get();
output.printlnInstruction("cons", operands, 0, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(Float2Storage storage = fldFloat2Storage, int slength = storage.length, int sindex = 0; sindex < slength; sindex++)
{
for(int2 value = Float2.toInt2Bits(storage[sindex]), int vindex = 0; vindex < 2; vindex++)
{
writer.set(fasmNums[vindex]).writeInt(value[vindex]).trim();
}
for(int vindex = 2; vindex < 4; vindex++)
{
writer.set(fasmNums[vindex]).writeDecimal(0).trim();
}
output.printlnInstruction("dd", fasmNums, 0, 4);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
commdata[0] = "float4";
output.printHeader("; <fold ");
output.print(String.format(commstring, commdata));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = "f4";
operands[1] = writer.set(operandA).writeByte(0x10).get();
output.printlnInstruction("cons", operands, 0, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(Float4Storage storage = fldFloat4Storage, int slength = storage.length, int sindex = 0; sindex < slength; sindex++)
{
for(int4 value = Float4.toInt4Bits(storage[sindex]), int vindex = 0; vindex < 4; vindex++)
{
writer.set(fasmNums[vindex]).writeInt(value[vindex]).trim();
}
output.printlnInstruction("dd", fasmNums, 0, 4);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
commdata[0] = "float8";
output.printHeader("; <fold ");
output.print(String.format(commstring, commdata));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = "f8";
operands[1] = writer.set(operandA).writeByte(0x20).get();
output.printlnInstruction("cons", operands, 0, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(Float8Storage storage = fldFloat8Storage, int slength = storage.length, int sindex = 0; sindex < slength; sindex++)
{
for(int8 value = Float8.toInt8Bits(storage[sindex]), int vindex = 0; vindex < 8; vindex++)
{
writer.set(fasmNums[vindex]).writeInt(value[vindex]).trim();
}
output.printlnInstruction("dd", fasmNums, 0, 8);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
commdata[0] = "byte2";
output.printHeader("; <fold ");
output.print(String.format(commstring, commdata));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = "b2";
operands[1] = writer.set(operandA).writeByte(0x10).get();
output.printlnInstruction("cons", operands, 0, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(Byte2Storage storage = fldByte2Storage, int slength = storage.length, int sindex = 0; sindex < slength; sindex++)
{
for(byte2 value = storage[sindex], int vindex = 0; vindex < 2; vindex++)
{
writer.set(fasmNums[vindex]).writeByte(value[vindex]).trim();
}
for(int vindex = 2; vindex < 16; vindex++)
{
writer.set(fasmNums[vindex]).writeDecimal(0).trim();
}
output.printlnInstruction("db", fasmNums, 0, 16);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
commdata[0] = "byte4";
output.printHeader("; <fold ");
output.print(String.format(commstring, commdata));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = "b4";
operands[1] = writer.set(operandA).writeByte(0x10).get();
output.printlnInstruction("cons", operands, 0, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(Byte4Storage storage = fldByte4Storage, int slength = storage.length, int sindex = 0; sindex < slength; sindex++)
{
for(byte4 value = storage[sindex], int vindex = 0; vindex < 4; vindex++)
{
writer.set(fasmNums[vindex]).writeByte(value[vindex]).trim();
}
for(int vindex = 4; vindex < 16; vindex++)
{
writer.set(fasmNums[vindex]).writeDecimal(0).trim();
}
output.printlnInstruction("db", fasmNums, 0, 16);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
commdata[0] = "byte8";
output.printHeader("; <fold ");
output.print(String.format(commstring, commdata));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = "b8";
operands[1] = writer.set(operandA).writeByte(0x10).get();
output.printlnInstruction("cons", operands, 0, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(Byte8Storage storage = fldByte8Storage, int slength = storage.length, int sindex = 0; sindex < slength; sindex++)
{
for(byte8 value = storage[sindex], int vindex = 0; vindex < 8; vindex++)
{
writer.set(fasmNums[vindex]).writeByte(value[vindex]).trim();
}
for(int vindex = 8; vindex < 16; vindex++)
{
writer.set(fasmNums[vindex]).writeDecimal(0).trim();
}
output.printlnInstruction("db", fasmNums, 0, 16);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
commdata[0] = "short2";
output.printHeader("; <fold ");
output.print(String.format(commstring, commdata));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = "s2";
operands[1] = writer.set(operandA).writeByte(0x10).get();
output.printlnInstruction("cons", operands, 0, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(Short2Storage storage = fldShort2Storage, int slength = storage.length, int sindex = 0; sindex < slength; sindex++)
{
for(short2 value = storage[sindex], int vindex = 0; vindex < 2; vindex++)
{
writer.set(fasmNums[vindex]).writeShort(value[vindex]).trim();
}
for(int vindex = 2; vindex < 8; vindex++)
{
writer.set(fasmNums[vindex]).writeDecimal(0).trim();
}
output.printlnInstruction("dw", fasmNums, 0, 8);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
commdata[0] = "short4";
output.printHeader("; <fold ");
output.print(String.format(commstring, commdata));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = "s4";
operands[1] = writer.set(operandA).writeByte(0x10).get();
output.printlnInstruction("cons", operands, 0, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(Short4Storage storage = fldShort4Storage, int slength = storage.length, int sindex = 0; sindex < slength; sindex++)
{
for(short4 value = storage[sindex], int vindex = 0; vindex < 4; vindex++)
{
writer.set(fasmNums[vindex]).writeShort(value[vindex]).trim();
}
for(int vindex = 4; vindex < 8; vindex++)
{
writer.set(fasmNums[vindex]).writeDecimal(0).trim();
}
output.printlnInstruction("dw", fasmNums, 0, 8);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
commdata[0] = "short8";
output.printHeader("; <fold ");
output.print(String.format(commstring, commdata));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = "s8";
operands[1] = writer.set(operandA).writeByte(0x10).get();
output.printlnInstruction("cons", operands, 0, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(Short8Storage storage = fldShort8Storage, int slength = storage.length, int sindex = 0; sindex < slength; sindex++)
{
for(short8 value = storage[sindex], int vindex = 0; vindex < 8; vindex++)
{
writer.set(fasmNums[vindex]).writeShort(value[vindex]).trim();
}
output.printlnInstruction("dw", fasmNums, 0, 8);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
commdata[0] = "int2";
output.printHeader("; <fold ");
output.print(String.format(commstring, commdata));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = "i2";
operands[1] = writer.set(operandA).writeByte(0x10).get();
output.printlnInstruction("cons", operands, 0, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(Int2Storage storage = fldInt2Storage, int slength = storage.length, int sindex = 0; sindex < slength; sindex++)
{
for(int2 value = storage[sindex], int vindex = 0; vindex < 2; vindex++)
{
writer.set(fasmNums[vindex]).writeInt(value[vindex]).trim();
}
for(int vindex = 2; vindex < 4; vindex++)
{
writer.set(fasmNums[vindex]).writeDecimal(0).trim();
}
output.printlnInstruction("dd", fasmNums, 0, 4);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
commdata[0] = "int4";
output.printHeader("; <fold ");
output.print(String.format(commstring, commdata));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = "i4";
operands[1] = writer.set(operandA).writeByte(0x10).get();
output.printlnInstruction("cons", operands, 0, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(Int4Storage storage = fldInt4Storage, int slength = storage.length, int sindex = 0; sindex < slength; sindex++)
{
for(int4 value = storage[sindex], int vindex = 0; vindex < 4; vindex++)
{
writer.set(fasmNums[vindex]).writeInt(value[vindex]).trim();
}
output.printlnInstruction("dd", fasmNums, 0, 4);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
commdata[0] = "int8";
output.printHeader("; <fold ");
output.print(String.format(commstring, commdata));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = "i8";
operands[1] = writer.set(operandA).writeByte(0x20).get();
output.printlnInstruction("cons", operands, 0, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(Int8Storage storage = fldInt8Storage, int slength = storage.length, int sindex = 0; sindex < slength; sindex++)
{
for(int8 value = storage[sindex], int vindex = 0; vindex < 8; vindex++)
{
writer.set(fasmNums[vindex]).writeInt(value[vindex]).trim();
}
output.printlnInstruction("dd", fasmNums, 0, 8);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
commdata[0] = "long";
output.printHeader("; <fold ");
output.print(String.format(commstring, commdata));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = "l";
operands[1] = writer.set(operandA).writeByte(0x08).get();
output.printlnInstruction("cons", operands, 0, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(LongStorage storage = fldLongStorage, int slength = storage.length, int sindex = 0; sindex < slength; sindex++)
{
{
writer.set(fasmNums[0]).writeLong(storage[sindex]).trim();
}
output.printlnInstruction("dq", fasmNums, 0, 1);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
commdata[0] = "long2";
output.printHeader("; <fold ");
output.print(String.format(commstring, commdata));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = "l2";
operands[1] = writer.set(operandA).writeByte(0x10).get();
output.printlnInstruction("cons", operands, 0, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(Long2Storage storage = fldLong2Storage, int slength = storage.length, int sindex = 0; sindex < slength; sindex++)
{
for(long2 value = storage[sindex], int vindex = 0; vindex < 2; vindex++)
{
writer.set(fasmNums[vindex]).writeLong(value[vindex]).trim();
}
output.printlnInstruction("dq", fasmNums, 0, 2);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
commdata[0] = "long4";
output.printHeader("; <fold ");
output.print(String.format(commstring, commdata));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = "l4";
operands[1] = writer.set(operandA).writeByte(0x20).get();
output.printlnInstruction("cons", operands, 0, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(Long4Storage storage = fldLong4Storage, int slength = storage.length, int sindex = 0; sindex < slength; sindex++)
{
for(long4 value = storage[sindex], int vindex = 0; vindex < 4; vindex++)
{
writer.set(fasmNums[vindex]).writeLong(value[vindex]).trim();
}
output.printlnInstruction("dq", fasmNums, 0, 4);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
commdata[0] = "long8";
output.printHeader("; <fold ");
output.print(String.format(commstring, commdata));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = "l8";
operands[1] = writer.set(operandA).writeByte(0x40).get();
output.printlnInstruction("cons", operands, 0, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(Long8Storage storage = fldLong8Storage, int slength = storage.length, int sindex = 0; sindex < slength; sindex++)
{
for(long8 value = storage[sindex], int vindex = 0; vindex < 8; vindex++)
{
writer.set(fasmNums[vindex]).writeLong(value[vindex]).trim();
}
output.printlnInstruction("dq", fasmNums, 0, 8);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
commdata[0] = PACKNAME_LANG + "." + TYPENAME_STRING;
output.printHeader("; <fold ");
output.print(String.format(commstring, commdata));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = "s";
operands[1] = writer.set(operandA).writeByte(0x04).get();
output.printlnInstruction("cons", operands, 0, 2);
/* -------------------------------------------------------------------------------------------------------------------------------- */
StringStorage storage = fldStringStorage;
int slength = storage.length;
for(int slimit = slength - 1, int sindex = 0; sindex < slength; sindex++)
{
int slower = sindex & 0x07;
{
writer.set(fasmNums[slower]).writeString("-cons$s+").writeLabel(sindex).trim();
}
if(slower++ == 0x07 || sindex == slimit)
{
output.printlnInstruction("dd", fasmNums, 0, slower);
}
}
for(char[] chars = new char[0xffff], int sindex = 0; sindex < slength; sindex++)
{
String value = storage[sindex];
int vlength = value.length;
if(vlength > 0xffff)
{
throw new OutOfBoundsException(package.getResourceString("not-encodable.too-long-string"));
}
value.copyInto(chars, 0);
output.printLabel(writer.set(operandA).writeLabel(sindex).get());
for(int vlimit = vlength - 1, int vindex = -1; vindex < vlength; vindex++)
{
int vlower = vindex + 1 & 0x0f;
{
writer.set(fasmNums[vlower]).writeShort(vindex < 0 ? vlength : chars[vindex]).trim();
}
if(vlower++ == 0x0f || vindex == vlimit)
{
output.printlnInstruction("dw", fasmNums, 0, vlower);
}
}
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
protected void generateDebugInfoEntries(AssemblerSourcePrintStream output) {
AssemblerElementWriter writer = getAssemblerElementWriter();
char[] operandA = new char[0x0020];
char[] operandB = new char[0x0100];
char[] operandC = new char[0x0020];
CharArray[] operands = new CharArray[5];
StringStorage sources = fldDebugInfoSources;
StringStorage strings = fldDebugInfoStrings;
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printHeader("; <fold ");
output.print(package.getResourceString("comment.debug.entries"));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printlnInstruction("align_d", writer.set(operandA).writeByte(0x20).get());
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printlnLabel("dbgi$ient");
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(PackageArray packages = packages, int plength = packages.length, int pindex = 0; pindex < plength; pindex++)
{
for(Package pack = packages[pindex], int tlength = pack.length, int tindex = 0; tindex < tlength; tindex++)
{
Type type = pack[tindex];
if(!(type instanceof ClassType) || !type.isCompilable()) continue;
ClassType clas = (ClassType) type;
String classFullName = clas.fasmFullName;
for(int mlength = clas.length, int mindex = 0; mindex < mlength; mindex++)
{
Member member = clas[mindex];
if(!(member instanceof Callable) || member.isAbstract()) continue;
Callable method = (Callable) member;
String di = "dientry";
String name = method.specialSimpleName;
String methodFullName = method.fasmFullName;
int nlength = name.length - 1;
boolean isSpecial = nlength > 0 && name[0] == '<' && name[nlength] == '>';
strings.indexAcquire(name);
if(isSpecial) di = "dientry_s";
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printHeader("if(used ");
output.print(methodFullName);
output.print(") ; <fold ");
output.print(method.toString());
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
operands[0] = writer.set(operandA).writeLabel(sources.indexAcquire(clas.outputPath)).get();
operands[1] = classFullName;
operands[2] = !isSpecial ? (CharArray) name : writer.set(operandB).writeString(name, 1, nlength).get();
operands[3] = methodFullName;
operands[4] = "\\";
output.printlnInstruction(di, operands, 0, 5);
/* -------------------------------------------------------------------------------------------------------------------------------- */
Code code = method.code;
IntArray lines = code == null ? null : code.debugLineIndices;
int length = lines == null ? 0 : lines.length;
if(length <= 0)
{
operands[0] = writer.set(operandA).writeDecimal(0).get();
operands[1] = "";
operands[2] = ".D.IEND";
output.printlnContinuation(operands, 0, 3);
} else
{
operands[0] = operandA;
operands[1] = operandB;
operands[2] = operandC;
operands[3] = "\\";
for(int index = 0; index < length; )
{
writer.set(operandA).writeDecimal(lines[index] + 1).trim();
writer.set(operandB).writeLabel('D', index++).trim();
(index >= length ? writer.set(operandC).writeString(".D.IEND") : writer.set(operandC).writeLabel('D', index)).trim();
output.printlnContinuation(operands, 0, index >= length ? 3 : 4);
}
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("end if ; </fold>");
}
}
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printlnLabel(".$iend$");
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
protected void generateDebugInfoSources(AssemblerSourcePrintStream output) {
AssemblerElementWriter writer = getAssemblerElementWriter();
char[] operandA = new char[0x0020];
char[][] fasmNums = new char[0x0010][0x0020];
StringStorage sources = fldDebugInfoSources;
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printHeader("; <fold ");
output.print(package.getResourceString("comment.debug.sources"));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printlnInstruction("align_d", writer.set(operandA).writeByte(0x10).get());
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printLabel("dbgi$isrc");
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(char[] chars = new char[0xffff], int length = sources.length, int index = 0; index < length; index++)
{
String name = sources[index];
int nlength = name.length;
if(nlength > 0xffff) nlength = 0xffff;
name.getChars(0, nlength, chars, 0);
output.printLabel(writer.set(operandA).writeLabel(index).get());
for(int nlimit = nlength - 1, int nindex = -1; nindex < nlength; nindex++)
{
int nlower = nindex + 1 & 0x0f;
writer.set(fasmNums[nlower]).writeShort(nindex < 0 ? nlength : chars[nindex]).trim();
if(nlower++ == 0x0f || nindex == nlimit) output.printlnInstruction("dw", fasmNums, 0, nlower);
}
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printlnLabel(".$iend$");
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
protected void generateDebugInfoStrings(AssemblerSourcePrintStream output) {
AssemblerElementWriter writer = getAssemblerElementWriter();
char[] operandA = new char[0x0100];
StringStorage strings = fldDebugInfoStrings;
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printHeader("; <fold ");
output.print(package.getResourceString("comment.debug.strings"));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printlnInstruction("align_d", writer.set(operandA).writeByte(0x10).get());
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printLabel("dbgi$istr");
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(int length = strings.length, int index = 0; index < length; index++)
{
String name = strings[index];
int nlength = name.length - 1;
boolean isSpecial = nlength > 0 && name[0] == '<' && name[nlength] == '>';
output.printlnInstruction(isSpecial ? "distring_s" : "distring", !isSpecial ? (CharArray) name : writer.set(operandA).writeString(name, 1, nlength).get());
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printlnLabel(".$iend$");
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
protected void generateProgramme(AssemblerSourcePrintStream output) {
AssemblerElementWriter writer = getAssemblerElementWriter();
char[] operandA = new char[0xffff];
char[] operandB = new char[0xffff];
CharArray[] operands = new CharArray[] { operandA, operandB };
PackageArray packages = packages;
Hashtable resourcesTable = fldResourcesTable;
StringArray resourcesArray = fldResourcesArray;
int plength = packages.length;
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printHeader("; <fold ");
output.print(package.getResourceString("comment.header"));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printlnInstruction("include", "\u0022!format/!header.inc\u0022");
output.printlnInstruction("include", "\u0022!macro/!main.inc\u0022");
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printHeader("; <fold ");
output.print(package.getResourceString("comment.code"));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printlnInstruction("include", "\u0022!format/chapter/code.inc\u0022");
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printLabel("code$begin");
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printlnInstruction("include", "\u0022!proc/!main.inc\u0022");
output.printlnInstruction("include", "\u0022!inst/!main.inc\u0022");
/* -------------------------------------------------------------------------------------------------------------------------------- */
int codeLength = writer.set(operandA).writeString("\u0022code/").offset;
for(int pindex = 0; pindex < plength; pindex++)
{
Package pack = packages[pindex];
int pathLength = writer.set(operandA, codeLength).writeString(pack.fasmFileName).writeChar('/').offset;
for(int tlength = pack.length, int tindex = 0; tindex < tlength; tindex++)
{
Type type = pack[tindex];
if(type instanceof ClassType && (!(type instanceof ArrayType) || !((ClassType) type).getSuperclassType().isArray()))
{
output.printlnInstruction("include", writer.set(operandA, pathLength).writeString(type.fasmFileName).writeString(".inc\u0022").get());
}
}
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printlnLabel("code$end");
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printHeader("; <fold ");
output.print(package.getResourceString("comment.data"));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printlnInstruction("include", "\u0022!format/chapter/data.inc\u0022");
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printLabel("data$begin");
/* -------------------------------------------------------------------------------------------------------------------------------- */
int codeLength = writer.set(operandA).writeString("\u0022data/").offset;
for(int pindex = 0; pindex < plength; pindex++)
{
Package pack = packages[pindex];
int pathLength = writer.set(operandA, codeLength).writeString(pack.fasmFileName).writeChar('/').offset;
output.printlnInstruction("include", writer.set(operandA, pathLength).writeString("!package.inc\u0022").get());
for(int tlength = pack.length, int tindex = 0; tindex < tlength; tindex++)
{
Type type = pack[tindex];
if(type.isCompilable())
{
output.printlnInstruction("include", writer.set(operandA, pathLength).writeString(type.fasmFileName).writeString(".inc\u0022").get());
}
}
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printlnLabel("data$end");
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printHeader("; <fold ");
output.print(package.getResourceString("comment.constants"));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printlnInstruction("include", "\u0022!format/chapter/const.inc\u0022");
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printLabel("cons$begin");
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printlnInstruction("include", "\u0022const/proc.inc\u0022");
output.printlnInstruction("include", "\u0022const/inst.inc\u0022");
output.printlnInstruction("include", "\u0022const/prog.inc\u0022");
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printlnLabel("cons$end");
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printHeader("; <fold ");
output.print(package.getResourceString("comment.resources"));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printlnInstruction("include", "\u0022!format/chapter/rsrc.inc\u0022");
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printLabel("rsrc$begin");
/* -------------------------------------------------------------------------------------------------------------------------------- */
for(int length = resourcesArray.length, int index = 0; index < length; index++)
{
String name = resourcesArray[index];
String path = ((ResourceLocation) resourcesTable[name]).destinationPath;
writer.set(operandA).writeChar('\u0022').writeString(path).writeChar('\u0022').trim();
writer.set(operandB).writeChar('\u0022').writeString(name).writeChar('\u0022').trim();
output.printlnInstruction("avtrsrc", operands, 0, 2);
}
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printlnLabel("rsrc$end");
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printHeader("; <fold ");
output.print(package.getResourceString("comment.debug"));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printlnInstruction("include", "\u0022!format/chapter/dbgi.inc\u0022");
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printLabel("dbgi$begin");
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printlnInstruction("dbinfob", "\u0022AVTC 0.5 [2022-08-04]\u0022");
output.printlnInstruction("include", "\u0022dbgi/strings.inc\u0022");
output.printlnInstruction("include", "\u0022dbgi/sources.inc\u0022");
output.printlnInstruction("include", "\u0022dbgi/entries.inc\u0022");
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printlnLabel("dbgi$end");
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
{
output.println();
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printHeader("; <fold ");
output.print(package.getResourceString("comment.footer"));
output.println(">");
output.increaseMargin();
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.printlnInstruction("include", "\u0022!format/!footer.inc\u0022");
/* -------------------------------------------------------------------------------------------------------------------------------- */
output.decreaseMargin();
output.printlnHeader("; </fold>");
}
}
protected AssemblerElementWriter newAssemblerElementWriter() { return null; }
protected AssemblerSourcePrintStream newAssemblerSourcePrintStream() { return null; }
protected final AssemblerElementWriter getAssemblerElementWriter() { return fldGlobalWriter; }
private void findSourcesIn(Library library) throws IOException {
with(fldSourcesArray, fldSourcesTable, library.fileSystem)
{
String directoryPath = library.directoryPath + ASSEMBLER_SOURCE_PATH;
if(isObjectExists(directoryPath)) with(findFirst(directoryPath + "/")) try
{
do
{
String name = name;
if(!".".equals(name) && !"..".equals(name) && !"code".equals(name) && !"data".equals(name) && !"dbgi".equals(name))
{
if(directory)
{
findSourcesIn(library, name + "/");
} else
{
if(!containsKey(name)) append(name);
operator []=(name, library);
}
}
} while(findNext());
} finally
{
close();
}
}
}
private void findSourcesIn(Library library, String relativePath) throws IOException {
with(fldSourcesArray, fldSourcesTable, library.fileSystem.findFirst((new StringBuilder() + library.directoryPath + (ASSEMBLER_SOURCE_PATH + "/") + relativePath).toString()))
{
try
{
do
{
String name = name;
if(!".".equals(name) && !"..".equals(name))
{
if(directory)
{
findSourcesIn(library, (new StringBuilder() + relativePath + name + "/").toString());
} else
{
String path = relativePath + name;
if(!containsKey(path)) append(path);
operator []=(path, library);
}
}
} while(findNext());
} finally
{
close();
}
}
}
private void constantToFasmString(Constant value, char[] operand) {
if(value.isNull())
{
getAssemblerElementWriter().set(operand).writeString("null").trim();
return;
}
if(value.isReflective())
{
getAssemblerElementWriter().set(operand).writeString(((RequiredReflectItem) value.asObject()).fasmFullName).trim();
return;
}
if(value.isBoolean())
{
getAssemblerElementWriter().set(operand).writeString(value.asBoolean() ? "true" : "false").trim();
return;
}
switch(value.type.kind)
{
case REAL:
getAssemblerElementWriter().set(operand).writeChar('[').writeString("cons$e+").writeDecimal(fldRealStorage.indexAcquire(value.asReal()) * 10).writeChar(']').trim();
return;
case DOUBLE:
getAssemblerElementWriter().set(operand).writeChar('[').writeString("cons$d+").writeOffset(fldDoubleStorage.indexAcquire(value.asDouble()) << 4).writeChar(']').trim();
return;
case DOUBLE2:
getAssemblerElementWriter().set(operand).writeChar('[').writeString("cons$d2+").writeOffset(fldDouble2Storage.indexAcquire(value.asDouble2()) << 4).writeChar(']').trim();
return;
case DOUBLE4:
getAssemblerElementWriter().set(operand).writeChar('[').writeString("cons$d4+").writeOffset(fldDouble4Storage.indexAcquire(value.asDouble4()) << 5).writeChar(']').trim();
return;
case DOUBLE8:
getAssemblerElementWriter().set(operand).writeChar('[').writeString("cons$d8+").writeOffset(fldDouble8Storage.indexAcquire(value.asDouble8()) << 6).writeChar(']').trim();
return;
case FLOAT:
getAssemblerElementWriter().set(operand).writeChar('[').writeString("cons$f+").writeOffset(fldFloatStorage.indexAcquire(value.asFloat()) << 4).writeChar(']').trim();
return;
case FLOAT2:
getAssemblerElementWriter().set(operand).writeChar('[').writeString("cons$f2+").writeOffset(fldFloat2Storage.indexAcquire(value.asFloat2()) << 4).writeChar(']').trim();
return;
case FLOAT4:
getAssemblerElementWriter().set(operand).writeChar('[').writeString("cons$f4+").writeOffset(fldFloat4Storage.indexAcquire(value.asFloat4()) << 4).writeChar(']').trim();
return;
case FLOAT8:
getAssemblerElementWriter().set(operand).writeChar('[').writeString("cons$f8+").writeOffset(fldFloat8Storage.indexAcquire(value.asFloat8()) << 5).writeChar(']').trim();
return;
case BYTE2:
getAssemblerElementWriter().set(operand).writeChar('[').writeString("cons$b2+").writeOffset(fldByte2Storage.indexAcquire(value.asByte2()) << 4).writeChar(']').trim();
return;
case BYTE4:
getAssemblerElementWriter().set(operand).writeChar('[').writeString("cons$b4+").writeOffset(fldByte4Storage.indexAcquire(value.asByte4()) << 4).writeChar(']').trim();
return;
case BYTE8:
getAssemblerElementWriter().set(operand).writeChar('[').writeString("cons$b8+").writeOffset(fldByte8Storage.indexAcquire(value.asByte8()) << 4).writeChar(']').trim();
return;
case SHORT2:
getAssemblerElementWriter().set(operand).writeChar('[').writeString("cons$s2+").writeOffset(fldShort2Storage.indexAcquire(value.asShort2()) << 4).writeChar(']').trim();
return;
case SHORT4:
getAssemblerElementWriter().set(operand).writeChar('[').writeString("cons$s4+").writeOffset(fldShort4Storage.indexAcquire(value.asShort4()) << 4).writeChar(']').trim();
return;
case SHORT8:
getAssemblerElementWriter().set(operand).writeChar('[').writeString("cons$s8+").writeOffset(fldShort8Storage.indexAcquire(value.asShort8()) << 4).writeChar(']').trim();
return;
case INT2:
getAssemblerElementWriter().set(operand).writeChar('[').writeString("cons$i2+").writeOffset(fldInt2Storage.indexAcquire(value.asInt2()) << 4).writeChar(']').trim();
return;
case INT4:
getAssemblerElementWriter().set(operand).writeChar('[').writeString("cons$i4+").writeOffset(fldInt4Storage.indexAcquire(value.asInt4()) << 4).writeChar(']').trim();
return;
case INT8:
getAssemblerElementWriter().set(operand).writeChar('[').writeString("cons$i8+").writeOffset(fldInt8Storage.indexAcquire(value.asInt8()) << 5).writeChar(']').trim();
return;
case LONG:
getAssemblerElementWriter().set(operand).writeChar('[').writeString("cons$l+").writeOffset(fldLongStorage.indexAcquire(value.asLong()) << 3).writeChar(']').trim();
return;
case LONG2:
getAssemblerElementWriter().set(operand).writeChar('[').writeString("cons$l2+").writeOffset(fldLong2Storage.indexAcquire(value.asLong2()) << 4).writeChar(']').trim();
return;
case LONG4:
getAssemblerElementWriter().set(operand).writeChar('[').writeString("cons$l4+").writeOffset(fldLong4Storage.indexAcquire(value.asLong4()) << 5).writeChar(']').trim();
return;
case LONG8:
getAssemblerElementWriter().set(operand).writeChar('[').writeString("cons$l8+").writeOffset(fldLong8Storage.indexAcquire(value.asLong8()) << 6).writeChar(']').trim();
return;
default:
int ivalue = value.asInt();
(ivalue >= 0 ? getAssemblerElementWriter().set(operand).writeInt(ivalue) : getAssemblerElementWriter().set(operand).writeChar('-').writeInt(-ivalue)).trim();
}
}
private String additionalToFasmString(TypedItem item, char[] operand) {
if(item == null)
{
operand.length = 0;
return "";
}
if(item instanceof Local)
{
getAssemblerElementWriter().set(operand).writeString(item.fasmSimpleName).trim();
return "_l";
}
if(item instanceof Field)
{
getAssemblerElementWriter().set(operand).writeChar('[').writeString(((Field) item).fasmFullName).writeChar(']').trim();
return "_g";
}
if(item instanceof Constant)
{
constantToFasmString((Constant) item, operand);
return "_g";
}
throw new IllegalArgumentException(String.format(avt.lang.package.getResourceString("illegal-argument"), new Object[] { "item" }));
}
private String additionalToFasmString(TypedItem item, char[] operand, Hashtable refsLocalTable) {
if(item == null)
{
operand.length = 0;
return "";
}
if(item instanceof Local)
{
String name = item.fasmSimpleName;
if(!item.type.isPrimitive() && refsLocalTable.containsKey(name))
{
getAssemblerElementWriter().set(operand).writeChar('$').writeString(name).trim();
} else
{
getAssemblerElementWriter().set(operand).writeString(name).trim();
}
return "_l";
}
if(item instanceof Field)
{
getAssemblerElementWriter().set(operand).writeChar('[').writeString(((Field) item).fasmFullName).writeChar(']').trim();
return "_g";
}
if(item instanceof Constant)
{
constantToFasmString((Constant) item, operand);
return "_g";
}
throw new IllegalArgumentException(String.format(avt.lang.package.getResourceString("illegal-argument"), new Object[] { "item" }));
}
}
helper AssemblerSourceGeneratorClassType: ClassType
{
public boolean hasOverriddingMembersFor(ClassType superservice, boolean isSuperclassesLook) {
for(int place = isSuperclassesLook ? Method.TYPE | Method.SUPERCLASSES : Method.TYPE_ONLY, int index = superservice.length; index-- > 0; )
{
ProgrammeItem member = superservice[index];
if(!(member instanceof OverriddableMember)) continue;
/* переопределённый член */ OverriddableMember overridden = (OverriddableMember) member;
if(overridden.visibility < PROTECTED || overridden.isAbstract()) continue;
/* переопределяющий член */ OverriddableMember overridding = overridden.overridesIn(this, place);
if(overridding != null && overridding.visibility >= PROTECTED) return true;
}
return false;
}
}