/** * Create an EmitterDescriptor for the given methodName. This conmstructor creates a descriptor * that represents explicitly the types and size of the operands of the given emit* method. This * constructor encapsulate the logic to parse the given method name into the appropriate * explicit representation. */ EmitterDescriptor(String methodName, Class<?>[] argTypes) { StringTokenizer toks = new StringTokenizer(methodName, "_"); toks.nextElement(); // first element is emitXXX; args = new ArgumentType[toks.countTokens()]; ArgumentType size = null; int count = 0; int argTypeNum = 0; for (int i = 0; i < args.length; i++) { String cs = toks.nextToken(); ArgumentType code; if (argTypeNum < argTypes.length) { code = getEncoding(cs, argTypes[argTypeNum]); } else { code = getEncoding(cs, null); } argTypeNum += code.getParameters(); if (DEBUG) { System.err.println(methodName + "[" + i + "] is " + code + " for " + cs); } args[count] = code; count++; if (code.isSize()) { size = code; count--; } } this.size = size; this.count = count; }
/** * This method checks whether the emit* method represented by this EmitterDescriptor expects the * argument type represented by enc as its argument'th operand. If enc is an operand type * encoding, this method checks wether the given argument is of the appropriate type. If enc is * an operand size encoding, the argument parameter is ignored, and this method checks whether * the emit* method represented operates upon data of the desired size. * * <p><EM>See the descriptions of the GenerateAssembler constants:</EM> * * <DL> * <DT><EM>Operand types</EM> <DI> * <UL> * <LI>{@link #Immediate} * <LI>{@link #Label} * <LI>{@link #LabelOrImmediate} * <LI>{@link #Absolute} * <LI>{@link #Register} * <LI>{@link #RegisterIndirect} * <LI>{@link #RegisterOffset} * <LI>{@link #RegisterIndexed} * </UL> * <DT><EM>Data size</EM> * <UL> * <LI>{@link #Byte} * <LI>{@link #Word} * <LI>{@link #Quad} * </UL> * </DL> * * <p> * * @param argument The operand number examined * @param enc The argument type queried, as encoded as one of the operand type constants used * throughout GenerateAssembler. * @return True if this method expects an argument type encoded by enc as its argument'th * operand, and false otherwise. */ boolean argMatchesEncoding(int argument, ArgumentType enc) { if (!enc.isSize()) return (count > argument) && args[argument] == enc; else return size == enc; }
/** * 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) + ")"); }