Mercurial > hg > truffle
comparison graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java @ 8995:585cc62fcdc5
PTX enhancements - arithmetic, control, float, integer math, control and basic switch
author | Morris Meyer <morris.meyer@oracle.com> |
---|---|
date | Wed, 10 Apr 2013 18:51:21 -0400 |
parents | 2c0c708a0ad6 |
children | 9f3a77848ea2 |
comparison
equal
deleted
inserted
replaced
8994:68d07bea21b8 | 8995:585cc62fcdc5 |
---|---|
26 import static com.oracle.graal.api.code.ValueUtil.*; | 26 import static com.oracle.graal.api.code.ValueUtil.*; |
27 import static com.oracle.graal.lir.ptx.PTXArithmetic.*; | 27 import static com.oracle.graal.lir.ptx.PTXArithmetic.*; |
28 import static com.oracle.graal.lir.ptx.PTXBitManipulationOp.IntrinsicOpcode.*; | 28 import static com.oracle.graal.lir.ptx.PTXBitManipulationOp.IntrinsicOpcode.*; |
29 import static com.oracle.graal.lir.ptx.PTXCompare.*; | 29 import static com.oracle.graal.lir.ptx.PTXCompare.*; |
30 | 30 |
31 import com.oracle.graal.api.code.*; | 31 import com.oracle.graal.api.code.AllocatableValue; |
32 import com.oracle.graal.api.meta.*; | 32 import com.oracle.graal.api.code.CodeCacheProvider; |
33 import com.oracle.graal.asm.*; | 33 import com.oracle.graal.api.code.DeoptimizationAction; |
34 import com.oracle.graal.compiler.gen.*; | 34 import com.oracle.graal.api.code.RuntimeCallTarget; |
35 import com.oracle.graal.compiler.target.*; | 35 import com.oracle.graal.api.code.StackSlot; |
36 import com.oracle.graal.graph.*; | 36 import com.oracle.graal.api.code.TargetDescription; |
37 import com.oracle.graal.lir.*; | 37 import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor; |
38 import com.oracle.graal.api.meta.Constant; | |
39 import com.oracle.graal.api.meta.Kind; | |
40 import com.oracle.graal.api.meta.ResolvedJavaMethod; | |
41 import com.oracle.graal.api.meta.Value; | |
42 import com.oracle.graal.asm.NumUtil; | |
43 import com.oracle.graal.compiler.gen.LIRGenerator; | |
44 import com.oracle.graal.compiler.target.LIRGenLowerable; | |
45 import com.oracle.graal.graph.GraalInternalError; | |
46 import com.oracle.graal.lir.FrameMap; | |
47 import com.oracle.graal.lir.LIR; | |
48 import com.oracle.graal.lir.LIRFrameState; | |
49 import com.oracle.graal.lir.LIRInstruction; | |
50 import com.oracle.graal.lir.LIRValueUtil; | |
51 import com.oracle.graal.lir.LabelRef; | |
38 import com.oracle.graal.lir.StandardOp.JumpOp; | 52 import com.oracle.graal.lir.StandardOp.JumpOp; |
39 import com.oracle.graal.lir.ptx.*; | 53 import com.oracle.graal.lir.Variable; |
54 import com.oracle.graal.lir.ptx.PTXAddressValue; | |
40 import com.oracle.graal.lir.ptx.PTXArithmetic.Op1Stack; | 55 import com.oracle.graal.lir.ptx.PTXArithmetic.Op1Stack; |
41 import com.oracle.graal.lir.ptx.PTXArithmetic.Op2Reg; | 56 import com.oracle.graal.lir.ptx.PTXArithmetic.Op2Reg; |
42 import com.oracle.graal.lir.ptx.PTXArithmetic.Op2Stack; | 57 import com.oracle.graal.lir.ptx.PTXArithmetic.Op2Stack; |
43 import com.oracle.graal.lir.ptx.PTXArithmetic.ShiftOp; | 58 import com.oracle.graal.lir.ptx.PTXArithmetic.ShiftOp; |
59 import com.oracle.graal.lir.ptx.PTXBitManipulationOp; | |
44 import com.oracle.graal.lir.ptx.PTXCompare.CompareOp; | 60 import com.oracle.graal.lir.ptx.PTXCompare.CompareOp; |
45 import com.oracle.graal.lir.ptx.PTXControlFlow.BranchOp; | 61 import com.oracle.graal.lir.ptx.PTXControlFlow.BranchOp; |
62 import com.oracle.graal.lir.ptx.PTXControlFlow.CondMoveOp; | |
63 import com.oracle.graal.lir.ptx.PTXControlFlow.FloatCondMoveOp; | |
46 import com.oracle.graal.lir.ptx.PTXControlFlow.ReturnOp; | 64 import com.oracle.graal.lir.ptx.PTXControlFlow.ReturnOp; |
65 import com.oracle.graal.lir.ptx.PTXControlFlow.SequentialSwitchOp; | |
66 import com.oracle.graal.lir.ptx.PTXControlFlow.TableSwitchOp; | |
47 import com.oracle.graal.lir.ptx.PTXMove.LoadOp; | 67 import com.oracle.graal.lir.ptx.PTXMove.LoadOp; |
48 import com.oracle.graal.lir.ptx.PTXMove.MoveFromRegOp; | 68 import com.oracle.graal.lir.ptx.PTXMove.MoveFromRegOp; |
49 import com.oracle.graal.lir.ptx.PTXMove.MoveToRegOp; | 69 import com.oracle.graal.lir.ptx.PTXMove.MoveToRegOp; |
50 import com.oracle.graal.lir.ptx.PTXMove.StoreOp; | 70 import com.oracle.graal.lir.ptx.PTXMove.StoreOp; |
51 import com.oracle.graal.nodes.*; | 71 import com.oracle.graal.nodes.BreakpointNode; |
52 import com.oracle.graal.nodes.calc.*; | 72 import com.oracle.graal.nodes.DeoptimizingNode; |
53 import com.oracle.graal.nodes.java.*; | 73 import com.oracle.graal.nodes.DirectCallTargetNode; |
74 import com.oracle.graal.nodes.IndirectCallTargetNode; | |
75 import com.oracle.graal.nodes.SafepointNode; | |
76 import com.oracle.graal.nodes.StructuredGraph; | |
77 import com.oracle.graal.nodes.ValueNode; | |
78 import com.oracle.graal.nodes.calc.Condition; | |
79 import com.oracle.graal.nodes.calc.ConvertNode; | |
80 import com.oracle.graal.nodes.java.CompareAndSwapNode; | |
54 | 81 |
55 /** | 82 /** |
56 * This class implements the PTX specific portion of the LIR generator. | 83 * This class implements the PTX specific portion of the LIR generator. |
57 */ | 84 */ |
58 public class PTXLIRGenerator extends LIRGenerator { | 85 public class PTXLIRGenerator extends LIRGenerator { |
86 | |
87 public static final Descriptor ARITHMETIC_FREM = new Descriptor("arithmeticFrem", false, float.class, float.class, float.class); | |
88 public static final Descriptor ARITHMETIC_DREM = new Descriptor("arithmeticDrem", false, double.class, double.class, double.class); | |
59 | 89 |
60 public static class PTXSpillMoveFactory implements LIR.SpillMoveFactory { | 90 public static class PTXSpillMoveFactory implements LIR.SpillMoveFactory { |
61 | 91 |
62 @Override | 92 @Override |
63 public LIRInstruction createMove(Value result, Value input) { | 93 public LIRInstruction createMove(Value result, Value input) { |
188 switch (left.getKind().getStackKind()) { | 218 switch (left.getKind().getStackKind()) { |
189 case Int: | 219 case Int: |
190 append(new CompareOp(ICMP, cond, left, right)); | 220 append(new CompareOp(ICMP, cond, left, right)); |
191 append(new BranchOp(cond, label)); | 221 append(new BranchOp(cond, label)); |
192 break; | 222 break; |
223 case Long: | |
224 append(new CompareOp(LCMP, cond, left, right)); | |
225 append(new BranchOp(cond, label)); | |
226 break; | |
227 case Float: | |
228 append(new CompareOp(FCMP, cond, left, right)); | |
229 append(new BranchOp(cond, label)); | |
230 break; | |
231 case Double: | |
232 append(new CompareOp(DCMP, cond, left, right)); | |
233 append(new BranchOp(cond, label)); | |
234 break; | |
193 case Object: | 235 case Object: |
194 append(new CompareOp(ACMP, cond, left, right)); | 236 append(new CompareOp(ACMP, cond, left, right)); |
195 append(new BranchOp(cond, label)); | 237 append(new BranchOp(cond, label)); |
196 break; | 238 break; |
197 default: | 239 default: |
209 throw new InternalError("NYI"); | 251 throw new InternalError("NYI"); |
210 } | 252 } |
211 | 253 |
212 @Override | 254 @Override |
213 public Variable emitConditionalMove(Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) { | 255 public Variable emitConditionalMove(Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) { |
214 throw new InternalError("NYI"); | 256 boolean mirrored = emitCompare(cond, left, right); |
257 Condition finalCondition = mirrored ? cond.mirror() : cond; | |
258 | |
259 Variable result = newVariable(trueValue.getKind()); | |
260 switch (left.getKind().getStackKind()) { | |
261 case Int: | |
262 case Long: | |
263 case Object: | |
264 append(new CondMoveOp(result, finalCondition, load(trueValue), loadNonConst(falseValue))); | |
265 break; | |
266 case Float: | |
267 case Double: | |
268 append(new FloatCondMoveOp(result, finalCondition, unorderedIsTrue, load(trueValue), load(falseValue))); | |
269 break; | |
270 default: | |
271 throw GraalInternalError.shouldNotReachHere("missing: " + left.getKind()); | |
272 } | |
273 return result; | |
274 } | |
275 | |
276 /** | |
277 * This method emits the compare instruction, and may reorder the operands. It returns true if | |
278 * it did so. | |
279 * | |
280 * @param a the left operand of the comparison | |
281 * @param b the right operand of the comparison | |
282 * @return true if the left and right operands were switched, false otherwise | |
283 */ | |
284 private boolean emitCompare(Condition cond, Value a, Value b) { | |
285 Variable left; | |
286 Value right; | |
287 boolean mirrored; | |
288 if (LIRValueUtil.isVariable(b)) { | |
289 left = load(b); | |
290 right = loadNonConst(a); | |
291 mirrored = true; | |
292 } else { | |
293 left = load(a); | |
294 right = loadNonConst(b); | |
295 mirrored = false; | |
296 } | |
297 switch (left.getKind().getStackKind()) { | |
298 case Int: | |
299 append(new CompareOp(ICMP, cond, left, right)); | |
300 break; | |
301 case Long: | |
302 append(new CompareOp(LCMP, cond, left, right)); | |
303 break; | |
304 case Object: | |
305 append(new CompareOp(ACMP, cond, left, right)); | |
306 break; | |
307 case Float: | |
308 append(new CompareOp(FCMP, cond, left, right)); | |
309 break; | |
310 case Double: | |
311 append(new CompareOp(DCMP, cond, left, right)); | |
312 break; | |
313 default: | |
314 throw GraalInternalError.shouldNotReachHere(); | |
315 } | |
316 return mirrored; | |
215 } | 317 } |
216 | 318 |
217 @Override | 319 @Override |
218 public Variable emitIntegerTestMove(Value left, Value right, Value trueValue, Value falseValue) { | 320 public Variable emitIntegerTestMove(Value left, Value right, Value trueValue, Value falseValue) { |
219 throw new InternalError("NYI"); | 321 throw new InternalError("NYI"); |
224 Variable result = newVariable(input.getKind()); | 326 Variable result = newVariable(input.getKind()); |
225 switch (input.getKind()) { | 327 switch (input.getKind()) { |
226 case Int: | 328 case Int: |
227 append(new Op1Stack(INEG, result, input)); | 329 append(new Op1Stack(INEG, result, input)); |
228 break; | 330 break; |
331 case Float: | |
332 append(new Op1Stack(FNEG, result, input)); | |
333 break; | |
334 case Double: | |
335 append(new Op1Stack(DNEG, result, input)); | |
336 break; | |
229 default: | 337 default: |
230 throw GraalInternalError.shouldNotReachHere(); | 338 throw GraalInternalError.shouldNotReachHere(); |
231 } | 339 } |
232 return result; | 340 return result; |
233 } | 341 } |
237 Variable result = newVariable(a.getKind()); | 345 Variable result = newVariable(a.getKind()); |
238 switch (a.getKind()) { | 346 switch (a.getKind()) { |
239 case Int: | 347 case Int: |
240 append(new Op2Stack(IADD, result, a, loadNonConst(b))); | 348 append(new Op2Stack(IADD, result, a, loadNonConst(b))); |
241 break; | 349 break; |
242 default: | 350 case Long: |
243 throw GraalInternalError.shouldNotReachHere(); | 351 append(new Op2Stack(LADD, result, a, loadNonConst(b))); |
352 break; | |
353 case Float: | |
354 append(new Op2Stack(FADD, result, a, loadNonConst(b))); | |
355 break; | |
356 case Double: | |
357 append(new Op2Stack(DADD, result, a, loadNonConst(b))); | |
358 break; | |
359 default: | |
360 throw GraalInternalError.shouldNotReachHere("missing: " + a.getKind() + " prim: " + a.getKind().isPrimitive()); | |
244 } | 361 } |
245 return result; | 362 return result; |
246 } | 363 } |
247 | 364 |
248 @Override | 365 @Override |
250 Variable result = newVariable(a.getKind()); | 367 Variable result = newVariable(a.getKind()); |
251 switch (a.getKind()) { | 368 switch (a.getKind()) { |
252 case Int: | 369 case Int: |
253 append(new Op2Stack(ISUB, result, a, loadNonConst(b))); | 370 append(new Op2Stack(ISUB, result, a, loadNonConst(b))); |
254 break; | 371 break; |
255 default: | 372 case Long: |
256 throw GraalInternalError.shouldNotReachHere(); | 373 append(new Op2Stack(LSUB, result, a, loadNonConst(b))); |
374 break; | |
375 case Float: | |
376 append(new Op2Stack(FSUB, result, a, loadNonConst(b))); | |
377 break; | |
378 case Double: | |
379 append(new Op2Stack(DSUB, result, a, loadNonConst(b))); | |
380 break; | |
381 default: | |
382 throw GraalInternalError.shouldNotReachHere("missing: " + a.getKind()); | |
257 } | 383 } |
258 return result; | 384 return result; |
259 } | 385 } |
260 | 386 |
261 @Override | 387 @Override |
263 Variable result = newVariable(a.getKind()); | 389 Variable result = newVariable(a.getKind()); |
264 switch (a.getKind()) { | 390 switch (a.getKind()) { |
265 case Int: | 391 case Int: |
266 append(new Op2Reg(IMUL, result, a, loadNonConst(b))); | 392 append(new Op2Reg(IMUL, result, a, loadNonConst(b))); |
267 break; | 393 break; |
268 default: | 394 case Long: |
269 throw GraalInternalError.shouldNotReachHere(); | 395 append(new Op2Reg(LMUL, result, a, loadNonConst(b))); |
396 break; | |
397 case Float: | |
398 append(new Op2Stack(FMUL, result, a, loadNonConst(b))); | |
399 break; | |
400 case Double: | |
401 append(new Op2Stack(DMUL, result, a, loadNonConst(b))); | |
402 break; | |
403 default: | |
404 throw GraalInternalError.shouldNotReachHere("missing: " + a.getKind()); | |
270 } | 405 } |
271 return result; | 406 return result; |
272 } | 407 } |
273 | 408 |
274 @Override | 409 @Override |
277 return false; | 412 return false; |
278 } | 413 } |
279 | 414 |
280 @Override | 415 @Override |
281 public Value emitDiv(Value a, Value b, DeoptimizingNode deopting) { | 416 public Value emitDiv(Value a, Value b, DeoptimizingNode deopting) { |
282 throw new InternalError("NYI"); | 417 Variable result = newVariable(a.getKind()); |
418 switch (a.getKind()) { | |
419 case Int: | |
420 append(new Op2Reg(IDIV, result, a, loadNonConst(b))); | |
421 break; | |
422 case Long: | |
423 append(new Op2Reg(LDIV, result, a, loadNonConst(b))); | |
424 break; | |
425 case Float: | |
426 append(new Op2Stack(FDIV, result, a, loadNonConst(b))); | |
427 break; | |
428 case Double: | |
429 append(new Op2Stack(DDIV, result, a, loadNonConst(b))); | |
430 break; | |
431 default: | |
432 throw GraalInternalError.shouldNotReachHere("missing: " + a.getKind()); | |
433 } | |
434 return result; | |
283 } | 435 } |
284 | 436 |
285 @Override | 437 @Override |
286 public Value emitRem(Value a, Value b, DeoptimizingNode deopting) { | 438 public Value emitRem(Value a, Value b, DeoptimizingNode deopting) { |
287 throw new InternalError("NYI"); | 439 Variable result = newVariable(a.getKind()); |
440 switch (a.getKind()) { | |
441 case Int: | |
442 append(new Op2Reg(IREM, result, a, loadNonConst(b))); | |
443 break; | |
444 case Long: | |
445 append(new Op2Reg(LREM, result, a, loadNonConst(b))); | |
446 break; | |
447 default: | |
448 throw GraalInternalError.shouldNotReachHere("missing: " + a.getKind()); | |
449 } | |
450 return result; | |
288 } | 451 } |
289 | 452 |
290 @Override | 453 @Override |
291 public Variable emitUDiv(Value a, Value b, DeoptimizingNode deopting) { | 454 public Variable emitUDiv(Value a, Value b, DeoptimizingNode deopting) { |
292 throw new InternalError("NYI"); | 455 throw new InternalError("NYI"); |
302 Variable result = newVariable(a.getKind()); | 465 Variable result = newVariable(a.getKind()); |
303 switch (a.getKind()) { | 466 switch (a.getKind()) { |
304 case Int: | 467 case Int: |
305 append(new Op2Stack(IAND, result, a, loadNonConst(b))); | 468 append(new Op2Stack(IAND, result, a, loadNonConst(b))); |
306 break; | 469 break; |
470 case Long: | |
471 append(new Op2Stack(LAND, result, a, loadNonConst(b))); | |
472 break; | |
473 | |
474 default: | |
475 throw GraalInternalError.shouldNotReachHere("missing: " + a.getKind()); | |
476 } | |
477 return result; | |
478 } | |
479 | |
480 @Override | |
481 public Variable emitOr(Value a, Value b) { | |
482 Variable result = newVariable(a.getKind()); | |
483 switch (a.getKind()) { | |
484 case Int: | |
485 append(new Op2Stack(IOR, result, a, loadNonConst(b))); | |
486 break; | |
487 case Long: | |
488 append(new Op2Stack(LOR, result, a, loadNonConst(b))); | |
489 break; | |
490 default: | |
491 throw GraalInternalError.shouldNotReachHere("missing: " + a.getKind()); | |
492 } | |
493 return result; | |
494 } | |
495 | |
496 @Override | |
497 public Variable emitXor(Value a, Value b) { | |
498 Variable result = newVariable(a.getKind()); | |
499 switch (a.getKind()) { | |
500 case Int: | |
501 append(new Op2Stack(IXOR, result, a, loadNonConst(b))); | |
502 break; | |
503 case Long: | |
504 append(new Op2Stack(LXOR, result, a, loadNonConst(b))); | |
505 break; | |
307 default: | 506 default: |
308 throw GraalInternalError.shouldNotReachHere(); | 507 throw GraalInternalError.shouldNotReachHere(); |
309 } | 508 } |
310 return result; | 509 return result; |
311 } | 510 } |
312 | |
313 @Override | |
314 public Variable emitOr(Value a, Value b) { | |
315 throw new InternalError("NYI"); | |
316 } | |
317 | |
318 @Override | |
319 public Variable emitXor(Value a, Value b) { | |
320 throw new InternalError("NYI"); | |
321 } | |
322 | 511 |
323 @Override | 512 @Override |
324 public Variable emitShl(Value a, Value b) { | 513 public Variable emitShl(Value a, Value b) { |
325 throw new InternalError("NYI"); | 514 Variable result = newVariable(a.getKind()); |
515 switch (a.getKind()) { | |
516 case Int: | |
517 append(new Op2Stack(ISHL, result, a, loadNonConst(b))); | |
518 break; | |
519 case Long: | |
520 append(new Op1Stack(LSHL, result, loadNonConst(b))); | |
521 break; | |
522 default: | |
523 throw GraalInternalError.shouldNotReachHere(); | |
524 } | |
525 return result; | |
326 } | 526 } |
327 | 527 |
328 @Override | 528 @Override |
329 public Variable emitShr(Value a, Value b) { | 529 public Variable emitShr(Value a, Value b) { |
330 throw new InternalError("NYI"); | 530 Variable result = newVariable(a.getKind()); |
531 switch (a.getKind()) { | |
532 case Int: | |
533 append(new Op2Stack(ISHR, result, a, loadNonConst(b))); | |
534 break; | |
535 case Long: | |
536 append(new Op1Stack(LSHR, result, loadNonConst(b))); | |
537 break; | |
538 default: | |
539 throw GraalInternalError.shouldNotReachHere(); | |
540 } | |
541 return result; | |
331 } | 542 } |
332 | 543 |
333 @Override | 544 @Override |
334 public Variable emitUShr(Value a, Value b) { | 545 public Variable emitUShr(Value a, Value b) { |
335 Variable result = newVariable(a.getKind()); | 546 Variable result = newVariable(a.getKind()); |
336 switch (a.getKind()) { | 547 switch (a.getKind()) { |
337 case Int: | 548 case Int: |
338 append(new ShiftOp(IUSHR, result, a, b)); | 549 append(new ShiftOp(IUSHR, result, a, b)); |
339 break; | 550 break; |
340 default: | 551 case Long: |
341 GraalInternalError.shouldNotReachHere(); | 552 append(new ShiftOp(LUSHR, result, a, b)); |
553 break; | |
554 default: | |
555 throw GraalInternalError.shouldNotReachHere(); | |
342 } | 556 } |
343 return result; | 557 return result; |
344 } | 558 } |
345 | 559 |
346 @Override | 560 @Override |
347 public Variable emitConvert(ConvertNode.Op opcode, Value inputVal) { | 561 public Variable emitConvert(ConvertNode.Op opcode, Value inputVal) { |
348 throw new InternalError("NYI"); | 562 Variable input = load(inputVal); |
563 Variable result = newVariable(opcode.to); | |
564 switch (opcode) { | |
565 case I2L: | |
566 append(new Unary2Op(I2L, result, input)); | |
567 break; | |
568 case L2I: | |
569 append(new Unary1Op(L2I, result, input)); | |
570 break; | |
571 case I2B: | |
572 append(new Unary2Op(I2B, result, input)); | |
573 break; | |
574 case I2C: | |
575 append(new Unary1Op(I2C, result, input)); | |
576 break; | |
577 case I2S: | |
578 append(new Unary2Op(I2S, result, input)); | |
579 break; | |
580 case F2D: | |
581 append(new Unary2Op(F2D, result, input)); | |
582 break; | |
583 case D2F: | |
584 append(new Unary2Op(D2F, result, input)); | |
585 break; | |
586 case I2F: | |
587 append(new Unary2Op(I2F, result, input)); | |
588 break; | |
589 case I2D: | |
590 append(new Unary2Op(I2D, result, input)); | |
591 break; | |
592 case F2I: | |
593 append(new Unary2Op(F2I, result, input)); | |
594 break; | |
595 case D2I: | |
596 append(new Unary2Op(D2I, result, input)); | |
597 break; | |
598 case L2F: | |
599 append(new Unary2Op(L2F, result, input)); | |
600 break; | |
601 case L2D: | |
602 append(new Unary2Op(L2D, result, input)); | |
603 break; | |
604 case F2L: | |
605 append(new Unary2Op(F2L, result, input)); | |
606 break; | |
607 case D2L: | |
608 append(new Unary2Op(D2L, result, input)); | |
609 break; | |
610 case MOV_I2F: | |
611 append(new Unary2Op(MOV_I2F, result, input)); | |
612 break; | |
613 case MOV_L2D: | |
614 append(new Unary2Op(MOV_L2D, result, input)); | |
615 break; | |
616 case MOV_F2I: | |
617 append(new Unary2Op(MOV_F2I, result, input)); | |
618 break; | |
619 case MOV_D2L: | |
620 append(new Unary2Op(MOV_D2L, result, input)); | |
621 break; | |
622 case UNSIGNED_I2L: | |
623 // Instructions that move or generate 32-bit register values also set the upper 32 | |
624 // bits of the register to zero. | |
625 // Consequently, there is no need for a special zero-extension move. | |
626 emitMove(result, input); | |
627 break; | |
628 default: | |
629 throw GraalInternalError.shouldNotReachHere(); | |
630 } | |
631 return result; | |
349 } | 632 } |
350 | 633 |
351 @Override | 634 @Override |
352 public void emitDeoptimize(DeoptimizationAction action, DeoptimizingNode deopting) { | 635 public void emitDeoptimize(DeoptimizationAction action, DeoptimizingNode deopting) { |
353 append(new ReturnOp(Value.ILLEGAL)); | 636 append(new ReturnOp(Value.ILLEGAL)); |
432 append(new ReturnOp(input)); | 715 append(new ReturnOp(input)); |
433 } | 716 } |
434 | 717 |
435 @Override | 718 @Override |
436 protected void emitSequentialSwitch(Constant[] keyConstants, LabelRef[] keyTargets, LabelRef defaultTarget, Value key) { | 719 protected void emitSequentialSwitch(Constant[] keyConstants, LabelRef[] keyTargets, LabelRef defaultTarget, Value key) { |
437 throw new InternalError("NYI"); | 720 // Making a copy of the switch value is necessary because jump table destroys the input |
721 // value | |
722 if (key.getKind() == Kind.Int || key.getKind() == Kind.Long) { | |
723 append(new SequentialSwitchOp(keyConstants, keyTargets, defaultTarget, key, Value.ILLEGAL)); | |
724 } else { | |
725 assert key.getKind() == Kind.Object : key.getKind(); | |
726 append(new SequentialSwitchOp(keyConstants, keyTargets, defaultTarget, key, newVariable(Kind.Object))); | |
727 } | |
438 } | 728 } |
439 | 729 |
440 @Override | 730 @Override |
441 protected void emitSwitchRanges(int[] lowKeys, int[] highKeys, LabelRef[] targets, LabelRef defaultTarget, Value key) { | 731 protected void emitSwitchRanges(int[] lowKeys, int[] highKeys, LabelRef[] targets, LabelRef defaultTarget, Value key) { |
442 throw new InternalError("NYI"); | 732 throw new InternalError("NYI"); |
443 } | 733 } |
444 | 734 |
445 @Override | 735 @Override |
446 protected void emitTableSwitch(int lowKey, LabelRef defaultTarget, LabelRef[] targets, Value key) { | 736 protected void emitTableSwitch(int lowKey, LabelRef defaultTarget, LabelRef[] targets, Value key) { |
447 throw new InternalError("NYI"); | 737 // Making a copy of the switch value is necessary because jump table destroys the input |
738 // value | |
739 Variable tmp = emitMove(key); | |
740 append(new TableSwitchOp(lowKey, defaultTarget, targets, tmp, newVariable(target.wordKind))); | |
448 } | 741 } |
449 | 742 |
450 @Override | 743 @Override |
451 public void visitCompareAndSwap(CompareAndSwapNode node) { | 744 public void visitCompareAndSwap(CompareAndSwapNode node) { |
452 throw new InternalError("NYI"); | 745 throw new InternalError("NYI"); |
457 throw new InternalError("NYI"); | 750 throw new InternalError("NYI"); |
458 } | 751 } |
459 | 752 |
460 @Override | 753 @Override |
461 public void visitSafepointNode(SafepointNode i) { | 754 public void visitSafepointNode(SafepointNode i) { |
755 // LIRFrameState info = state(); | |
756 // append(new PTXSafepointOp(info, runtime().config, this)); | |
462 throw new InternalError("NYI"); | 757 throw new InternalError("NYI"); |
463 } | 758 } |
464 | 759 |
465 @Override | 760 @Override |
466 public void emitUnwind(Value operand) { | 761 public void emitUnwind(Value operand) { |
467 // TODO Auto-generated method stub | 762 throw new InternalError("NYI"); |
468 | |
469 } | 763 } |
470 | 764 |
471 @Override | 765 @Override |
472 public void emitNullCheck(ValueNode v, DeoptimizingNode deopting) { | 766 public void emitNullCheck(ValueNode v, DeoptimizingNode deopting) { |
473 throw new InternalError("NYI"); | 767 throw new InternalError("NYI"); |