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