comparison 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
comparison
equal deleted inserted replaced
3732:3e2e8b8abdaf 3733:e233f5660da4
1 /*
2 * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package com.sun.max.asm.gen.risc;
24
25 import static com.sun.max.asm.gen.LabelParameter.*;
26
27 import java.util.*;
28
29 import com.sun.max.*;
30 import com.sun.max.asm.*;
31 import com.sun.max.asm.gen.*;
32 import com.sun.max.asm.gen.risc.bitRange.*;
33 import com.sun.max.asm.gen.risc.field.*;
34 import com.sun.max.io.*;
35 import com.sun.max.lang.*;
36 import com.sun.max.program.*;
37
38 /**
39 */
40 public abstract class RiscAssemblerGenerator<Template_Type extends RiscTemplate> extends AssemblerGenerator<Template_Type> {
41
42 protected RiscAssemblerGenerator(Assembly<Template_Type> assembly) {
43 super(assembly, false);
44 }
45
46 private String encode(OperandField operandField, String val) {
47 String value = val;
48 // Convert the argument value to the operand value
49 if (operandField.zeroes() != 0) {
50 value = "(" + value + " >> " + operandField.zeroes() + ")";
51 }
52 return operandField.bitRange().encodingString(value, operandField.isSigned(), false);
53 }
54
55 @Override
56 protected int printMethod(IndentWriter writer, Template_Type template) {
57 final int startLineCount = writer.lineCount();
58 writer.print("public void ");
59 writer.print(template.assemblerMethodName() + "(");
60 writer.print(formatParameterList("final ", template.parameters(), false));
61 writer.println(") {");
62 writer.indent();
63 writer.println("int instruction = " + Ints.toHexLiteral(template.opcode()) + ";");
64
65 // Print argument constraint checking statements
66 final List<InstructionConstraint> constraints = template.instructionDescription().constraints();
67 for (InstructionConstraint constraint : constraints) {
68 if (!(constraint instanceof TestOnlyInstructionConstraint)) {
69 final String constraintExpression = constraint.asJavaExpression();
70 writer.println("checkConstraint(" + constraintExpression + ", \"" + constraintExpression + "\");");
71 }
72 }
73
74 for (OperandField operandField : template.operandFields()) {
75 if (operandField instanceof InputOperandField) {
76 continue;
77 }
78 writer.println("instruction |= " + encode(operandField, operandField.valueString()) + ";");
79 }
80
81 writer.println("emitInt(instruction);");
82 writer.outdent();
83 writer.println("}");
84 return writer.lineCount() - startLineCount;
85 }
86
87 @Override
88 protected void printLabelMethod(final IndentWriter indentWriter, final Template_Type labelTemplate, String assemblerClassName) {
89 final List<Parameter> parameters = getParameters(labelTemplate, true);
90 final InstructionWithLabelSubclass labelInstructionSubclass = new InstructionWithLabelSubclass(labelTemplate, InstructionWithOffset.class, "");
91 printLabelMethodHelper(indentWriter, labelTemplate, parameters, 4, assemblerClassName, labelInstructionSubclass);
92 }
93
94 /**
95 * Prints the reference to the raw method from which a synthetic method was defined.
96 */
97 @Override
98 protected void printExtraMethodJavadoc(IndentWriter writer, Template_Type template, List<String> extraLinks, boolean forLabelAssemblerMethod) {
99 if (template.instructionDescription().isSynthetic()) {
100 final RiscTemplate syntheticTemplate = template;
101 final RiscTemplate rawTemplate = syntheticTemplate.synthesizedFrom();
102 final List<? extends Parameter> parameters = getParameters(rawTemplate, forLabelAssemblerMethod);
103 final String ref = rawTemplate.internalName() + "(" + formatParameterList("", parameters, true) + ")";
104 writer.println(" * <p>");
105 writer.print(" * This is a synthetic instruction equivalent to: {@code " + rawTemplate.internalName() + "(");
106 extraLinks.add("#" + ref);
107
108 boolean firstOperand = true;
109 for (OperandField rawOperand : rawTemplate.operandFields()) {
110 if (!firstOperand) {
111 writer.print(", ");
112 }
113 writer.print(getRawOperandReplacement(syntheticTemplate, rawTemplate, rawOperand, forLabelAssemblerMethod));
114 firstOperand = false;
115 }
116
117 writer.println(")}");
118 }
119 }
120
121 /**
122 * Gets the expression in terms of the parameters and opcode of a synthetic instruction that replaces a parameter of
123 * the raw instruction from which the synthetic operand was derived.
124 *
125 * @param syntheticTemplate
126 * the synthetic instruction
127 * @param rawTemplate
128 * the raw instruction from which {@code syntheticTemplate} was derived
129 * @param rawOperand
130 * a parameter of {@code rawTemplate}
131 */
132 private String getRawOperandReplacement(RiscTemplate syntheticTemplate, RiscTemplate rawTemplate, OperandField rawOperand, boolean forLabelAssemblerMethod) {
133 if (Utils.indexOfIdentical(syntheticTemplate.operandFields(), rawOperand) != -1) {
134 if (rawOperand instanceof OffsetParameter && forLabelAssemblerMethod) {
135 return LABEL.variableName();
136 }
137 return rawOperand.variableName();
138 }
139
140 final int rawOperandMask = rawOperand.bitRange().instructionMask();
141 String expression = null;
142 if ((syntheticTemplate.opcodeMask() & rawOperandMask) != 0) {
143 // Some or all bits of the raw operand are encoded as part of the synthetic instruction opcode
144 final Argument value = rawOperand.disassemble(syntheticTemplate.opcode());
145 assert value != null;
146 if (value instanceof SymbolicArgument) {
147 expression = ((SymbolicArgument) value).name();
148 } else if (value instanceof Enum) {
149 expression = ((Enum) value).name();
150 } else if (value instanceof ImmediateArgument) {
151 expression = Long.toString(((ImmediateArgument) value).asLong());
152 } else {
153 throw ProgramError.unexpected("unknown type of disassembled value: " + value.getClass().getName());
154 }
155 }
156 if ((syntheticTemplate.opcodeMask() & rawOperandMask) != rawOperandMask) {
157 // Some or all bits of the raw operand are given as a parameter of the synthetic instruction
158 for (OperandField syntheticOperand : syntheticTemplate.operandFields()) {
159 final int syntheticOperandMask = syntheticOperand.bitRange().instructionMask();
160 if ((syntheticOperandMask & rawOperandMask) != 0) {
161 final String term;
162 if (syntheticOperand.boundTo() != null) {
163 term = syntheticOperand.boundTo().valueString();
164 } else {
165 assert (syntheticOperandMask & rawOperandMask) == syntheticOperandMask :
166 "cannot handle synthetic parameter that defines bits that are not a subset of bits defined by a raw parameter";
167 final BitRange subFieldRange = syntheticOperand.bitRange().move(false, syntheticOperand.bitRange().numberOfLessSignificantBits());
168 final int shift = syntheticOperand.bitRange().numberOfLessSignificantBits() - rawOperand.bitRange().numberOfLessSignificantBits();
169 final String value = syntheticOperand.variableName();
170 final String assembledSubField = subFieldRange.encodingString(value, syntheticOperand.isSigned(), true);
171 if (shift != 0) {
172 term = "(" + assembledSubField + " * " + (1 << shift) + ")";
173 } else {
174 term = assembledSubField;
175 }
176 }
177
178 if (expression != null && !expression.equals("0")) {
179 expression += " | " + term;
180 } else {
181 expression = term;
182 }
183 }
184 }
185 }
186 assert expression != null;
187 return expression;
188 }
189 }