comparison graal/com.oracle.max.asmdis/src/com/sun/max/asm/gen/cisc/x86/X86TemplateCreator.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.util.*;
26
27 import com.sun.max.asm.gen.*;
28 import com.sun.max.lang.*;
29
30 /**
31 */
32 public abstract class X86TemplateCreator<Template_Type extends X86Template> {
33
34 private final Assembly assembly;
35 private final WordWidth addressWidth;
36 private X86InstructionDescription instructionDescription;
37 private InstructionAssessment instructionAssessment;
38 private X86TemplateContext context;
39 private int serial = 1;
40
41 protected X86TemplateCreator(Assembly assembly, WordWidth addressWidth) {
42 this.assembly = assembly;
43 this.addressWidth = addressWidth;
44 }
45
46 private final List<Template_Type> templates = new ArrayList<Template_Type>();
47
48 public List<Template_Type> templates() {
49 return templates;
50 }
51
52 private final Map<String, List<Template_Type>> internalNameToTemplates = new HashMap<String, List<Template_Type>>();
53
54 private void addTemplate(Template_Type template) {
55 templates.add(template);
56 List<Template_Type> t = internalNameToTemplates.get(template.internalName());
57 if (t == null) {
58 t = new LinkedList<Template_Type>();
59 internalNameToTemplates.put(template.internalName(), t);
60 }
61 t.add(template);
62 }
63
64 private void computeRedundancy(X86Template template) {
65 final List<Template_Type> t = internalNameToTemplates.get(template.internalName());
66 if (t != null) {
67 for (X86Template other : t) {
68 if (template.computeRedundancyWith(other)) {
69 return;
70 }
71 }
72 }
73 }
74
75 protected abstract Template_Type createTemplate(X86InstructionDescription description, int ser, InstructionAssessment instructionFamily, X86TemplateContext contxt);
76
77 private void createTemplate() {
78 final Template_Type template = createTemplate(instructionDescription, serial, instructionAssessment, context);
79 if (X86InstructionDescriptionVisitor.Static.visitInstructionDescription(template, instructionDescription)) {
80 final InstructionDescription modRMInstructionDescription = template.modRMInstructionDescription();
81 if (modRMInstructionDescription != null && !X86InstructionDescriptionVisitor.Static.visitInstructionDescription(template, modRMInstructionDescription)) {
82 return;
83 }
84 computeRedundancy(template);
85 addTemplate(template);
86 serial++;
87 }
88 }
89
90 private void createTemplatesForSibBaseCases() {
91 for (X86TemplateContext.SibBaseCase sibBaseCase : X86TemplateContext.SibBaseCase.VALUES) {
92 if (sibBaseCase == X86TemplateContext.SibBaseCase.GENERAL_REGISTER || context.modCase() == X86TemplateContext.ModCase.MOD_0) {
93 context = context.clone();
94 context.sibBaseCase = sibBaseCase;
95 createTemplate();
96 }
97 }
98 }
99
100 private void createTemplatesForSibIndexCases() {
101 for (X86TemplateContext.SibIndexCase sibIndexCase : X86TemplateContext.SibIndexCase.VALUES) {
102 context = context.clone();
103 context.setSibIndexCase(sibIndexCase);
104 createTemplatesForSibBaseCases();
105 }
106 }
107
108 private void createTemplatesForRMCases() {
109 for (X86TemplateContext.RMCase rmCase : X86TemplateContext.RMCase.VALUES) {
110 context = context.clone();
111 context.setRMCase(rmCase);
112 switch (context.modCase()) {
113 case MOD_3: {
114 if (rmCase == X86TemplateContext.RMCase.NORMAL) {
115 createTemplate();
116 }
117 break;
118 }
119 default: {
120 switch (rmCase) {
121 case SIB:
122 createTemplatesForSibIndexCases();
123 break;
124 default:
125 createTemplate();
126 break;
127 }
128 }
129 }
130 }
131 }
132
133 private void createTemplatesForModRMGroups() {
134 if (instructionAssessment.modRMGroup() != null) {
135 for (ModRMGroup.Opcode modRMGroupOpcode : ModRMGroup.Opcode.VALUES) {
136 context = context.clone();
137 context.setModRMGroupOpcode(modRMGroupOpcode);
138 createTemplatesForRMCases();
139 }
140 } else {
141 createTemplatesForRMCases();
142 }
143 }
144
145 private void createTemplatesForModCases(WordWidth operandSizeAttribute) {
146 context = context.clone();
147 context.setOperandSizeAttribute(operandSizeAttribute);
148
149 if (instructionAssessment.hasModRMByte()) {
150 for (X86TemplateContext.ModCase modCase : X86TemplateContext.ModCase.VALUES) {
151 context = context.clone();
152 context.setModCase(modCase);
153 createTemplatesForModRMGroups();
154 }
155 } else {
156 createTemplate();
157 }
158 }
159
160 private void createTemplatesForOperandSizeAttribute(WordWidth addressSizeAttribute) {
161 context = context.clone();
162 context.setAddressSizeAttribute(addressSizeAttribute);
163
164 if (instructionDescription.requiredOperandSize() != null) {
165 createTemplatesForModCases(instructionDescription.requiredOperandSize());
166 } else {
167 if (instructionDescription.defaultOperandSize() != WordWidth.BITS_64) {
168 createTemplatesForModCases(WordWidth.BITS_32);
169 }
170 if (addressWidth == WordWidth.BITS_64) {
171 createTemplatesForModCases(WordWidth.BITS_64);
172 }
173 if (X86Assembly.are16BitOffsetsSupported() || !instructionAssessment.isJump()) {
174 createTemplatesForModCases(WordWidth.BITS_16);
175 }
176 }
177 }
178
179 private void createTemplatesForAddressSizeAttribute() {
180 if (instructionDescription.requiredAddressSize() != null) {
181 if (X86Assembly.are16BitAddressesSupported() || instructionDescription.requiredAddressSize() == addressWidth) {
182 createTemplatesForOperandSizeAttribute(instructionDescription.requiredAddressSize());
183 }
184 } else {
185 createTemplatesForOperandSizeAttribute(addressWidth);
186 if (X86Assembly.are16BitAddressesSupported() && instructionAssessment.hasAddressSizeVariants()) {
187 createTemplatesForOperandSizeAttribute(WordWidth.fromInt(addressWidth.numberOfBits / 2));
188 }
189 }
190 }
191
192 public void createTemplates(InstructionDescriptionCreator<X86InstructionDescription> instructionDescriptionCreator) {
193 for (X86InstructionDescription description : instructionDescriptionCreator.instructionDescriptions()) {
194 this.instructionDescription = description;
195 this.instructionAssessment = new InstructionAssessment();
196 final OpcodeAssessor assessor = new OpcodeAssessor(instructionAssessment);
197 X86InstructionDescriptionVisitor.Static.visitInstructionDescription(assessor, description);
198 this.context = new X86TemplateContext();
199 createTemplatesForAddressSizeAttribute();
200 }
201 }
202 }