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 }