Mercurial > hg > graal-compiler
comparison graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java @ 7804:447f9ba1962b
Experimental PTX backend. Contribution by Christian Thalinger.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Mon, 18 Feb 2013 14:47:54 -0800 |
parents | |
children | 0e58445d54df |
comparison
equal
deleted
inserted
replaced
7803:89d316f8f33e | 7804:447f9ba1962b |
---|---|
1 /* | |
2 * Copyright (c) 2013, 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 | |
24 package com.oracle.graal.compiler.ptx; | |
25 | |
26 import static com.oracle.graal.api.code.ValueUtil.*; | |
27 import static com.oracle.graal.lir.ptx.PTXArithmetic.*; | |
28 import static com.oracle.graal.lir.ptx.PTXCompare.*; | |
29 import static com.oracle.graal.lir.ptx.PTXBitManipulationOp.IntrinsicOpcode.*; | |
30 //import static com.oracle.graal.lir.ptx.PTXMathIntrinsicOp.IntrinsicOpcode.*; | |
31 | |
32 import com.oracle.graal.ptx.*; | |
33 import com.oracle.graal.api.code.*; | |
34 import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor; | |
35 import com.oracle.graal.api.meta.*; | |
36 import com.oracle.graal.asm.*; | |
37 import com.oracle.graal.compiler.gen.*; | |
38 import com.oracle.graal.compiler.target.*; | |
39 import com.oracle.graal.graph.*; | |
40 import com.oracle.graal.lir.*; | |
41 import com.oracle.graal.lir.StandardOp.JumpOp; | |
42 import com.oracle.graal.lir.ptx.PTXBitManipulationOp; | |
43 import com.oracle.graal.lir.ptx.PTXCompare.CompareOp; | |
44 import com.oracle.graal.lir.ptx.PTXControlFlow.BranchOp; | |
45 import com.oracle.graal.lir.ptx.PTXControlFlow.ReturnOp; | |
46 import com.oracle.graal.lir.ptx.PTXMove.LoadOp; | |
47 import com.oracle.graal.lir.ptx.PTXMove.MoveFromRegOp; | |
48 import com.oracle.graal.lir.ptx.PTXMove.MoveToRegOp; | |
49 import com.oracle.graal.lir.ptx.PTXMove.NullCheckOp; | |
50 import com.oracle.graal.lir.ptx.PTXMove.StoreOp; | |
51 import com.oracle.graal.nodes.BreakpointNode; | |
52 import com.oracle.graal.nodes.DirectCallTargetNode; | |
53 import com.oracle.graal.nodes.IndirectCallTargetNode; | |
54 import com.oracle.graal.nodes.StructuredGraph; | |
55 import com.oracle.graal.nodes.ValueNode; | |
56 import com.oracle.graal.nodes.calc.Condition; | |
57 import com.oracle.graal.nodes.calc.ConvertNode; | |
58 import com.oracle.graal.nodes.extended.IndexedLocationNode; | |
59 import com.oracle.graal.nodes.extended.LocationNode; | |
60 import com.oracle.graal.nodes.java.CompareAndSwapNode; | |
61 import com.oracle.graal.phases.util.Util; | |
62 | |
63 /** | |
64 * This class implements the PTX specific portion of the LIR generator. | |
65 */ | |
66 public abstract class PTXLIRGenerator extends LIRGenerator { | |
67 | |
68 public static class PTXSpillMoveFactory implements LIR.SpillMoveFactory { | |
69 | |
70 @Override | |
71 public LIRInstruction createMove(Value result, Value input) { | |
72 // return new SpillMoveOp(result, input); | |
73 throw new InternalError("NYI"); | |
74 } | |
75 } | |
76 | |
77 public PTXLIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, ResolvedJavaMethod method, LIR lir) { | |
78 super(graph, runtime, target, frameMap, method, lir); | |
79 lir.spillMoveFactory = new PTXSpillMoveFactory(); | |
80 } | |
81 | |
82 @Override | |
83 protected void emitNode(ValueNode node) { | |
84 if (node instanceof LIRGenLowerable) { | |
85 ((LIRGenLowerable) node).generate(this); | |
86 } else { | |
87 super.emitNode(node); | |
88 } | |
89 } | |
90 | |
91 @Override | |
92 public boolean canStoreConstant(Constant c) { | |
93 // Operand b must be in the .reg state space. | |
94 return false; | |
95 } | |
96 | |
97 @Override | |
98 public boolean canInlineConstant(Constant c) { | |
99 switch (c.getKind()) { | |
100 case Long: | |
101 return NumUtil.isInt(c.asLong()) && !runtime.needsDataPatch(c); | |
102 case Object: | |
103 return c.isNull(); | |
104 default: | |
105 return true; | |
106 } | |
107 } | |
108 | |
109 @Override | |
110 public Address makeAddress(LocationNode location, ValueNode object) { | |
111 Value base = operand(object); | |
112 Value index = Value.ILLEGAL; | |
113 int scale = 1; | |
114 int displacement = location.displacement(); | |
115 | |
116 if (isConstant(base)) { | |
117 if (asConstant(base).isNull()) { | |
118 base = Value.ILLEGAL; | |
119 } else if (asConstant(base).getKind() != Kind.Object) { | |
120 long newDisplacement = displacement + asConstant(base).asLong(); | |
121 if (NumUtil.isInt(newDisplacement)) { | |
122 assert !runtime.needsDataPatch(asConstant(base)); | |
123 displacement = (int) newDisplacement; | |
124 base = Value.ILLEGAL; | |
125 } else { | |
126 Value newBase = newVariable(Kind.Long); | |
127 emitMove(base, newBase); | |
128 base = newBase; | |
129 } | |
130 } | |
131 } | |
132 | |
133 if (location instanceof IndexedLocationNode) { | |
134 IndexedLocationNode indexedLoc = (IndexedLocationNode) location; | |
135 | |
136 index = operand(indexedLoc.index()); | |
137 if (indexedLoc.indexScalingEnabled()) { | |
138 scale = target().sizeInBytes(location.getValueKind()); | |
139 } | |
140 if (isConstant(index)) { | |
141 long newDisplacement = displacement + asConstant(index).asLong() * scale; | |
142 // only use the constant index if the resulting displacement fits into a 32 bit | |
143 // offset | |
144 if (NumUtil.isInt(newDisplacement)) { | |
145 displacement = (int) newDisplacement; | |
146 index = Value.ILLEGAL; | |
147 } else { | |
148 // create a temporary variable for the index, the pointer load cannot handle a | |
149 // constant index | |
150 Value newIndex = newVariable(Kind.Long); | |
151 emitMove(index, newIndex); | |
152 index = newIndex; | |
153 } | |
154 } | |
155 } | |
156 | |
157 return new Address(location.getValueKind(), base, index, Address.Scale.fromInt(scale), displacement); | |
158 } | |
159 | |
160 @Override | |
161 public Variable emitMove(Value input) { | |
162 Variable result = newVariable(input.getKind()); | |
163 emitMove(input, result); | |
164 return result; | |
165 } | |
166 | |
167 @Override | |
168 public void emitMove(Value src, Value dst) { | |
169 if (isRegister(src) || isStackSlot(dst)) { | |
170 append(new MoveFromRegOp(dst, src)); | |
171 } else { | |
172 append(new MoveToRegOp(dst, src)); | |
173 } | |
174 } | |
175 | |
176 @Override | |
177 public Variable emitLoad(Value loadAddress, boolean canTrap) { | |
178 Variable result = newVariable(loadAddress.getKind()); | |
179 append(new LoadOp(result, loadAddress, canTrap ? state() : null)); | |
180 return result; | |
181 } | |
182 | |
183 @Override | |
184 public void emitStore(Value storeAddress, Value inputVal, boolean canTrap) { | |
185 Value input = loadForStore(inputVal, storeAddress.getKind()); | |
186 append(new StoreOp(storeAddress, input, canTrap ? state() : null)); | |
187 } | |
188 | |
189 @Override | |
190 public Variable emitLea(Value address) { | |
191 // Variable result = newVariable(target().wordKind); | |
192 // append(new LeaOp(result, address)); | |
193 // return result; | |
194 throw new InternalError("NYI"); | |
195 } | |
196 | |
197 @Override | |
198 public void emitJump(LabelRef label, LIRFrameState info) { | |
199 append(new JumpOp(label, info)); | |
200 } | |
201 | |
202 @Override | |
203 public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef label, LIRFrameState info) { | |
204 // boolean mirrored = emitCompare(left, right); | |
205 // Condition finalCondition = mirrored ? cond.mirror() : cond; | |
206 switch (left.getKind().getStackKind()) { | |
207 case Int: | |
208 append(new CompareOp(ICMP, cond, left, right)); | |
209 append(new BranchOp(cond, label, info)); | |
210 break; | |
211 // case Long: | |
212 case Object: | |
213 append(new CompareOp(ACMP, cond, left, right)); | |
214 append(new BranchOp(cond, label, info)); | |
215 break; | |
216 // case Float: | |
217 // case Double: | |
218 // append(new FloatBranchOp(finalCondition, unorderedIsTrue, label, info)); | |
219 // break; | |
220 default: | |
221 throw GraalInternalError.shouldNotReachHere("" + left.getKind()); | |
222 } | |
223 } | |
224 | |
225 @Override | |
226 public void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef label, LIRFrameState info) { | |
227 // emitIntegerTest(left, right); | |
228 // append(new BranchOp(negated ? Condition.NE : Condition.EQ, label, info)); | |
229 throw new InternalError("NYI"); | |
230 } | |
231 | |
232 @Override | |
233 public Variable emitConditionalMove(Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) { | |
234 // boolean mirrored = emitCompare(left, right); | |
235 // Condition finalCondition = mirrored ? cond.mirror() : cond; | |
236 // | |
237 // Variable result = newVariable(trueValue.getKind()); | |
238 // switch (left.getKind().getStackKind()) { | |
239 // case Int: | |
240 // case Long: | |
241 // case Object: | |
242 // append(new CondMoveOp(result, finalCondition, load(trueValue), loadNonConst(falseValue))); | |
243 // break; | |
244 // case Float: | |
245 // case Double: | |
246 // append(new FloatCondMoveOp(result, finalCondition, unorderedIsTrue, load(trueValue), load(falseValue))); | |
247 // break; | |
248 // default: | |
249 // throw GraalInternalError.shouldNotReachHere("" + left.getKind()); | |
250 // } | |
251 // return result; | |
252 throw new InternalError("NYI"); | |
253 } | |
254 | |
255 @Override | |
256 public Variable emitIntegerTestMove(Value left, Value right, Value trueValue, Value falseValue) { | |
257 // emitIntegerTest(left, right); | |
258 // Variable result = newVariable(trueValue.getKind()); | |
259 // append(new CondMoveOp(result, Condition.EQ, load(trueValue), loadNonConst(falseValue))); | |
260 // return result; | |
261 throw new InternalError("NYI"); | |
262 } | |
263 | |
264 private void emitIntegerTest(Value a, Value b) { | |
265 // assert a.getKind().getStackKind() == Kind.Int || a.getKind() == Kind.Long; | |
266 // if (LIRValueUtil.isVariable(b)) { | |
267 // append(new AMD64TestOp(load(b), loadNonConst(a))); | |
268 // } else { | |
269 // append(new AMD64TestOp(load(a), loadNonConst(b))); | |
270 // } | |
271 throw new InternalError("NYI"); | |
272 } | |
273 | |
274 // /** | |
275 // * This method emits the compare instruction, and may reorder the operands. It returns true if | |
276 // * it did so. | |
277 // * | |
278 // * @param a the left operand of the comparison | |
279 // * @param b the right operand of the comparison | |
280 // * @return true if the left and right operands were switched, false otherwise | |
281 // */ | |
282 // private boolean emitCompare(Value a, Value b) { | |
283 // Variable left; | |
284 // Value right; | |
285 // boolean mirrored; | |
286 // if (LIRValueUtil.isVariable(b)) { | |
287 // left = load(b); | |
288 // right = loadNonConst(a); | |
289 // mirrored = true; | |
290 // } else { | |
291 // left = load(a); | |
292 // right = loadNonConst(b); | |
293 // mirrored = false; | |
294 // } | |
295 // switch (left.getKind().getStackKind()) { | |
296 //// case Jsr: | |
297 // case Int: | |
298 // append(new CompareOp(ICMP, left, right)); | |
299 // break; | |
300 //// case Long: | |
301 //// append(new CompareOp(LCMP, left, right)); | |
302 //// break; | |
303 //// case Object: | |
304 //// append(new CompareOp(ACMP, left, right)); | |
305 //// break; | |
306 //// case Float: | |
307 //// append(new CompareOp(FCMP, left, right)); | |
308 //// break; | |
309 //// case Double: | |
310 //// append(new CompareOp(DCMP, left, right)); | |
311 //// break; | |
312 // default: | |
313 // throw GraalInternalError.shouldNotReachHere(); | |
314 // } | |
315 // return mirrored; | |
316 // } | |
317 | |
318 @Override | |
319 public Variable emitNegate(Value input) { | |
320 Variable result = newVariable(input.getKind()); | |
321 switch (input.getKind()) { | |
322 case Int: | |
323 append(new Op1Stack(INEG, result, input)); | |
324 break; | |
325 // case Long: | |
326 // append(new Op1Stack(LNEG, result, input)); | |
327 // break; | |
328 // case Float: | |
329 // append(new Op2Reg(FXOR, result, input, Constant.forFloat(Float.intBitsToFloat(0x80000000)))); | |
330 // break; | |
331 // case Double: | |
332 // append(new Op2Reg(DXOR, result, input, Constant.forDouble(Double.longBitsToDouble(0x8000000000000000L)))); | |
333 // break; | |
334 default: | |
335 throw GraalInternalError.shouldNotReachHere(); | |
336 } | |
337 return result; | |
338 } | |
339 | |
340 @Override | |
341 public Variable emitAdd(Value a, Value b) { | |
342 Variable result = newVariable(a.getKind()); | |
343 switch (a.getKind()) { | |
344 case Int: | |
345 append(new Op2Stack(IADD, result, a, loadNonConst(b))); | |
346 break; | |
347 // case Long: | |
348 // append(new Op2Stack(LADD, result, a, loadNonConst(b))); | |
349 // break; | |
350 // case Float: | |
351 // append(new Op2Stack(FADD, result, a, loadNonConst(b))); | |
352 // break; | |
353 // case Double: | |
354 // append(new Op2Stack(DADD, result, a, loadNonConst(b))); | |
355 // break; | |
356 default: | |
357 throw GraalInternalError.shouldNotReachHere(); | |
358 } | |
359 return result; | |
360 } | |
361 | |
362 @Override | |
363 public Variable emitSub(Value a, Value b) { | |
364 Variable result = newVariable(a.getKind()); | |
365 switch (a.getKind()) { | |
366 case Int: | |
367 append(new Op2Stack(ISUB, result, a, loadNonConst(b))); | |
368 break; | |
369 // case Long: | |
370 // append(new Op2Stack(LSUB, result, a, loadNonConst(b))); | |
371 // break; | |
372 // case Float: | |
373 // append(new Op2Stack(FSUB, result, a, loadNonConst(b))); | |
374 // break; | |
375 // case Double: | |
376 // append(new Op2Stack(DSUB, result, a, loadNonConst(b))); | |
377 // break; | |
378 default: | |
379 throw GraalInternalError.shouldNotReachHere(); | |
380 } | |
381 return result; | |
382 } | |
383 | |
384 @Override | |
385 public Variable emitMul(Value a, Value b) { | |
386 Variable result = newVariable(a.getKind()); | |
387 switch (a.getKind()) { | |
388 case Int: | |
389 append(new Op2Reg(IMUL, result, a, loadNonConst(b))); | |
390 break; | |
391 // case Long: | |
392 // append(new Op2Reg(LMUL, result, a, loadNonConst(b))); | |
393 // break; | |
394 // case Float: | |
395 // append(new Op2Stack(FMUL, result, a, loadNonConst(b))); | |
396 // break; | |
397 // case Double: | |
398 // append(new Op2Stack(DMUL, result, a, loadNonConst(b))); | |
399 // break; | |
400 default: | |
401 throw GraalInternalError.shouldNotReachHere(); | |
402 } | |
403 return result; | |
404 } | |
405 | |
406 @Override | |
407 protected boolean peephole(ValueNode valueNode) { | |
408 // No peephole optimizations for now | |
409 return false; | |
410 } | |
411 | |
412 public Value[] emitIntegerDivRem(Value a, Value b) { | |
413 // switch (a.getKind()) { | |
414 // case Int: | |
415 // emitMove(a, RAX_I); | |
416 // append(new DivRemOp(IDIVREM, RAX_I, load(b), state())); | |
417 // return new Value[]{emitMove(RAX_I), emitMove(RDX_I)}; | |
418 // case Long: | |
419 // emitMove(a, RAX_L); | |
420 // append(new DivRemOp(LDIVREM, RAX_L, load(b), state())); | |
421 // return new Value[]{emitMove(RAX_L), emitMove(RDX_L)}; | |
422 // default: | |
423 // throw GraalInternalError.shouldNotReachHere(); | |
424 // } | |
425 throw new InternalError("NYI"); | |
426 } | |
427 | |
428 @Override | |
429 public Value emitDiv(Value a, Value b) { | |
430 // switch (a.getKind()) { | |
431 // case Int: | |
432 // emitMove(a, RAX_I); | |
433 // append(new DivOp(IDIV, RAX_I, RAX_I, load(b), state())); | |
434 // return emitMove(RAX_I); | |
435 // case Long: | |
436 // emitMove(a, RAX_L); | |
437 // append(new DivOp(LDIV, RAX_L, RAX_L, load(b), state())); | |
438 // return emitMove(RAX_L); | |
439 // case Float: { | |
440 // Variable result = newVariable(a.getKind()); | |
441 // append(new Op2Stack(FDIV, result, a, loadNonConst(b))); | |
442 // return result; | |
443 // } | |
444 // case Double: { | |
445 // Variable result = newVariable(a.getKind()); | |
446 // append(new Op2Stack(DDIV, result, a, loadNonConst(b))); | |
447 // return result; | |
448 // } | |
449 // default: | |
450 // throw GraalInternalError.shouldNotReachHere(); | |
451 // } | |
452 throw new InternalError("NYI"); | |
453 } | |
454 | |
455 @Override | |
456 public Value emitRem(Value a, Value b) { | |
457 // switch (a.getKind()) { | |
458 // case Int: | |
459 // emitMove(a, RAX_I); | |
460 // append(new DivOp(IREM, RDX_I, RAX_I, load(b), state())); | |
461 // return emitMove(RDX_I); | |
462 // case Long: | |
463 // emitMove(a, RAX_L); | |
464 // append(new DivOp(LREM, RDX_L, RAX_L, load(b), state())); | |
465 // return emitMove(RDX_L); | |
466 // case Float: { | |
467 // RuntimeCallTarget stub = runtime.lookupRuntimeCall(ARITHMETIC_FREM); | |
468 // return emitCall(stub, stub.getCallingConvention(), false, a, b); | |
469 // } | |
470 // case Double: { | |
471 // RuntimeCallTarget stub = runtime.lookupRuntimeCall(ARITHMETIC_DREM); | |
472 // return emitCall(stub, stub.getCallingConvention(), false, a, b); | |
473 // } | |
474 // default: | |
475 // throw GraalInternalError.shouldNotReachHere(); | |
476 // } | |
477 throw new InternalError("NYI"); | |
478 } | |
479 | |
480 @Override | |
481 public Variable emitUDiv(Value a, Value b) { | |
482 // switch (a.getKind()) { | |
483 // case Int: | |
484 // emitMove(a, RAX_I); | |
485 // append(new DivOp(IUDIV, RAX_I, RAX_I, load(b), state())); | |
486 // return emitMove(RAX_I); | |
487 // case Long: | |
488 // emitMove(a, RAX_L); | |
489 // append(new DivOp(LUDIV, RAX_L, RAX_L, load(b), state())); | |
490 // return emitMove(RAX_L); | |
491 // default: | |
492 // throw GraalInternalError.shouldNotReachHere(); | |
493 // } | |
494 throw new InternalError("NYI"); | |
495 } | |
496 | |
497 @Override | |
498 public Variable emitURem(Value a, Value b) { | |
499 // switch (a.getKind()) { | |
500 // case Int: | |
501 // emitMove(a, RAX_I); | |
502 // append(new DivOp(IUREM, RDX_I, RAX_I, load(b), state())); | |
503 // return emitMove(RDX_I); | |
504 // case Long: | |
505 // emitMove(a, RAX_L); | |
506 // append(new DivOp(LUREM, RDX_L, RAX_L, load(b), state())); | |
507 // return emitMove(RDX_L); | |
508 // default: | |
509 // throw GraalInternalError.shouldNotReachHere(); | |
510 // } | |
511 throw new InternalError("NYI"); | |
512 } | |
513 | |
514 @Override | |
515 public Variable emitAnd(Value a, Value b) { | |
516 Variable result = newVariable(a.getKind()); | |
517 switch (a.getKind()) { | |
518 case Int: | |
519 append(new Op2Stack(IAND, result, a, loadNonConst(b))); | |
520 break; | |
521 // case Long: | |
522 // append(new Op2Stack(LAND, result, a, loadNonConst(b))); | |
523 // break; | |
524 default: | |
525 throw GraalInternalError.shouldNotReachHere(); | |
526 } | |
527 return result; | |
528 } | |
529 | |
530 @Override | |
531 public Variable emitOr(Value a, Value b) { | |
532 // Variable result = newVariable(a.getKind()); | |
533 // switch (a.getKind()) { | |
534 // case Int: | |
535 // append(new Op2Stack(IOR, result, a, loadNonConst(b))); | |
536 // break; | |
537 // case Long: | |
538 // append(new Op2Stack(LOR, result, a, loadNonConst(b))); | |
539 // break; | |
540 // default: | |
541 // throw GraalInternalError.shouldNotReachHere(); | |
542 // } | |
543 // return result; | |
544 throw new InternalError("NYI"); | |
545 } | |
546 | |
547 @Override | |
548 public Variable emitXor(Value a, Value b) { | |
549 // Variable result = newVariable(a.getKind()); | |
550 // switch (a.getKind()) { | |
551 // case Int: | |
552 // append(new Op2Stack(IXOR, result, a, loadNonConst(b))); | |
553 // break; | |
554 // case Long: | |
555 // append(new Op2Stack(LXOR, result, a, loadNonConst(b))); | |
556 // break; | |
557 // default: | |
558 // throw GraalInternalError.shouldNotReachHere(); | |
559 // } | |
560 // return result; | |
561 throw new InternalError("NYI"); | |
562 } | |
563 | |
564 @Override | |
565 public Variable emitShl(Value a, Value b) { | |
566 // Variable result = newVariable(a.getKind()); | |
567 // switch (a.getKind()) { | |
568 // case Int: | |
569 // append(new ShiftOp(ISHL, result, a, b)); | |
570 // break; | |
571 // case Long: | |
572 // append(new ShiftOp(LSHL, result, a, b)); | |
573 // break; | |
574 // default: | |
575 // GraalInternalError.shouldNotReachHere(); | |
576 // } | |
577 // return result; | |
578 throw new InternalError("NYI"); | |
579 } | |
580 | |
581 @Override | |
582 public Variable emitShr(Value a, Value b) { | |
583 // Variable result = newVariable(a.getKind()); | |
584 // switch (a.getKind()) { | |
585 // case Int: | |
586 // append(new ShiftOp(ISHR, result, a, b)); | |
587 // break; | |
588 // case Long: | |
589 // append(new ShiftOp(LSHR, result, a, b)); | |
590 // break; | |
591 // default: | |
592 // GraalInternalError.shouldNotReachHere(); | |
593 // } | |
594 // return result; | |
595 throw new InternalError("NYI"); | |
596 } | |
597 | |
598 @Override | |
599 public Variable emitUShr(Value a, Value b) { | |
600 Variable result = newVariable(a.getKind()); | |
601 switch (a.getKind()) { | |
602 case Int: | |
603 append(new ShiftOp(IUSHR, result, a, b)); | |
604 break; | |
605 // case Long: | |
606 // append(new ShiftOp(LUSHR, result, a, b)); | |
607 // break; | |
608 default: | |
609 GraalInternalError.shouldNotReachHere(); | |
610 } | |
611 return result; | |
612 } | |
613 | |
614 @Override | |
615 public Variable emitConvert(ConvertNode.Op opcode, Value inputVal) { | |
616 // Variable input = load(inputVal); | |
617 // Variable result = newVariable(opcode.to); | |
618 // switch (opcode) { | |
619 // case I2L: | |
620 // append(new Op1Reg(I2L, result, input)); | |
621 // break; | |
622 // case L2I: | |
623 // append(new Op1Stack(L2I, result, input)); | |
624 // break; | |
625 // case I2B: | |
626 // append(new Op1Stack(I2B, result, input)); | |
627 // break; | |
628 // case I2C: | |
629 // append(new Op1Stack(I2C, result, input)); | |
630 // break; | |
631 // case I2S: | |
632 // append(new Op1Stack(I2S, result, input)); | |
633 // break; | |
634 // case F2D: | |
635 // append(new Op1Reg(F2D, result, input)); | |
636 // break; | |
637 // case D2F: | |
638 // append(new Op1Reg(D2F, result, input)); | |
639 // break; | |
640 // case I2F: | |
641 // append(new Op1Reg(I2F, result, input)); | |
642 // break; | |
643 // case I2D: | |
644 // append(new Op1Reg(I2D, result, input)); | |
645 // break; | |
646 // case F2I: | |
647 // append(new Op1Reg(F2I, result, input)); | |
648 // break; | |
649 // case D2I: | |
650 // append(new Op1Reg(D2I, result, input)); | |
651 // break; | |
652 // case L2F: | |
653 // append(new Op1Reg(L2F, result, input)); | |
654 // break; | |
655 // case L2D: | |
656 // append(new Op1Reg(L2D, result, input)); | |
657 // break; | |
658 // case F2L: | |
659 // append(new Op1Reg(F2L, result, input)); | |
660 // break; | |
661 // case D2L: | |
662 // append(new Op1Reg(D2L, result, input)); | |
663 // break; | |
664 // case MOV_I2F: | |
665 // append(new Op1Reg(MOV_I2F, result, input)); | |
666 // break; | |
667 // case MOV_L2D: | |
668 // append(new Op1Reg(MOV_L2D, result, input)); | |
669 // break; | |
670 // case MOV_F2I: | |
671 // append(new Op1Reg(MOV_F2I, result, input)); | |
672 // break; | |
673 // case MOV_D2L: | |
674 // append(new Op1Reg(MOV_D2L, result, input)); | |
675 // break; | |
676 // case UNSIGNED_I2L: | |
677 // // Instructions that move or generate 32-bit register values also set the upper 32 | |
678 // // bits of the register to zero. | |
679 // // Consequently, there is no need for a special zero-extension move. | |
680 // emitMove(input, result); | |
681 // break; | |
682 // default: | |
683 // throw GraalInternalError.shouldNotReachHere(); | |
684 // } | |
685 // return result; | |
686 throw new InternalError("NYI"); | |
687 } | |
688 | |
689 @Override | |
690 public void emitDeoptimizeOnOverflow(DeoptimizationAction action, DeoptimizationReason reason, Object deoptInfo) { | |
691 // LIRFrameState info = state(); | |
692 // LabelRef stubEntry = createDeoptStub(action, reason, info, deoptInfo); | |
693 // append(new BranchOp(ConditionFlag.overflow, stubEntry, info)); | |
694 throw new InternalError("NYI"); | |
695 } | |
696 | |
697 @Override | |
698 public void emitDeoptimize(DeoptimizationAction action, DeoptimizationReason reason, Object deoptInfo) { | |
699 // LIRFrameState info = state(); | |
700 // LabelRef stubEntry = createDeoptStub(action, reason, info, deoptInfo); | |
701 // append(new JumpOp(stubEntry, info)); | |
702 System.err.println("deopt"); | |
703 } | |
704 | |
705 @Override | |
706 public void emitMembar(int barriers) { | |
707 // int necessaryBarriers = target.arch.requiredBarriers(barriers); | |
708 // if (target.isMP && necessaryBarriers != 0) { | |
709 // append(new MembarOp(necessaryBarriers)); | |
710 // } | |
711 throw new InternalError("NYI"); | |
712 } | |
713 | |
714 @Override | |
715 protected void emitDirectCall(DirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { | |
716 // append(new DirectCallOp(callTarget.target(), result, parameters, temps, callState)); | |
717 throw new InternalError("NYI"); | |
718 } | |
719 | |
720 @Override | |
721 protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { | |
722 // // The current register allocator cannot handle variables at call sites, need a fixed | |
723 // // register. | |
724 // Value targetAddress = AMD64.rax.asValue(); | |
725 // emitMove(operand(callTarget.computedAddress()), targetAddress); | |
726 // append(new IndirectCallOp(callTarget.target(), result, parameters, temps, targetAddress, callState)); | |
727 throw new InternalError("NYI"); | |
728 } | |
729 | |
730 @Override | |
731 protected void emitCall(RuntimeCallTarget callTarget, Value result, Value[] arguments, Value[] temps, Value targetAddress, LIRFrameState info) { | |
732 // if (isConstant(targetAddress)) { | |
733 // append(new DirectCallOp(callTarget, result, arguments, temps, info)); | |
734 // } else { | |
735 // append(new IndirectCallOp(callTarget, result, arguments, temps, targetAddress, info)); | |
736 // } | |
737 throw new InternalError("NYI"); | |
738 } | |
739 | |
740 @Override | |
741 public void emitBitCount(Variable result, Value value) { | |
742 if (value.getKind().getStackKind() == Kind.Int) { | |
743 append(new PTXBitManipulationOp(IPOPCNT, result, value)); | |
744 } else { | |
745 append(new PTXBitManipulationOp(LPOPCNT, result, value)); | |
746 } | |
747 } | |
748 | |
749 @Override | |
750 public void emitBitScanForward(Variable result, Value value) { | |
751 // append(new AMD64BitManipulationOp(BSF, result, value)); | |
752 throw new InternalError("NYI"); | |
753 } | |
754 | |
755 @Override | |
756 public void emitBitScanReverse(Variable result, Value value) { | |
757 // if (value.getKind().getStackKind() == Kind.Int) { | |
758 // append(new AMD64BitManipulationOp(IBSR, result, value)); | |
759 // } else { | |
760 // append(new AMD64BitManipulationOp(LBSR, result, value)); | |
761 // } | |
762 throw new InternalError("NYI"); | |
763 } | |
764 | |
765 @Override | |
766 public void emitMathAbs(Variable result, Variable input) { | |
767 // append(new Op2Reg(DAND, result, input, Constant.forDouble(Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL)))); | |
768 throw new InternalError("NYI"); | |
769 } | |
770 | |
771 @Override | |
772 public void emitMathSqrt(Variable result, Variable input) { | |
773 // append(new AMD64MathIntrinsicOp(SQRT, result, input)); | |
774 throw new InternalError("NYI"); | |
775 } | |
776 | |
777 @Override | |
778 public void emitMathLog(Variable result, Variable input, boolean base10) { | |
779 // append(new AMD64MathIntrinsicOp(base10 ? LOG10 : LOG, result, input)); | |
780 throw new InternalError("NYI"); | |
781 } | |
782 | |
783 @Override | |
784 public void emitMathCos(Variable result, Variable input) { | |
785 // append(new AMD64MathIntrinsicOp(COS, result, input)); | |
786 throw new InternalError("NYI"); | |
787 } | |
788 | |
789 @Override | |
790 public void emitMathSin(Variable result, Variable input) { | |
791 // append(new AMD64MathIntrinsicOp(SIN, result, input)); | |
792 throw new InternalError("NYI"); | |
793 } | |
794 | |
795 @Override | |
796 public void emitMathTan(Variable result, Variable input) { | |
797 // append(new AMD64MathIntrinsicOp(TAN, result, input)); | |
798 throw new InternalError("NYI"); | |
799 } | |
800 | |
801 @Override | |
802 public void emitByteSwap(Variable result, Value input) { | |
803 // append(new AMD64ByteSwapOp(result, input)); | |
804 throw new InternalError("NYI"); | |
805 } | |
806 | |
807 @Override | |
808 protected void emitReturn(Value input) { | |
809 append(new ReturnOp(input)); | |
810 } | |
811 | |
812 @Override | |
813 protected void emitSequentialSwitch(Constant[] keyConstants, LabelRef[] keyTargets, LabelRef defaultTarget, Value key) { | |
814 // // Making a copy of the switch value is necessary because jump table destroys the input | |
815 // // value | |
816 // if (key.getKind() == Kind.Int || key.getKind() == Kind.Long) { | |
817 // append(new SequentialSwitchOp(keyConstants, keyTargets, defaultTarget, key, Value.ILLEGAL)); | |
818 // } else { | |
819 // assert key.getKind() == Kind.Object : key.getKind(); | |
820 // append(new SequentialSwitchOp(keyConstants, keyTargets, defaultTarget, key, newVariable(Kind.Object))); | |
821 // } | |
822 throw new InternalError("NYI"); | |
823 } | |
824 | |
825 @Override | |
826 protected void emitSwitchRanges(int[] lowKeys, int[] highKeys, LabelRef[] targets, LabelRef defaultTarget, Value key) { | |
827 // append(new SwitchRangesOp(lowKeys, highKeys, targets, defaultTarget, key)); | |
828 throw new InternalError("NYI"); | |
829 } | |
830 | |
831 @Override | |
832 protected void emitTableSwitch(int lowKey, LabelRef defaultTarget, LabelRef[] targets, Value key) { | |
833 // // Making a copy of the switch value is necessary because jump table destroys the input | |
834 // // value | |
835 // Variable tmp = emitMove(key); | |
836 // append(new TableSwitchOp(lowKey, defaultTarget, targets, tmp, newVariable(target.wordKind))); | |
837 throw new InternalError("NYI"); | |
838 } | |
839 | |
840 @Override | |
841 protected LabelRef createDeoptStub(DeoptimizationAction action, DeoptimizationReason reason, LIRFrameState info, Object deoptInfo) { | |
842 assert info.topFrame.getBCI() >= 0 : "invalid bci for deopt framestate"; | |
843 PTXDeoptimizationStub stub = new PTXDeoptimizationStub(action, reason, info, deoptInfo); | |
844 lir.stubs.add(stub); | |
845 return LabelRef.forLabel(stub.label); | |
846 } | |
847 | |
848 @Override | |
849 protected void emitNullCheckGuard(ValueNode object) { | |
850 Variable value = load(operand(object)); | |
851 LIRFrameState info = state(); | |
852 append(new NullCheckOp(value, info)); | |
853 } | |
854 | |
855 @Override | |
856 public void visitCompareAndSwap(CompareAndSwapNode node) { | |
857 // Kind kind = node.newValue().kind(); | |
858 // assert kind == node.expected().kind(); | |
859 // | |
860 // Value expected = loadNonConst(operand(node.expected())); | |
861 // Variable newValue = load(operand(node.newValue())); | |
862 // | |
863 // Address address; | |
864 // int displacement = node.displacement(); | |
865 // Value index = operand(node.offset()); | |
866 // if (isConstant(index) && NumUtil.isInt(asConstant(index).asLong() + displacement)) { | |
867 // assert !runtime.needsDataPatch(asConstant(index)); | |
868 // displacement += (int) asConstant(index).asLong(); | |
869 // address = new Address(kind, load(operand(node.object())), displacement); | |
870 // } else { | |
871 // address = new Address(kind, load(operand(node.object())), load(index), Address.Scale.Times1, displacement); | |
872 // } | |
873 // | |
874 // RegisterValue rax = AMD64.rax.asValue(kind); | |
875 // emitMove(expected, rax); | |
876 // append(new CompareAndSwapOp(rax, address, rax, newValue)); | |
877 // | |
878 // Variable result = newVariable(node.kind()); | |
879 // append(new CondMoveOp(result, Condition.EQ, load(Constant.TRUE), Constant.FALSE)); | |
880 // setResult(node, result); | |
881 throw new InternalError("NYI"); | |
882 } | |
883 | |
884 @Override | |
885 public void visitBreakpointNode(BreakpointNode node) { | |
886 // JavaType[] sig = new JavaType[node.arguments.size()]; | |
887 // for (int i = 0; i < sig.length; i++) { | |
888 // sig[i] = node.arguments.get(i).stamp().javaType(runtime); | |
889 // } | |
890 // | |
891 // CallingConvention cc = frameMap.registerConfig.getCallingConvention(CallingConvention.Type.JavaCall, null, sig, target(), false); | |
892 // Value[] parameters = visitInvokeArguments(cc, node.arguments); | |
893 // append(new AMD64BreakpointOp(parameters)); | |
894 throw new InternalError("NYI"); | |
895 } | |
896 } |