Mercurial > hg > truffle
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 } |