Mercurial > hg > truffle
comparison graal/com.oracle.max.asmdis/src/com/sun/max/asm/gen/cisc/x86/X86AssemblerGenerator.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.cisc.x86; | |
24 | |
25 import java.io.*; | |
26 import java.util.*; | |
27 | |
28 import com.sun.max.*; | |
29 import com.sun.max.asm.*; | |
30 import com.sun.max.asm.gen.*; | |
31 import com.sun.max.io.*; | |
32 import com.sun.max.lang.*; | |
33 import com.sun.max.program.*; | |
34 import com.sun.max.program.option.*; | |
35 | |
36 /** | |
37 */ | |
38 public abstract class X86AssemblerGenerator<Template_Type extends X86Template> extends AssemblerGenerator<Template_Type> { | |
39 | |
40 private final Option<Boolean> support16BitAddressesOption = options.newBooleanOption("a16", false, "Enables 16 bit addressing."); | |
41 private final Option<Boolean> support16BitOffsetOption = options.newBooleanOption("d16", false, "Enables 16 bit offsets."); | |
42 | |
43 private final WordWidth addressWidth; | |
44 | |
45 protected X86AssemblerGenerator(Assembly<Template_Type> assembly, WordWidth addressWidth) { | |
46 super(assembly, true); | |
47 this.addressWidth = addressWidth; | |
48 } | |
49 | |
50 @Override | |
51 public X86Assembly<Template_Type> assembly() { | |
52 final Class<X86Assembly<Template_Type>> type = null; | |
53 return Utils.cast(type, super.assembly()); | |
54 } | |
55 | |
56 public WordWidth addressWidth() { | |
57 return addressWidth; | |
58 } | |
59 | |
60 @Override | |
61 protected void generate() { | |
62 if (support16BitAddressesOption.getValue() != null && support16BitAddressesOption.getValue()) { | |
63 X86Assembly.support16BitAddresses(); | |
64 } | |
65 if (support16BitOffsetOption.getValue() != null && support16BitOffsetOption.getValue()) { | |
66 X86Assembly.support16BitOffsets(); | |
67 } | |
68 super.generate(); | |
69 } | |
70 | |
71 protected X86Parameter getParameter(Template_Type template, Class parameterType) { | |
72 for (X86Parameter parameter : template.parameters()) { | |
73 if (parameter.type() == parameterType) { | |
74 return parameter; | |
75 } | |
76 } | |
77 throw ProgramError.unexpected("found no parameter of type: " + parameterType); | |
78 } | |
79 | |
80 private void printCallWithByteDisplacement(IndentWriter writer, Template_Type template, Class argumentType) { | |
81 final Template_Type modVariantTemplate = X86Assembly.getModVariantTemplate(assembly().templates(), template, argumentType); | |
82 final String subroutineName = makeSubroutine(modVariantTemplate); | |
83 writer.print(subroutineName + "("); | |
84 if (template.opcode2() != null) { | |
85 writer.print(OPCODE2_VARIABLE_NAME); | |
86 } else { | |
87 writer.print(OPCODE1_VARIABLE_NAME); | |
88 } | |
89 if (template.modRMGroupOpcode() != null) { | |
90 writer.print(", " + MODRM_GROUP_OPCODE_VARIABLE_NAME); | |
91 } | |
92 for (X86Parameter parameter : template.parameters()) { | |
93 if (parameter.type() == argumentType) { | |
94 writer.print(", (byte) 0"); | |
95 } | |
96 writer.print(", " + parameter.variableName()); | |
97 } | |
98 writer.println(");"); | |
99 } | |
100 | |
101 protected String asIdentifier(EnumerableArgument argument) { | |
102 return argument.getClass().getSimpleName() + "." + argument.name(); | |
103 } | |
104 | |
105 protected <Argument_Type extends Enum<Argument_Type> & EnumerableArgument<Argument_Type>> void printModVariant(IndentWriter writer, final Template_Type template, Argument_Type... arguments) { | |
106 final Class argumentType = arguments[0].getClass(); | |
107 final X86Parameter parameter = getParameter(template, argumentType); | |
108 writer.print("if ("); | |
109 String separator = ""; | |
110 for (EnumerableArgument argument : arguments) { | |
111 writer.print(separator + parameter.variableName() + " == " + asIdentifier(argument)); | |
112 separator = " || "; | |
113 } | |
114 writer.println(") {"); | |
115 writer.indent(); | |
116 printCallWithByteDisplacement(writer, template, argumentType); | |
117 writer.println("return;"); | |
118 writer.outdent(); | |
119 writer.println("}"); | |
120 } | |
121 | |
122 protected abstract void printModVariants(IndentWriter writer, Template_Type template); | |
123 | |
124 protected void printPrefixes(IndentWriter writer, Template_Type template) { | |
125 if (template.addressSizeAttribute() != addressWidth()) { | |
126 emitByte(writer, X86Opcode.ADDRESS_SIZE.byteValue()); | |
127 writer.println(" // address size prefix"); | |
128 } | |
129 if (template.operandSizeAttribute() == WordWidth.BITS_16) { | |
130 emitByte(writer, X86Opcode.OPERAND_SIZE.byteValue()); | |
131 writer.println(" // operand size prefix"); | |
132 } | |
133 if (template.instructionSelectionPrefix() != null) { | |
134 emitByte(writer, template.instructionSelectionPrefix().byteValue()); | |
135 writer.println(" // instruction selection prefix"); | |
136 } | |
137 } | |
138 | |
139 private void printOpcode(IndentWriter writer, Template_Type template, String opcodeVarName, final ParameterPlace parameterPlace32, ParameterPlace parameterPlace64) { | |
140 String comment = ""; | |
141 String opcodeVariableName = opcodeVarName; | |
142 for (X86Parameter parameter : template.parameters()) { | |
143 if (parameter.place() == parameterPlace32) { | |
144 opcodeVariableName += " + " + parameter.valueString(); | |
145 comment = " // " + parameterPlace32.name().toLowerCase(); | |
146 } else if (parameter.place() == parameterPlace64) { | |
147 opcodeVariableName += " + (" + parameter.valueString() + "& 7)"; | |
148 comment = " // " + parameterPlace64.name().toLowerCase(); | |
149 } | |
150 } | |
151 if (comment.length() == 0) { | |
152 emitByte(writer, opcodeVariableName); | |
153 writer.println(); | |
154 } else { | |
155 emitByte(writer, "(byte) (" + opcodeVariableName + ")"); | |
156 writer.println(comment); | |
157 } | |
158 } | |
159 | |
160 private static final String MODRM_BYTE_VARIABLE_NAME = "modRMByte"; | |
161 | |
162 private void printModRMByte(IndentWriter writer, Template_Type template) { | |
163 writer.print("byte " + MODRM_BYTE_VARIABLE_NAME + " = (byte) ((" + template.modCase().ordinal() + " << " + X86Field.MOD.shift() + ")"); | |
164 if (template.modRMGroupOpcode() != null) { | |
165 writer.print(" | (" + MODRM_GROUP_OPCODE_VARIABLE_NAME + " << " + X86Field.REG.shift() + ")"); | |
166 } | |
167 writer.print("); // mod field"); | |
168 if (template.modRMGroupOpcode() != null) { | |
169 writer.print(", group opcode in reg field"); | |
170 } | |
171 writer.println(); | |
172 switch (template.rmCase()) { | |
173 case SIB: | |
174 case SWORD: | |
175 case SDWORD: { | |
176 writer.println(MODRM_BYTE_VARIABLE_NAME + " |= " + template.rmCase().value() + " << " + X86Field.RM.shift() + "; // rm field"); | |
177 break; | |
178 } | |
179 default: | |
180 break; | |
181 } | |
182 for (X86Parameter parameter : template.parameters()) { | |
183 switch (parameter.place()) { | |
184 case MOD_REG: | |
185 case MOD_REG_REXR: { | |
186 writer.println(MODRM_BYTE_VARIABLE_NAME + " |= (" + parameter.valueString() + " & 7) << " + X86Field.REG.shift() + "; // reg field"); | |
187 break; | |
188 } | |
189 case MOD_RM: | |
190 case MOD_RM_REXB: { | |
191 writer.println(MODRM_BYTE_VARIABLE_NAME + " |= (" + parameter.valueString() + " & 7) << " + X86Field.RM.shift() + "; // rm field"); | |
192 break; | |
193 } | |
194 default: | |
195 break; | |
196 } | |
197 } | |
198 emitByte(writer, MODRM_BYTE_VARIABLE_NAME); | |
199 writer.println(); | |
200 } | |
201 | |
202 private static final String SIB_BYTE_NAME = "sibByte"; | |
203 | |
204 private void printSibByte(IndentWriter writer, Template_Type template) { | |
205 writer.print("byte " + SIB_BYTE_NAME + " = "); | |
206 if (template.sibBaseCase() == X86TemplateContext.SibBaseCase.SPECIAL) { | |
207 writer.println("(byte) (5 << " + X86Field.BASE.shift() + "); // base field"); | |
208 } else { | |
209 writer.println("(byte) 0;"); | |
210 } | |
211 for (X86Parameter parameter : template.parameters()) { | |
212 switch (parameter.place()) { | |
213 case SIB_BASE: | |
214 case SIB_BASE_REXB: | |
215 writer.println(SIB_BYTE_NAME + " |= (" + parameter.valueString() + " & 7) << " + X86Field.BASE.shift() + "; // base field"); | |
216 break; | |
217 case SIB_INDEX: | |
218 case SIB_INDEX_REXX: | |
219 writer.println(SIB_BYTE_NAME + " |= (" + parameter.valueString() + " & 7) << " + X86Field.INDEX.shift() + "; // index field"); | |
220 break; | |
221 case SIB_SCALE: | |
222 writer.println(SIB_BYTE_NAME + " |= " + parameter.valueString() + " << " + X86Field.SCALE.shift() + "; // scale field"); | |
223 break; | |
224 default: | |
225 break; | |
226 } | |
227 } | |
228 emitByte(writer, SIB_BYTE_NAME); | |
229 writer.println(); | |
230 } | |
231 | |
232 protected <Argument_Type extends Enum<Argument_Type> & EnumerableArgument<Argument_Type>> void printSibVariant(IndentWriter writer, Template_Type template, Argument_Type... arguments) { | |
233 final Class argumentType = arguments[0].getClass(); | |
234 final X86Parameter parameter = getParameter(template, argumentType); | |
235 writer.print("if ("); | |
236 String separator = ""; | |
237 for (EnumerableArgument argument : arguments) { | |
238 writer.print(separator + parameter.variableName() + " == " + asIdentifier(argument)); | |
239 separator = " || "; | |
240 } | |
241 writer.println(") {"); | |
242 writer.indent(); | |
243 emitByte(writer, (byte) 0x24); | |
244 writer.println(" // SIB byte"); | |
245 writer.outdent(); | |
246 writer.println("}"); | |
247 } | |
248 | |
249 protected abstract void printSibVariants(IndentWriter writer, Template_Type template); | |
250 | |
251 private void printImmediateParameter(IndentWriter writer, X86NumericalParameter parameter) { | |
252 if (parameter.width() == WordWidth.BITS_8) { | |
253 emitByte(writer, parameter.variableName()); | |
254 writer.println(" // appended"); | |
255 } else { | |
256 writer.println("// appended:"); | |
257 for (int i = 0; i < parameter.width().numberOfBytes; i++) { | |
258 if (i > 0) { | |
259 writer.println(parameter.variableName() + " >>= 8;"); | |
260 } | |
261 emitByte(writer, "(byte) (" + parameter.variableName() + " & 0xff)"); | |
262 writer.println(); | |
263 } | |
264 } | |
265 } | |
266 | |
267 private void printAppendedEnumerableParameter(IndentWriter writer, X86EnumerableParameter parameter) { | |
268 emitByte(writer, "(byte) " + parameter.variableName() + ".value()"); | |
269 writer.println(" // appended"); | |
270 } | |
271 | |
272 private void printAppendedParameter(IndentWriter writer, Template_Type template) { | |
273 for (X86Parameter parameter : template.parameters()) { | |
274 if (parameter.place() == ParameterPlace.APPEND) { | |
275 if (parameter instanceof X86NumericalParameter) { | |
276 printImmediateParameter(writer, (X86NumericalParameter) parameter); | |
277 } else if (parameter instanceof X86EnumerableParameter) { | |
278 printAppendedEnumerableParameter(writer, (X86EnumerableParameter) parameter); | |
279 } else { | |
280 throw ProgramError.unexpected("appended parameter of unexpected type: " + parameter); | |
281 } | |
282 } | |
283 } | |
284 } | |
285 | |
286 private int subroutineSerial; | |
287 | |
288 private String createSubroutineName() { | |
289 ++subroutineSerial; | |
290 String number = Integer.toString(subroutineSerial); | |
291 while (number.length() < 4) { | |
292 number = "0" + number; | |
293 } | |
294 return "assemble" + number; | |
295 } | |
296 | |
297 private Map<String, String> subroutineToName = new HashMap<String, String>(); | |
298 | |
299 private static final String OPCODE1_VARIABLE_NAME = "opcode1"; | |
300 private static final String OPCODE2_VARIABLE_NAME = "opcode2"; | |
301 private static final String MODRM_GROUP_OPCODE_VARIABLE_NAME = "modRmOpcode"; | |
302 | |
303 private void printSubroutine(IndentWriter writer, Template_Type template) { | |
304 writer.print("(byte "); | |
305 if (template.opcode2() != null) { | |
306 writer.print(OPCODE2_VARIABLE_NAME); | |
307 } else { | |
308 writer.print(OPCODE1_VARIABLE_NAME); | |
309 } | |
310 if (template.modRMGroupOpcode() != null) { | |
311 writer.print(", byte " + MODRM_GROUP_OPCODE_VARIABLE_NAME); | |
312 } | |
313 writer.print(formatParameterList(", ", template.parameters(), false)); | |
314 writer.println(") {"); | |
315 writer.indent(); | |
316 writer.indent(); | |
317 printModVariants(writer, template); | |
318 printPrefixes(writer, template); | |
319 if (template.opcode2() != null) { | |
320 emitByte(writer, "(byte) (" + Bytes.toHexLiteral(template.opcode1().byteValue()) + ")"); | |
321 writer.println(" // " + OPCODE1_VARIABLE_NAME); | |
322 printOpcode(writer, template, OPCODE2_VARIABLE_NAME, ParameterPlace.OPCODE2, ParameterPlace.OPCODE2_REXB); | |
323 } else { | |
324 printOpcode(writer, template, OPCODE1_VARIABLE_NAME, ParameterPlace.OPCODE1, ParameterPlace.OPCODE1_REXB); | |
325 } | |
326 if (template.hasModRMByte()) { | |
327 printModRMByte(writer, template); | |
328 if (template.hasSibByte()) { | |
329 printSibByte(writer, template); | |
330 } else { | |
331 printSibVariants(writer, template); | |
332 } | |
333 } | |
334 printAppendedParameter(writer, template); | |
335 writer.outdent(); | |
336 writer.println("}"); | |
337 writer.outdent(); | |
338 } | |
339 | |
340 private String makeSubroutine(Template_Type template) { | |
341 final StringWriter stringWriter = new StringWriter(); | |
342 printSubroutine(new IndentWriter(new PrintWriter(stringWriter)), template); | |
343 final String subroutine = stringWriter.toString(); | |
344 String name = subroutineToName.get(subroutine); | |
345 if (name == null) { | |
346 name = createSubroutineName(); | |
347 subroutineToName.put(subroutine, name); | |
348 } | |
349 return name; | |
350 } | |
351 | |
352 @Override | |
353 protected int printMethod(IndentWriter writer, Template_Type template) { | |
354 final int startLineCount = writer.lineCount(); | |
355 writer.print("public void "); | |
356 writer.print(template.assemblerMethodName() + "("); | |
357 writer.print(formatParameterList("", template.parameters(), false)); | |
358 writer.println(") {"); | |
359 writer.indent(); | |
360 final String subroutineName = makeSubroutine(template); | |
361 writer.print(subroutineName + "("); | |
362 if (template.opcode2() != null) { | |
363 writer.print("(byte) " + Bytes.toHexLiteral(template.opcode2().byteValue())); | |
364 } else { | |
365 writer.print("(byte) " + Bytes.toHexLiteral(template.opcode1().byteValue())); | |
366 } | |
367 if (template.modRMGroupOpcode() != null) { | |
368 writer.print(", (byte) " + Bytes.toHexLiteral(template.modRMGroupOpcode().byteValue())); | |
369 } | |
370 for (X86Parameter parameter : template.parameters()) { | |
371 writer.print(", " + parameter.variableName()); | |
372 } | |
373 writer.println(");"); | |
374 writer.outdent(); | |
375 writer.println("}"); | |
376 return writer.lineCount() - startLineCount; | |
377 } | |
378 | |
379 @Override | |
380 protected int printSubroutines(IndentWriter writer) { | |
381 final Set<String> subroutineSet = subroutineToName.keySet(); | |
382 final String[] subroutines = subroutineSet.toArray(new String[subroutineSet.size()]); | |
383 for (int i = 0; i < subroutines.length; i++) { | |
384 subroutines[i] = subroutineToName.get(subroutines[i]) + subroutines[i]; | |
385 } | |
386 java.util.Arrays.sort(subroutines); | |
387 for (String subroutine : subroutines) { | |
388 writer.print("private void " + subroutine); | |
389 writer.println(); | |
390 } | |
391 return subroutines.length; | |
392 } | |
393 | |
394 private boolean parametersMatching(Template_Type candidate, Template_Type original) { | |
395 if (candidate.parameters().size() != original.parameters().size()) { | |
396 return false; | |
397 } | |
398 for (int i = 0; i < candidate.parameters().size(); i++) { | |
399 if (i == original.labelParameterIndex()) { | |
400 assert candidate.parameters().get(i).getClass() == X86OffsetParameter.class || candidate.parameters().get(i).getClass() == X86AddressParameter.class; | |
401 assert candidate.parameters().get(i).getClass() == original.parameters().get(i).getClass(); | |
402 } else if (candidate.parameters().get(i).type() != original.parameters().get(i).type()) { | |
403 return false; | |
404 } | |
405 } | |
406 return true; | |
407 } | |
408 | |
409 private final class LabelWidthCase { | |
410 final WordWidth width; | |
411 final Template_Type template; | |
412 | |
413 private LabelWidthCase(WordWidth width, Template_Type template) { | |
414 this.width = width; | |
415 this.template = template; | |
416 } | |
417 } | |
418 | |
419 private String getValidSizesMaskExpression(List<LabelWidthCase> labelWidthCases) { | |
420 final Iterator<LabelWidthCase> iterator = labelWidthCases.iterator(); | |
421 String mask = String.valueOf(iterator.next().width.numberOfBytes); | |
422 while (iterator.hasNext()) { | |
423 mask += " | " + iterator.next().width.numberOfBytes; | |
424 } | |
425 return mask; | |
426 } | |
427 | |
428 private List<LabelWidthCase> getRelatedLabelTemplatesByWidth(Template_Type template) { | |
429 final List<LabelWidthCase> array = Utils.newArrayAsList(WordWidth.VALUES.size()); | |
430 for (Template_Type t : labelTemplates()) { | |
431 if (t.assemblerMethodName().equals(template.assemblerMethodName()) && t.labelParameterIndex() == template.labelParameterIndex() && parametersMatching(t, template)) { | |
432 final X86NumericalParameter numericalParameter = (X86NumericalParameter) t.parameters().get(template.labelParameterIndex()); | |
433 final WordWidth width = numericalParameter.width(); | |
434 array.set(width.ordinal(), new LabelWidthCase(width, t)); | |
435 t.isLabelMethodWritten = true; | |
436 } | |
437 } | |
438 | |
439 // Report the found cases in the order of ascending width: | |
440 final List<LabelWidthCase> result = new LinkedList<LabelWidthCase>(); | |
441 for (int i = 0; i < array.size(); i++) { | |
442 final LabelWidthCase labelWidthCase = array.get(i); | |
443 if (labelWidthCase != null) { | |
444 assert result.isEmpty() || labelWidthCase.width.greaterThan(Utils.last(result).width); | |
445 result.add(labelWidthCase); | |
446 } | |
447 } | |
448 assert result.size() > 0; | |
449 return result; | |
450 } | |
451 | |
452 private void printOffsetLabelMethod(final IndentWriter indentWriter, | |
453 Template_Type template, | |
454 final List<Parameter> parameters, | |
455 String assemblerClassName) { | |
456 final List<LabelWidthCase> labelWidthCases = getRelatedLabelTemplatesByWidth(template); | |
457 final InstructionWithLabelSubclass labelInstructionSubclass = new InstructionWithLabelSubclass(template, InstructionWithOffset.class, ", " + getValidSizesMaskExpression(labelWidthCases)) { | |
458 @Override | |
459 public void printAssembleMethodBody(IndentWriter writer, Template t) { | |
460 if (labelWidthCases.size() == 1) { | |
461 final LabelWidthCase labelWidthCase = Utils.first(labelWidthCases); | |
462 super.printAssembleMethodBody(writer, labelWidthCase.template); | |
463 } else { | |
464 writer.println("final int labelSize = labelSize();"); | |
465 String prefix = ""; | |
466 for (LabelWidthCase labelWidthCase : labelWidthCases) { | |
467 writer.println(prefix + "if (labelSize == " + labelWidthCase.width.numberOfBytes + ") {"); | |
468 writer.indent(); | |
469 super.printAssembleMethodBody(writer, labelWidthCase.template); | |
470 writer.outdent(); | |
471 prefix = "} else "; | |
472 } | |
473 writer.println(prefix + "{"); | |
474 writer.println(" throw new " + AssemblyException.class.getSimpleName() + "(\"Unexpected label width: \" + labelSize);"); | |
475 writer.println("}"); | |
476 } | |
477 } | |
478 }; | |
479 | |
480 printLabelMethodHelper(indentWriter, | |
481 template, | |
482 parameters, | |
483 -1, | |
484 assemblerClassName, | |
485 labelInstructionSubclass); | |
486 } | |
487 | |
488 private void printAddressLabelMethod( | |
489 final IndentWriter indentWriter, | |
490 final Template_Type template, | |
491 final List<Parameter> parameters, | |
492 String assemblerClassName) { | |
493 final InstructionWithLabelSubclass labelInstructionSubclass = new InstructionWithLabelSubclass(template, InstructionWithAddress.class, ""); | |
494 printLabelMethodHelper(indentWriter, | |
495 template, | |
496 parameters, | |
497 -1, | |
498 assemblerClassName, | |
499 labelInstructionSubclass); | |
500 } | |
501 | |
502 @Override | |
503 protected boolean omitLabelTemplate(Template_Type labelTemplate) { | |
504 return labelTemplate.isLabelMethodWritten; | |
505 } | |
506 | |
507 @Override | |
508 protected void printLabelMethod(IndentWriter writer, Template_Type labelTemplate, String assemblerClassName) { | |
509 if (labelTemplate.addressSizeAttribute() == addressWidth()) { | |
510 if (!labelTemplate.isLabelMethodWritten) { | |
511 labelTemplate.isLabelMethodWritten = true; | |
512 final List<Parameter> parameters = getParameters(labelTemplate, true); | |
513 final X86Parameter parameter = labelTemplate.parameters().get(labelTemplate.labelParameterIndex()); | |
514 if (parameter instanceof X86OffsetParameter) { | |
515 printOffsetLabelMethod(writer, labelTemplate, parameters, assemblerClassName); | |
516 } else { | |
517 printAddressLabelMethod(writer, labelTemplate, parameters, assemblerClassName); | |
518 } | |
519 } | |
520 } | |
521 } | |
522 | |
523 public static byte basicRexValue(X86Template template) { | |
524 if (template.operandSizeAttribute() == WordWidth.BITS_64 && template.instructionDescription().defaultOperandSize() != WordWidth.BITS_64) { | |
525 return (byte) (X86Opcode.REX_MIN.ordinal() + (1 << X86Field.REX_W_BIT_INDEX)); | |
526 } | |
527 return (byte) X86Opcode.REX_MIN.ordinal(); | |
528 } | |
529 } |