/** * Generate code to fetch all the arguments needed for a given operand number and encoding. The * different argument encodings of the Assembler need different arguments to be passed to the * emitter function. For instance, a register-displacement mode operand needs to be given a base * register and an immediate displacement. This function generates the appropriate arguments given * the operand number and encoding; that is, it generates reads of the appropriate Instruction * argument and fetches of the appropriate pieces of information from the operand. * * @param argNumber The argument being generated. * @param argEcoding The encoding to use. */ private static void emitArgs(int argNumber, ArgumentType argEncoding) { String op = getOperand(argNumber); switch (argEncoding) { case LabelOrImmediate: emit("getImm(" + op + "), getLabel(" + op + ")"); break; case RegisterDisplacement: emit("getBase(" + op + "), getDisp(" + op + ")"); break; case Absolute: emit("getDisp(" + op + ").toWord().toAddress()"); break; case RegisterOffset: emit("getIndex(" + op + "), getScale(" + op + "), getDisp(" + op + ")"); break; case RegisterIndexed: emit( "getBase(" + op + "), getIndex(" + op + "), getScale(" + op + "), getDisp(" + op + ")"); break; case RegisterIndirect: emit("getBase(" + op + ")"); break; default: emit("get" + argEncoding.getOptName() + "(" + op + ")"); } }
/** * For a given string representing a valid operand encoding for the Assembler, return the * corresponding Assembler constant. This function only looks for encodings of operand types, and * will not accept strings that correspond to size encodings. * * @param str A valid Assembler encoding of operand type * @return The Assembler constant corresponding to str, or -1 if none */ private static ArgumentType getEncoding(String str, Class<?> type) { if (str.equals("Reg")) { if (type == null) { throw new Error("Unable to encode Reg with no type information"); } String typeName = type.getName(); str = typeName.substring(typeName.lastIndexOf('$') + 1) + "_Reg"; } for (ArgumentType arg : ArgumentType.values()) { if (arg.getOptName().equals(str)) { return arg; } } throw new Error( "Unable to encode the argument " + str + " of type " + type + " as a valid argument type"); }
/** * Given an operand number and an encoding, generate a test to determine whether the given operand * matches the encoding. That is, generate code to the Assembler that examines a given operand of * the current Instruction, and determines whether it is of the type encoded by the given * encoding. This is used to generate the if statements of the dispatch functions for each opt * compiler opcode. * * @param argNumber The argument to examine * @param argEncoding The encoding for which to check */ private static void emitTest(int argNumber, ArgumentType argEncoding) { if (argEncoding.isSize()) emit("is" + argEncoding.getOptName() + "(inst)"); else emit("is" + argEncoding.getOptName() + "(" + getOperand(argNumber) + ")"); }