Mercurial > hg > truffle
view graal/com.oracle.max.asmdis/src/com/sun/max/asm/gen/risc/RiscAssemblerGenerator.java @ 4150:c78bace5086a
start work on integrating old hooks into mx, work on sanity checks
introduce a DB class to access the bench DB in an easier way (create benchmarks and benchmark values automatically in the DB)
author | Gilles Duboscq <gilles.m.duboscq@gmail.com> |
---|---|
date | Tue, 20 Dec 2011 15:34:43 +0100 |
parents | bc8527f3071c |
children |
line wrap: on
line source
/* * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.sun.max.asm.gen.risc; import static com.sun.max.asm.gen.LabelParameter.*; import java.util.*; import com.sun.max.*; import com.sun.max.asm.*; import com.sun.max.asm.gen.*; import com.sun.max.asm.gen.risc.bitRange.*; import com.sun.max.asm.gen.risc.field.*; import com.sun.max.io.*; import com.sun.max.lang.*; import com.sun.max.program.*; /** */ public abstract class RiscAssemblerGenerator<Template_Type extends RiscTemplate> extends AssemblerGenerator<Template_Type> { protected RiscAssemblerGenerator(Assembly<Template_Type> assembly) { super(assembly, false); } private static String encode(OperandField operandField, String val) { String value = val; // Convert the argument value to the operand value if (operandField.zeroes() != 0) { value = "(" + value + " >> " + operandField.zeroes() + ")"; } return operandField.bitRange().encodingString(value, operandField.isSigned(), false); } @Override protected int printMethod(IndentWriter writer, Template_Type template) { final int startLineCount = writer.lineCount(); writer.print("public void "); writer.print(template.assemblerMethodName() + "("); writer.print(formatParameterList("final ", template.parameters(), false)); writer.println(") {"); writer.indent(); writer.println("int instruction = " + Ints.toHexLiteral(template.opcode()) + ";"); // Print argument constraint checking statements final List<InstructionConstraint> constraints = template.instructionDescription().constraints(); for (InstructionConstraint constraint : constraints) { if (!(constraint instanceof TestOnlyInstructionConstraint)) { final String constraintExpression = constraint.asJavaExpression(); writer.println("checkConstraint(" + constraintExpression + ", \"" + constraintExpression + "\");"); } } for (OperandField operandField : template.operandFields()) { if (operandField instanceof InputOperandField) { continue; } writer.println("instruction |= " + encode(operandField, operandField.valueString()) + ";"); } writer.println("emitInt(instruction);"); writer.outdent(); writer.println("}"); return writer.lineCount() - startLineCount; } @Override protected void printLabelMethod(final IndentWriter indentWriter, final Template_Type labelTemplate, String assemblerClassName) { final List<Parameter> parameters = getParameters(labelTemplate, true); final InstructionWithLabelSubclass labelInstructionSubclass = new InstructionWithLabelSubclass(labelTemplate, InstructionWithOffset.class, ""); printLabelMethodHelper(indentWriter, labelTemplate, parameters, 4, assemblerClassName, labelInstructionSubclass); } /** * Prints the reference to the raw method from which a synthetic method was defined. */ @Override protected void printExtraMethodJavadoc(IndentWriter writer, Template_Type template, List<String> extraLinks, boolean forLabelAssemblerMethod) { if (template.instructionDescription().isSynthetic()) { final RiscTemplate syntheticTemplate = template; final RiscTemplate rawTemplate = syntheticTemplate.synthesizedFrom(); final List<? extends Parameter> parameters = getParameters(rawTemplate, forLabelAssemblerMethod); final String ref = rawTemplate.internalName() + "(" + formatParameterList("", parameters, true) + ")"; writer.println(" * <p>"); writer.print(" * This is a synthetic instruction equivalent to: {@code " + rawTemplate.internalName() + "("); extraLinks.add("#" + ref); boolean firstOperand = true; for (OperandField rawOperand : rawTemplate.operandFields()) { if (!firstOperand) { writer.print(", "); } writer.print(getRawOperandReplacement(syntheticTemplate, rawTemplate, rawOperand, forLabelAssemblerMethod)); firstOperand = false; } writer.println(")}"); } } /** * Gets the expression in terms of the parameters and opcode of a synthetic instruction that replaces a parameter of * the raw instruction from which the synthetic operand was derived. * * @param syntheticTemplate * the synthetic instruction * @param rawTemplate * the raw instruction from which {@code syntheticTemplate} was derived * @param rawOperand * a parameter of {@code rawTemplate} */ private static String getRawOperandReplacement(RiscTemplate syntheticTemplate, RiscTemplate rawTemplate, OperandField rawOperand, boolean forLabelAssemblerMethod) { if (Utils.indexOfIdentical(syntheticTemplate.operandFields(), rawOperand) != -1) { if (rawOperand instanceof OffsetParameter && forLabelAssemblerMethod) { return LABEL.variableName(); } return rawOperand.variableName(); } final int rawOperandMask = rawOperand.bitRange().instructionMask(); String expression = null; if ((syntheticTemplate.opcodeMask() & rawOperandMask) != 0) { // Some or all bits of the raw operand are encoded as part of the synthetic instruction opcode final Argument value = rawOperand.disassemble(syntheticTemplate.opcode()); assert value != null; if (value instanceof SymbolicArgument) { expression = ((SymbolicArgument) value).name(); } else if (value instanceof Enum) { expression = ((Enum) value).name(); } else if (value instanceof ImmediateArgument) { expression = Long.toString(((ImmediateArgument) value).asLong()); } else { throw ProgramError.unexpected("unknown type of disassembled value: " + value.getClass().getName()); } } if ((syntheticTemplate.opcodeMask() & rawOperandMask) != rawOperandMask) { // Some or all bits of the raw operand are given as a parameter of the synthetic instruction for (OperandField syntheticOperand : syntheticTemplate.operandFields()) { final int syntheticOperandMask = syntheticOperand.bitRange().instructionMask(); if ((syntheticOperandMask & rawOperandMask) != 0) { final String term; if (syntheticOperand.boundTo() != null) { term = syntheticOperand.boundTo().valueString(); } else { assert (syntheticOperandMask & rawOperandMask) == syntheticOperandMask : "cannot handle synthetic parameter that defines bits that are not a subset of bits defined by a raw parameter"; final BitRange subFieldRange = syntheticOperand.bitRange().move(false, syntheticOperand.bitRange().numberOfLessSignificantBits()); final int shift = syntheticOperand.bitRange().numberOfLessSignificantBits() - rawOperand.bitRange().numberOfLessSignificantBits(); final String value = syntheticOperand.variableName(); final String assembledSubField = subFieldRange.encodingString(value, syntheticOperand.isSigned(), true); if (shift != 0) { term = "(" + assembledSubField + " * " + (1 << shift) + ")"; } else { term = assembledSubField; } } if (expression != null && !expression.equals("0")) { expression += " | " + term; } else { expression = term; } } } } assert expression != null; return expression; } }