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.PTXBitManipulationOp.IntrinsicOpcode.*; 29 import static com.oracle.graal.lir.ptx.PTXCompare.*; 30 31 import com.oracle.graal.api.code.AllocatableValue; 32 import com.oracle.graal.api.code.CodeCacheProvider; 33 import com.oracle.graal.api.code.DeoptimizationAction; 34 import com.oracle.graal.api.code.RuntimeCallTarget; 35 import com.oracle.graal.api.code.StackSlot; 36 import com.oracle.graal.api.code.TargetDescription; 37 import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor; 38 import com.oracle.graal.api.meta.Constant; 39 import com.oracle.graal.api.meta.DeoptimizationReason; 40 import com.oracle.graal.api.meta.Kind; 41 import com.oracle.graal.api.meta.ResolvedJavaMethod; 42 import com.oracle.graal.api.meta.Value; 43 import com.oracle.graal.asm.NumUtil; 44 import com.oracle.graal.compiler.gen.LIRGenerator; 45 import com.oracle.graal.compiler.target.LIRGenLowerable; 46 import com.oracle.graal.graph.GraalInternalError; 47 import com.oracle.graal.lir.FrameMap; 48 import com.oracle.graal.lir.LIR; 49 import com.oracle.graal.lir.LIRFrameState; 50 import com.oracle.graal.lir.LIRInstruction; 51 import com.oracle.graal.lir.LIRValueUtil; 52 import com.oracle.graal.lir.LabelRef; 53 import com.oracle.graal.lir.StandardOp.JumpOp; 54 import com.oracle.graal.lir.Variable; 55 import com.oracle.graal.lir.ptx.PTXAddressValue; 56 import com.oracle.graal.lir.ptx.PTXArithmetic.Op1Stack; 57 import com.oracle.graal.lir.ptx.PTXArithmetic.Op2Reg; 58 import com.oracle.graal.lir.ptx.PTXArithmetic.Op2Stack; 59 import com.oracle.graal.lir.ptx.PTXArithmetic.ShiftOp; 60 import com.oracle.graal.lir.ptx.PTXBitManipulationOp; 61 import com.oracle.graal.lir.ptx.PTXCompare.CompareOp; 62 import com.oracle.graal.lir.ptx.PTXControlFlow.BranchOp; 63 import com.oracle.graal.lir.ptx.PTXControlFlow.ReturnOp; 64 import com.oracle.graal.lir.ptx.PTXControlFlow.CondMoveOp; 65 import com.oracle.graal.lir.ptx.PTXControlFlow.FloatCondMoveOp; 66 import com.oracle.graal.lir.ptx.PTXMove.LoadOp; 67 import com.oracle.graal.lir.ptx.PTXMove.MoveFromRegOp; 68 import com.oracle.graal.lir.ptx.PTXMove.MoveToRegOp; 69 import com.oracle.graal.lir.ptx.PTXMove.StoreOp; 70 import com.oracle.graal.nodes.BreakpointNode; 71 import com.oracle.graal.nodes.DirectCallTargetNode; 72 import com.oracle.graal.nodes.IndirectCallTargetNode; 73 import com.oracle.graal.nodes.SafepointNode; 74 import com.oracle.graal.nodes.StructuredGraph; 75 import com.oracle.graal.nodes.ValueNode; 76 import com.oracle.graal.nodes.calc.Condition; 77 import com.oracle.graal.nodes.calc.ConvertNode; 78 import com.oracle.graal.nodes.java.CompareAndSwapNode; 79 import com.oracle.graal.nodes.java.ExceptionObjectNode; 80 81 /** 82 * This class implements the PTX specific portion of the LIR generator. 83 */ 84 public class PTXLIRGenerator extends LIRGenerator { 85 86 public static final Descriptor ARITHMETIC_FREM = new Descriptor("arithmeticFrem", false, float.class, float.class, float.class); 87 public static final Descriptor ARITHMETIC_DREM = new Descriptor("arithmeticDrem", false, double.class, double.class, double.class); 88 89 public static class PTXSpillMoveFactory implements LIR.SpillMoveFactory { 90 91 @Override 92 public LIRInstruction createMove(Value result, Value input) { 93 throw new InternalError("NYI"); 94 } 95 } 96 97 public PTXLIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, ResolvedJavaMethod method, LIR lir) { 98 super(graph, runtime, target, frameMap, method, lir); 99 lir.spillMoveFactory = new PTXSpillMoveFactory(); 100 } 101 102 @Override 103 protected void emitNode(ValueNode node) { 104 if (node instanceof LIRGenLowerable) { 105 ((LIRGenLowerable) node).generate(this); 106 } else { 107 super.emitNode(node); 108 } 109 } 110 111 @Override 112 public boolean canStoreConstant(Constant c) { 113 // Operand b must be in the .reg state space. 114 return false; 115 } 116 117 @Override 118 public boolean canInlineConstant(Constant c) { 119 switch (c.getKind()) { 120 case Long: 121 return NumUtil.isInt(c.asLong()) && !runtime.needsDataPatch(c); 122 case Object: 123 return c.isNull(); 124 default: 125 return true; 126 } 127 } 128 129 @Override 130 public Variable emitMove(Value input) { 131 Variable result = newVariable(input.getKind()); 132 emitMove(result, input); 133 return result; 134 } 135 136 @Override 137 public void emitMove(Value dst, Value src) { 138 if (isRegister(src) || isStackSlot(dst)) { 139 append(new MoveFromRegOp(dst, src)); 140 } else { 141 append(new MoveToRegOp(dst, src)); 142 } 143 } 144 145 private PTXAddressValue prepareAddress(Kind kind, Value base, int displacement, Value index, int scale) { 146 AllocatableValue baseRegister; 147 long finalDisp = displacement; 148 if (isConstant(base)) { 149 if (asConstant(base).isNull()) { 150 baseRegister = AllocatableValue.UNUSED; 151 } else if (asConstant(base).getKind() != Kind.Object) { 152 finalDisp += asConstant(base).asLong(); 153 baseRegister = AllocatableValue.UNUSED; 154 } else { 155 baseRegister = load(base); 156 } 157 } else if (base == Value.ILLEGAL) { 158 baseRegister = AllocatableValue.UNUSED; 159 } else { 160 baseRegister = asAllocatable(base); 161 } 162 163 if (index != Value.ILLEGAL) { 164 if (isConstant(index)) { 165 finalDisp += asConstant(index).asLong() * scale; 166 } else { 167 Value indexRegister; 168 if (scale != 1) { 169 indexRegister = emitMul(index, Constant.forInt(scale)); 170 } else { 171 indexRegister = index; 172 } 173 174 if (baseRegister == AllocatableValue.UNUSED) { 175 baseRegister = asAllocatable(indexRegister); 176 } else { 177 baseRegister = emitAdd(baseRegister, indexRegister); 178 } 179 } 180 } 181 182 return new PTXAddressValue(kind, baseRegister, finalDisp); 183 } 184 185 @Override 186 public Variable emitLoad(Kind kind, Value base, int displacement, Value index, int scale, boolean canTrap) { 187 PTXAddressValue loadAddress = prepareAddress(kind, base, displacement, index, scale); 188 Variable result = newVariable(loadAddress.getKind()); 189 append(new LoadOp(result, loadAddress, canTrap ? state() : null)); 190 return result; 191 } 192 193 @Override 194 public void emitStore(Kind kind, Value base, int displacement, Value index, int scale, Value inputVal, boolean canTrap) { 195 PTXAddressValue storeAddress = prepareAddress(kind, base, displacement, index, scale); 196 Variable input = load(inputVal); 197 append(new StoreOp(storeAddress, input, canTrap ? state() : null)); 198 } 199 200 @Override 201 public Variable emitLea(Value base, int displacement, Value index, int scale) { 202 throw new InternalError("NYI"); 203 } 204 205 @Override 206 public Variable emitLea(StackSlot address) { 207 throw new InternalError("NYI"); 208 } 209 210 @Override 211 public void emitJump(LabelRef label) { 212 append(new JumpOp(label)); 213 } 214 215 @Override 216 public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef label) { 217 switch (left.getKind().getStackKind()) { 218 case Int: 219 append(new CompareOp(ICMP, cond, left, right)); 220 append(new BranchOp(cond, label)); 221 break; 222 case Long: 223 append(new CompareOp(LCMP, cond, left, right)); 224 append(new BranchOp(cond, label)); 225 break; 226 case Float: 227 append(new CompareOp(FCMP, cond, left, right)); 228 append(new BranchOp(cond, label)); 229 break; 230 case Double: 231 append(new CompareOp(DCMP, cond, left, right)); 232 append(new BranchOp(cond, label)); 233 break; 234 case Object: 235 append(new CompareOp(ACMP, cond, left, right)); 236 append(new BranchOp(cond, label)); 237 break; 238 default: 239 System.err.println("missing: " + left.getKind()); 240 throw GraalInternalError.shouldNotReachHere("" + left.getKind()); 241 } 242 } 243 244 @Override 245 public void emitOverflowCheckBranch(LabelRef label, boolean negated) { 246 throw new InternalError("NYI"); 247 } 248 249 @Override 250 public void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef label) { 251 throw new InternalError("NYI"); 252 } 253 254 @Override 255 public Variable emitConditionalMove(Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) { 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("" + 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; 317 } 318 319 @Override 320 public Variable emitIntegerTestMove(Value left, Value right, Value trueValue, Value falseValue) { 321 throw new InternalError("NYI"); 322 } 323 324 @Override 325 public Variable emitNegate(Value input) { 326 Variable result = newVariable(input.getKind()); 327 switch (input.getKind()) { 328 case Int: 329 append(new Op1Stack(INEG, result, input)); 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; 337 default: 338 throw GraalInternalError.shouldNotReachHere(); 339 } 340 return result; 341 } 342 343 @Override 344 public Variable emitAdd(Value a, Value b) { 345 Variable result = newVariable(a.getKind()); 346 switch (a.getKind()) { 347 case Int: 348 append(new Op2Stack(IADD, result, a, loadNonConst(b))); 349 break; 350 case Long: 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(); 361 } 362 return result; 363 } 364 365 @Override 366 public Variable emitSub(Value a, Value b) { 367 Variable result = newVariable(a.getKind()); 368 switch (a.getKind()) { 369 case Int: 370 append(new Op2Stack(ISUB, result, a, loadNonConst(b))); 371 break; 372 case Long: 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 System.err.println("missing: " + a.getKind()); 383 throw GraalInternalError.shouldNotReachHere(); 384 } 385 return result; 386 } 387 388 @Override 389 public Variable emitMul(Value a, Value b) { 390 Variable result = newVariable(a.getKind()); 391 switch (a.getKind()) { 392 case Int: 393 append(new Op2Reg(IMUL, result, a, loadNonConst(b))); 394 break; 395 case Long: 396 append(new Op2Reg(LMUL, result, a, loadNonConst(b))); 397 break; 398 case Float: 399 append(new Op2Stack(FMUL, result, a, loadNonConst(b))); 400 break; 401 case Double: 402 append(new Op2Stack(DMUL, result, a, loadNonConst(b))); 403 break; 404 default: 405 System.err.println("missing: " + a.getKind()); 406 throw GraalInternalError.shouldNotReachHere(); 407 } 408 return result; 409 } 410 411 @Override 412 protected boolean peephole(ValueNode valueNode) { 413 // No peephole optimizations for now 414 return false; 415 } 416 417 @Override 418 public Value emitDiv(Value a, Value b) { 419 Variable result = newVariable(a.getKind()); 420 switch (a.getKind()) { 421 case Int: 422 append(new Op2Reg(IDIV, result, a, loadNonConst(b))); 423 break; 424 case Long: 425 append(new Op2Reg(LDIV, result, a, loadNonConst(b))); 426 break; 427 case Float: 428 append(new Op2Stack(FDIV, result, a, loadNonConst(b))); 429 break; 430 case Double: 431 append(new Op2Stack(DDIV, result, a, loadNonConst(b))); 432 break; 433 default: 434 System.err.println("missing: " + a.getKind()); 435 throw GraalInternalError.shouldNotReachHere(); 436 } 437 return result; 438 } 439 440 @Override 441 public Value emitRem(Value a, Value b) { 442 Variable result = newVariable(a.getKind()); 443 switch (a.getKind()) { 444 case Int: 445 append(new Op2Reg(IREM, result, a, loadNonConst(b))); 446 break; 447 case Long: 448 append(new Op2Reg(LREM, result, a, loadNonConst(b))); 449 break; 450 /* 451 * not correct - these need to call the PTX double-precision remainder() function 452 case Float: { 453 RuntimeCallTarget stub = runtime.lookupRuntimeCall(ARITHMETIC_FREM); 454 return emitCall(stub, stub.getCallingConvention(), false, a, b); 455 } 456 case Double: { 457 RuntimeCallTarget stub = runtime.lookupRuntimeCall(ARITHMETIC_DREM); 458 return emitCall(stub, stub.getCallingConvention(), false, a, b); 459 } 460 */ 461 default: 462 System.err.println("missing: " + a.getKind()); 463 throw GraalInternalError.shouldNotReachHere(); 464 } 465 return result; 466 } 467 468 @Override 469 public Variable emitUDiv(Value a, Value b) { 470 throw new InternalError("NYI"); 471 } 472 473 @Override 474 public Variable emitURem(Value a, Value b) { 475 throw new InternalError("NYI"); 476 } 477 478 @Override 479 public Variable emitAnd(Value a, Value b) { 480 Variable result = newVariable(a.getKind()); 481 switch (a.getKind()) { 482 case Int: 483 append(new Op2Stack(IAND, result, a, loadNonConst(b))); 484 break; 485 case Long: 486 append(new Op2Stack(LAND, result, a, loadNonConst(b))); 487 break; 488 489 default: 490 System.err.println("missing: " + a.getKind()); 491 throw GraalInternalError.shouldNotReachHere(); 492 } 493 return result; 494 } 495 496 @Override 497 public Variable emitOr(Value a, Value b) { 498 Variable result = newVariable(a.getKind()); 499 switch (a.getKind()) { 500 case Int: 501 append(new Op2Stack(IOR, result, a, loadNonConst(b))); 502 break; 503 case Long: 504 append(new Op2Stack(LOR, result, a, loadNonConst(b))); 505 break; 506 default: 507 System.err.println("missing: " + a.getKind()); 508 throw GraalInternalError.shouldNotReachHere(); 509 } 510 return result; 511 } 512 513 @Override 514 public Variable emitXor(Value a, Value b) { 515 Variable result = newVariable(a.getKind()); 516 switch (a.getKind()) { 517 case Int: 518 append(new Op2Stack(IXOR, result, a, loadNonConst(b))); 519 break; 520 case Long: 521 append(new Op2Stack(LXOR, result, a, loadNonConst(b))); 522 break; 523 default: 524 throw GraalInternalError.shouldNotReachHere(); 525 } 526 return result; 527 } 528 529 @Override 530 public Variable emitShl(Value a, Value b) { 531 Variable result = newVariable(a.getKind()); 532 switch (a.getKind()) { 533 case Int: 534 append(new Op2Stack(ISHL, result, a, loadNonConst(b))); 535 break; 536 case Long: 537 append(new Op2Stack(LSHL, result, a, loadNonConst(b))); 538 break; 539 default: 540 throw GraalInternalError.shouldNotReachHere(); 541 } 542 return result; 543 } 544 545 @Override 546 public Variable emitShr(Value a, Value b) { 547 Variable result = newVariable(a.getKind()); 548 switch (a.getKind()) { 549 case Int: 550 append(new Op2Stack(ISHR, result, a, loadNonConst(b))); 551 break; 552 case Long: 553 append(new Op2Stack(LSHR, result, a, loadNonConst(b))); 554 break; 555 default: 556 throw GraalInternalError.shouldNotReachHere(); 557 } 558 return result; 559 } 560 561 @Override 562 public Variable emitUShr(Value a, Value b) { 563 Variable result = newVariable(a.getKind()); 564 switch (a.getKind()) { 565 case Int: 566 append(new ShiftOp(IUSHR, result, a, b)); 567 break; 568 case Long: 569 append(new ShiftOp(LUSHR, result, a, b)); 570 break; 571 default: 572 GraalInternalError.shouldNotReachHere(); 573 } 574 return result; 575 } 576 577 @Override 578 public Variable emitConvert(ConvertNode.Op opcode, Value inputVal) { 579 Variable input = load(inputVal); 580 Variable result = newVariable(opcode.to); 581 switch (opcode) { 582 case I2L: 583 append(new Unary2Op(I2L, result, input)); 584 break; 585 case L2I: 586 append(new Unary1Op(L2I, result, input)); 587 break; 588 case I2B: 589 append(new Unary2Op(I2B, result, input)); 590 break; 591 case I2C: 592 append(new Unary1Op(I2C, result, input)); 593 break; 594 case I2S: 595 append(new Unary2Op(I2S, result, input)); 596 break; 597 case F2D: 598 append(new Unary2Op(F2D, result, input)); 599 break; 600 case D2F: 601 append(new Unary2Op(D2F, result, input)); 602 break; 603 case I2F: 604 append(new Unary2Op(I2F, result, input)); 605 break; 606 case I2D: 607 append(new Unary2Op(I2D, result, input)); 608 break; 609 case F2I: 610 append(new Unary2Op(F2I, result, input)); 611 break; 612 case D2I: 613 append(new Unary2Op(D2I, result, input)); 614 break; 615 case L2F: 616 append(new Unary2Op(L2F, result, input)); 617 break; 618 case L2D: 619 append(new Unary2Op(L2D, result, input)); 620 break; 621 case F2L: 622 append(new Unary2Op(F2L, result, input)); 623 break; 624 case D2L: 625 append(new Unary2Op(D2L, result, input)); 626 break; 627 case MOV_I2F: 628 append(new Unary2Op(MOV_I2F, result, input)); 629 break; 630 case MOV_L2D: 631 append(new Unary2Op(MOV_L2D, result, input)); 632 break; 633 case MOV_F2I: 634 append(new Unary2Op(MOV_F2I, result, input)); 635 break; 636 case MOV_D2L: 637 append(new Unary2Op(MOV_D2L, result, input)); 638 break; 639 case UNSIGNED_I2L: 640 // Instructions that move or generate 32-bit register values also set the upper 32 641 // bits of the register to zero. 642 // Consequently, there is no need for a special zero-extension move. 643 emitMove(result, input); 644 break; 645 default: 646 throw GraalInternalError.shouldNotReachHere(); 647 } 648 return result; 649 } 650 651 @Override 652 public void emitDeoptimize(DeoptimizationAction action, DeoptimizationReason reason) { 653 append(new ReturnOp(Value.ILLEGAL)); 654 } 655 656 @Override 657 public void emitMembar(int barriers) { 658 throw new InternalError("NYI"); 659 } 660 661 @Override 662 protected void emitDirectCall(DirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { 663 throw new InternalError("NYI"); 664 } 665 666 @Override 667 protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { 668 throw new InternalError("NYI"); 669 } 670 671 @Override 672 protected void emitCall(RuntimeCallTarget callTarget, Value result, Value[] arguments, Value[] temps, LIRFrameState info) { 673 throw new InternalError("NYI"); 674 } 675 676 @Override 677 public void emitBitCount(Variable result, Value value) { 678 if (value.getKind().getStackKind() == Kind.Int) { 679 append(new PTXBitManipulationOp(IPOPCNT, result, value)); 680 } else { 681 append(new PTXBitManipulationOp(LPOPCNT, result, value)); 682 } 683 } 684 685 @Override 686 public void emitBitScanForward(Variable result, Value value) { 687 throw new InternalError("NYI"); 688 } 689 690 @Override 691 public void emitBitScanReverse(Variable result, Value value) { 692 throw new InternalError("NYI"); 693 } 694 695 @Override 696 public void emitMathAbs(Variable result, Variable input) { 697 throw new InternalError("NYI"); 698 } 699 700 @Override 701 public void emitMathSqrt(Variable result, Variable input) { 702 throw new InternalError("NYI"); 703 } 704 705 @Override 706 public void emitMathLog(Variable result, Variable input, boolean base10) { 707 throw new InternalError("NYI"); 708 } 709 710 @Override 711 public void emitMathCos(Variable result, Variable input) { 712 throw new InternalError("NYI"); 713 } 714 715 @Override 716 public void emitMathSin(Variable result, Variable input) { 717 throw new InternalError("NYI"); 718 } 719 720 @Override 721 public void emitMathTan(Variable result, Variable input) { 722 throw new InternalError("NYI"); 723 } 724 725 @Override 726 public void emitByteSwap(Variable result, Value input) { 727 throw new InternalError("NYI"); 728 } 729 730 @Override 731 protected void emitReturn(Value input) { 732 append(new ReturnOp(input)); 733 } 734 735 @Override 736 protected void emitSequentialSwitch(Constant[] keyConstants, LabelRef[] keyTargets, LabelRef defaultTarget, Value key) { 737 // Making a copy of the switch value is necessary because jump table destroys the input 738 // value 739 if (key.getKind() == Kind.Int || key.getKind() == Kind.Long) { 740 // append(new SequentialSwitchOp(keyConstants, keyTargets, defaultTarget, key, Value.ILLEGAL)); 741 } else { 742 assert key.getKind() == Kind.Object : key.getKind(); 743 // append(new SequentialSwitchOp(keyConstants, keyTargets, defaultTarget, key, newVariable(Kind.Object))); 744 } 745 throw new InternalError("NYI"); 746 } 747 748 @Override 749 protected void emitSwitchRanges(int[] lowKeys, int[] highKeys, LabelRef[] targets, LabelRef defaultTarget, Value key) { 750 throw new InternalError("NYI"); 751 } 752 753 @Override 754 protected void emitTableSwitch(int lowKey, LabelRef defaultTarget, LabelRef[] targets, Value key) { 755 throw new InternalError("NYI"); 756 } 757 758 @Override 759 public void visitCompareAndSwap(CompareAndSwapNode node) { 760 throw new InternalError("NYI"); 761 } 762 763 @Override 764 public void visitBreakpointNode(BreakpointNode node) { 765 throw new InternalError("NYI"); 766 } 767 768 @Override 769 public void visitExceptionObject(ExceptionObjectNode i) { 770 throw new InternalError("NYI"); 771 } 772 773 @Override 774 public void visitSafepointNode(SafepointNode i) { 775 LIRFrameState info = state(); 776 // append(new PTXSafepointOp(info, runtime().config, this)); 777 } 778 779 @Override 780 public void emitUnwind(Value operand) { 781 // TODO Auto-generated method stub 782 783 } 784 785 @Override 786 public void emitNullCheck(ValueNode v) { 787 throw new InternalError("NYI"); 788 } 789 }