comparison graal/Compiler/src/com/sun/c1x/target/amd64/AMD64XirAssembler.java @ 2507:9ec15d6914ca

Pull over of compiler from maxine repository.
author Thomas Wuerthinger <thomas@wuerthinger.net>
date Wed, 27 Apr 2011 11:43:22 +0200
parents
children
comparison
equal deleted inserted replaced
2506:4a3bf8a5bf41 2507:9ec15d6914ca
1 /*
2 * Copyright (c) 2009, 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.c1x.target.amd64;
24
25 import static com.sun.cri.xir.XirTemplate.GlobalFlags.*;
26
27 import java.util.*;
28
29 import com.sun.c1x.util.*;
30 import com.sun.cri.ci.*;
31 import com.sun.cri.xir.*;
32
33 /**
34 * AMD64 version of {@link CiXirAssembler}.
35 *
36 * @author Thomas Wuerthinger
37 *
38 */
39 public class AMD64XirAssembler extends CiXirAssembler {
40
41 @Override
42 protected XirTemplate buildTemplate(String name, boolean isStub) {
43 List<XirInstruction> fastPath = new ArrayList<XirInstruction>(instructions.size());
44 List<XirInstruction> slowPath = new ArrayList<XirInstruction>();
45 List<XirTemplate> calleeTemplates = new ArrayList<XirTemplate>();
46
47 int flags = 0;
48
49 if (isStub) {
50 flags |= GLOBAL_STUB.mask;
51 }
52
53 List<XirInstruction> currentList = fastPath;
54
55 XirOperand fixedRDX = null;
56 XirOperand fixedRAX = null;
57 XirOperand fixedRCX = null;
58 XirOperand fixedRSI = null;
59 XirOperand fixedRDI = null;
60 HashSet<XirLabel> boundLabels = new HashSet<XirLabel>();
61
62 for (XirInstruction i : instructions) {
63 boolean appended = false;
64 switch (i.op) {
65 case Mov:
66 break;
67
68 case Add:
69 case Sub:
70 case Div:
71 case Mul:
72 case Mod:
73 case Shl:
74 case Shr:
75 case And:
76 case Or:
77 case Xor:
78 // Convert to two operand form
79 XirOperand xOp = i.x();
80 if (i.op == XirOp.Div || i.op == XirOp.Mod) {
81 if (fixedRDX == null) {
82 fixedRDX = createRegisterTemp("divModTemp", CiKind.Int, AMD64.rdx);
83 }
84 // Special treatment to make sure that the left input of % and / is in RAX
85 if (fixedRAX == null) {
86 fixedRAX = createRegisterTemp("divModLeftInput", CiKind.Int, AMD64.rax);
87 }
88 currentList.add(new XirInstruction(i.x().kind, XirOp.Mov, fixedRAX, i.x()));
89 xOp = fixedRAX;
90 } else {
91 if (i.result != i.x()) {
92 currentList.add(new XirInstruction(i.result.kind, XirOp.Mov, i.result, i.x()));
93 xOp = i.result;
94 }
95 }
96
97 XirOperand yOp = i.y();
98 if ((i.op == XirOp.Shl || i.op == XirOp.Shr) && (!(i.y() instanceof XirConstantOperand))) {
99 // Special treatment to make sure that the shift count is always in RCX
100 if (fixedRCX == null) {
101 fixedRCX = createRegisterTemp("fixedShiftCount", i.y().kind, AMD64.rcx);
102 }
103 currentList.add(new XirInstruction(i.result.kind, XirOp.Mov, fixedRCX, i.y()));
104 yOp = fixedRCX;
105 } else if (i.op == XirOp.Mul && (i.y() instanceof XirConstantOperand)) {
106 // Cannot multiply directly with a constant, so introduce a new temporary variable
107 XirOperand tempLocation = createTemp("mulTempLocation", i.y().kind);
108 currentList.add(new XirInstruction(i.result.kind, XirOp.Mov, tempLocation, i.y()));
109 yOp = tempLocation;
110
111 }
112
113 if (xOp != i.x() || yOp != i.y()) {
114 currentList.add(new XirInstruction(i.result.kind, i.op, i.result, xOp, yOp));
115 appended = true;
116 }
117 break;
118
119 case RepeatMoveWords:
120 case RepeatMoveBytes:
121 if (fixedRSI == null) {
122 fixedRSI = createRegisterTemp("fixedRSI", CiKind.Word, AMD64.rsi);
123 }
124 if (fixedRDI == null) {
125 fixedRDI = createRegisterTemp("fixedRDI", CiKind.Word, AMD64.rdi);
126 }
127 if (fixedRCX == null) {
128 fixedRCX = createRegisterTemp("fixedRCX", CiKind.Word, AMD64.rcx);
129 }
130 currentList.add(new XirInstruction(CiKind.Word, XirOp.Mov, fixedRSI, i.x()));
131 currentList.add(new XirInstruction(CiKind.Word, XirOp.Mov, fixedRDI, i.y()));
132 currentList.add(new XirInstruction(CiKind.Word, XirOp.Mov, fixedRCX, i.z()));
133 currentList.add(new XirInstruction(CiKind.Illegal, i.op, i.result, fixedRSI, fixedRDI, fixedRCX));
134 appended = true;
135 break;
136
137 case NullCheck:
138 case PointerLoad:
139 case LoadEffectiveAddress:
140 case PointerStore:
141 case PointerLoadDisp:
142 case PointerStoreDisp:
143 break;
144 case PointerCAS:
145 if (fixedRAX == null) {
146 fixedRAX = createRegisterTemp("fixedRAX", CiKind.Word, AMD64.rax);
147 }
148 // x = source of cmpxch
149 // y = new value
150 // z = old value (i.e., the one compared to). Must be in RAX (and so must the result).
151 currentList.add(new XirInstruction(CiKind.Word, XirOp.Mov, fixedRAX, i.z()));
152 currentList.add(new XirInstruction(i.kind, i.op, i.result, i.x(), i.y(), fixedRAX));
153 appended = true;
154 break;
155 case CallStub:
156 flags |= HAS_STUB_CALL.mask;
157 calleeTemplates.add((XirTemplate) i.extra);
158 break;
159 case CallRuntime:
160 flags |= HAS_RUNTIME_CALL.mask;
161 break;
162 case Jmp:
163 // jmp can be either into the snippet or to a runtime target
164 flags |= i.extra instanceof XirLabel ? HAS_CONTROL_FLOW.mask : HAS_RUNTIME_CALL.mask;
165 break;
166 case Jeq:
167 case Jneq:
168 case Jgt:
169 case Jgteq:
170 case Jugteq:
171 case Jlt:
172 case Jlteq:
173 case DecAndJumpNotZero:
174 case Jbset:
175 flags |= HAS_CONTROL_FLOW.mask;
176 break;
177 case Bind:
178 XirLabel label = (XirLabel) i.extra;
179 currentList = label.inline ? fastPath : slowPath;
180 assert !boundLabels.contains(label) : "label may be bound only once";
181 boundLabels.add(label);
182 break;
183 case Safepoint:
184 case Align:
185 case StackOverflowCheck:
186 case PushFrame:
187 case PopFrame:
188 case Push:
189 case Pop:
190 case Mark:
191 case Nop:
192 case RawBytes:
193 case ShouldNotReachHere:
194 break;
195 default:
196 throw Util.unimplemented("XIR operation " + i.op);
197 }
198 if (!appended) {
199 currentList.add(i);
200 }
201 }
202 for (XirLabel label : labels) {
203 assert boundLabels.contains(label) : "label " + label.name + " is not bound!";
204 }
205 XirInstruction[] fp = fastPath.toArray(new XirInstruction[fastPath.size()]);
206 XirInstruction[] sp = slowPath.size() > 0 ? slowPath.toArray(new XirInstruction[slowPath.size()]) : null;
207 XirLabel[] xirLabels = labels.toArray(new XirLabel[labels.size()]);
208 XirParameter[] xirParameters = parameters.toArray(new XirParameter[parameters.size()]);
209 XirTemp[] temporaryOperands = temps.toArray(new XirTemp[temps.size()]);
210 XirConstant[] constantOperands = constants.toArray(new XirConstant[constants.size()]);
211 XirTemplate[] calleeTemplateArray = calleeTemplates.toArray(new XirTemplate[calleeTemplates.size()]);
212 XirMark[] marksArray = marks.toArray(new XirMark[marks.size()]);
213 return new XirTemplate(name, this.variableCount, this.allocateResultOperand, resultOperand, fp, sp, xirLabels, xirParameters, temporaryOperands, constantOperands, flags, calleeTemplateArray, marksArray, outgoingStackSize);
214 }
215
216 @Override
217 public CiXirAssembler copy() {
218 return new AMD64XirAssembler();
219 }
220 }