Mercurial > hg > graal-jvmci-8
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 } |