Mercurial > hg > truffle
diff graal/com.oracle.max.asmdis/src/com/sun/max/asm/gen/risc/RiscAssemblerGenerator.java @ 3733:e233f5660da4
Added Java files from Maxine project.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Sat, 17 Dec 2011 19:59:18 +0100 |
parents | |
children | bc8527f3071c |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.asmdis/src/com/sun/max/asm/gen/risc/RiscAssemblerGenerator.java Sat Dec 17 19:59:18 2011 +0100 @@ -0,0 +1,189 @@ +/* + * 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 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 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; + } +}