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;
+    }
+}