30 31 import com.oracle.graal.api.code.*; 32 import com.oracle.graal.api.meta.*; 33 import com.oracle.graal.asm.*; 34 import com.oracle.graal.compiler.gen.*; 35 import com.oracle.graal.compiler.target.*; 36 import com.oracle.graal.debug.*; 37 import com.oracle.graal.graph.*; 38 import com.oracle.graal.lir.*; 39 import com.oracle.graal.lir.StandardOp.JumpOp; 40 import com.oracle.graal.lir.hsail.*; 41 import com.oracle.graal.lir.hsail.HSAILArithmetic.Op1Stack; 42 import com.oracle.graal.lir.hsail.HSAILArithmetic.Op2Reg; 43 import com.oracle.graal.lir.hsail.HSAILArithmetic.Op2Stack; 44 import com.oracle.graal.lir.hsail.HSAILArithmetic.ShiftOp; 45 import com.oracle.graal.lir.hsail.HSAILControlFlow.CompareBranchOp; 46 import com.oracle.graal.lir.hsail.HSAILControlFlow.CondMoveOp; 47 import com.oracle.graal.lir.hsail.HSAILControlFlow.FloatCompareBranchOp; 48 import com.oracle.graal.lir.hsail.HSAILControlFlow.FloatCondMoveOp; 49 import com.oracle.graal.lir.hsail.HSAILControlFlow.ReturnOp; 50 import com.oracle.graal.lir.hsail.HSAILMove.LeaOp; 51 import com.oracle.graal.lir.hsail.HSAILMove.LoadOp; 52 import com.oracle.graal.lir.hsail.HSAILMove.MoveFromRegOp; 53 import com.oracle.graal.lir.hsail.HSAILMove.MoveToRegOp; 54 import com.oracle.graal.lir.hsail.HSAILMove.StoreOp; 55 import com.oracle.graal.nodes.*; 56 import com.oracle.graal.nodes.calc.*; 57 import com.oracle.graal.nodes.java.*; 58 59 /** 60 * This class implements the HSAIL specific portion of the LIR generator. 61 */ 62 public class HSAILLIRGenerator extends LIRGenerator { 63 64 public static class HSAILSpillMoveFactory implements LIR.SpillMoveFactory { 65 66 @Override 67 public LIRInstruction createMove(AllocatableValue dst, Value src) { 68 if (src instanceof HSAILAddressValue) { 69 return new LeaOp(dst, (HSAILAddressValue) src); 70 } else if (isRegister(src) || isStackSlot(dst)) { 71 return new MoveFromRegOp(dst, src); 72 } else { 73 return new MoveToRegOp(dst, src); 74 } 75 } 76 } 77 78 public HSAILLIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) { 79 super(graph, runtime, target, frameMap, cc, lir); 80 lir.spillMoveFactory = new HSAILSpillMoveFactory(); 81 } 82 83 @Override 106 return true; 107 } 108 } 109 110 @Override 111 public Variable emitMove(Value input) { 112 Variable result = newVariable(input.getKind()); 113 emitMove(result, input); 114 return result; 115 } 116 117 @Override 118 public void emitMove(AllocatableValue dst, Value src) { 119 if (isRegister(src) || isStackSlot(dst)) { 120 append(new MoveFromRegOp(dst, src)); 121 } else { 122 append(new MoveToRegOp(dst, src)); 123 } 124 } 125 126 public HSAILAddressValue emitAddress(Value base, long displacement, Value index, int scale) { 127 AllocatableValue baseRegister; 128 long finalDisp = displacement; 129 130 if (isConstant(base)) { 131 if (asConstant(base).isNull()) { 132 baseRegister = Value.ILLEGAL; 133 } else if (asConstant(base).getKind() != Kind.Object) { 134 finalDisp += asConstant(base).asLong(); 135 baseRegister = Value.ILLEGAL; 136 } else { 137 baseRegister = load(base); 138 } 139 } else if (base == Value.ILLEGAL) { 140 baseRegister = Value.ILLEGAL; 141 } else { 142 baseRegister = asAllocatable(base); 143 } 144 if (index != Value.ILLEGAL) { 145 if (isConstant(index)) { 154 indexRegister = convertedIndex; 155 } 156 if (baseRegister == Value.ILLEGAL) { 157 baseRegister = asAllocatable(indexRegister); 158 } else { 159 baseRegister = emitAdd(baseRegister, indexRegister); 160 } 161 } 162 } 163 return new HSAILAddressValue(target().wordKind, baseRegister, finalDisp); 164 } 165 166 private HSAILAddressValue asAddress(Value address) { 167 if (address instanceof HSAILAddressValue) { 168 return (HSAILAddressValue) address; 169 } else { 170 return emitAddress(address, 0, Value.ILLEGAL, 0); 171 } 172 } 173 174 @Override 175 public Variable emitLoad(Kind kind, Value address, DeoptimizingNode deopting) { 176 HSAILAddressValue loadAddress = asAddress(address); 177 Variable result = newVariable(kind); 178 append(new LoadOp(kind, result, loadAddress, deopting != null ? state(deopting) : null)); 179 return result; 180 } 181 182 @Override 183 public void emitStore(Kind kind, Value address, Value inputVal, DeoptimizingNode deopting) { 184 HSAILAddressValue storeAddress = asAddress(address); 185 Variable input = load(inputVal); 186 append(new StoreOp(kind, storeAddress, input, deopting != null ? state(deopting) : null)); 187 } 188 189 @Override 190 public Variable emitAddress(StackSlot address) { 191 throw new InternalError("NYI"); 192 } 193 194 @Override 195 public void emitJump(LabelRef label) { 196 append(new JumpOp(label)); 197 } 198 199 private static HSAILCompare mapKindToCompareOp(Kind kind) { 200 switch (kind) { 201 case Int: 202 return ICMP; 203 case Long: 204 return LCMP; 205 case Float: 206 return FCMP; 443 return result; 444 } 445 446 @Override 447 public Variable emitUDiv(Value a, Value b, DeoptimizingNode deopting) { 448 throw new InternalError("NYI"); 449 } 450 451 @Override 452 public Variable emitURem(Value a, Value b, DeoptimizingNode deopting) { 453 throw new InternalError("NYI"); 454 } 455 456 @Override 457 public Variable emitAnd(Value a, Value b) { 458 Variable result = newVariable(a.getKind()); 459 switch (a.getKind()) { 460 case Int: 461 append(new Op2Stack(IAND, result, a, loadNonConst(b))); 462 break; 463 default: 464 throw GraalInternalError.shouldNotReachHere(); 465 } 466 return result; 467 } 468 469 @Override 470 public Variable emitOr(Value a, Value b) { 471 throw new InternalError("NYI"); 472 } 473 474 @Override 475 public Variable emitXor(Value a, Value b) { 476 throw new InternalError("NYI"); 477 } 478 479 @Override 480 public Variable emitShl(Value a, Value b) { 481 Variable result = newVariable(a.getKind()); 482 switch (a.getKind()) { 483 case Int: 484 append(new ShiftOp(ISHL, result, a, b)); 485 break; 486 default: 487 GraalInternalError.shouldNotReachHere(); 488 } 489 return result; 490 } 491 492 @Override 493 public Variable emitShr(Value a, Value b) { 494 throw new InternalError("NYI"); 495 } 496 497 @Override 498 public Variable emitUShr(Value a, Value b) { 499 Variable result = newVariable(a.getKind()); 500 switch (a.getKind()) { 501 case Int: 502 append(new ShiftOp(IUSHR, result, a, b)); 503 break; 504 default: 505 GraalInternalError.shouldNotReachHere(); 506 } 507 return result; 508 } 509 510 @Override 511 public Variable emitConvert(ConvertNode.Op opcode, Value inputVal) { 512 Variable input = load(inputVal); 513 Variable result = newVariable(opcode.to); 514 switch (opcode) { 515 case I2F: 516 append(new Op1Stack(I2F, result, input)); 517 break; 518 case I2L: 519 append(new Op1Stack(I2L, result, input)); 520 break; 521 case I2D: 522 append(new Op1Stack(I2D, result, input)); 523 break; 544 append(new ReturnOp(Value.ILLEGAL)); 545 } 546 547 @Override 548 public void emitMembar(int barriers) { 549 throw new InternalError("NYI"); 550 } 551 552 @Override 553 protected void emitDirectCall(DirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { 554 throw new InternalError("NYI"); 555 } 556 557 @Override 558 protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { 559 throw new InternalError("NYI"); 560 } 561 562 @Override 563 protected void emitForeignCall(ForeignCallLinkage linkage, Value result, Value[] arguments, Value[] temps, LIRFrameState info) { 564 throw new InternalError("NYI emitForeignCall"); 565 } 566 567 @Override 568 public void emitBitCount(Variable result, Value value) { 569 if (value.getKind().getStackKind() == Kind.Int) { 570 append(new HSAILBitManipulationOp(IPOPCNT, result, value)); 571 } else { 572 append(new HSAILBitManipulationOp(LPOPCNT, result, value)); 573 } 574 } 575 576 @Override 577 public void emitBitScanForward(Variable result, Value value) { 578 throw new InternalError("NYI"); 579 } 580 581 @Override 582 public void emitBitScanReverse(Variable result, Value value) { 583 throw new InternalError("NYI"); 584 } | 30 31 import com.oracle.graal.api.code.*; 32 import com.oracle.graal.api.meta.*; 33 import com.oracle.graal.asm.*; 34 import com.oracle.graal.compiler.gen.*; 35 import com.oracle.graal.compiler.target.*; 36 import com.oracle.graal.debug.*; 37 import com.oracle.graal.graph.*; 38 import com.oracle.graal.lir.*; 39 import com.oracle.graal.lir.StandardOp.JumpOp; 40 import com.oracle.graal.lir.hsail.*; 41 import com.oracle.graal.lir.hsail.HSAILArithmetic.Op1Stack; 42 import com.oracle.graal.lir.hsail.HSAILArithmetic.Op2Reg; 43 import com.oracle.graal.lir.hsail.HSAILArithmetic.Op2Stack; 44 import com.oracle.graal.lir.hsail.HSAILArithmetic.ShiftOp; 45 import com.oracle.graal.lir.hsail.HSAILControlFlow.CompareBranchOp; 46 import com.oracle.graal.lir.hsail.HSAILControlFlow.CondMoveOp; 47 import com.oracle.graal.lir.hsail.HSAILControlFlow.FloatCompareBranchOp; 48 import com.oracle.graal.lir.hsail.HSAILControlFlow.FloatCondMoveOp; 49 import com.oracle.graal.lir.hsail.HSAILControlFlow.ReturnOp; 50 import com.oracle.graal.lir.hsail.HSAILControlFlow.ForeignCallNoOp0; 51 import com.oracle.graal.lir.hsail.HSAILControlFlow.ForeignCallNoOp1; 52 import com.oracle.graal.lir.hsail.HSAILMove.LeaOp; 53 import com.oracle.graal.lir.hsail.HSAILMove.LoadOp; 54 import com.oracle.graal.lir.hsail.HSAILMove.MoveFromRegOp; 55 import com.oracle.graal.lir.hsail.HSAILMove.MoveToRegOp; 56 import com.oracle.graal.lir.hsail.HSAILMove.StoreOp; 57 import com.oracle.graal.lir.hsail.HSAILMove.LoadCompressedPointer; 58 import com.oracle.graal.lir.hsail.HSAILMove.StoreCompressedPointer; 59 import com.oracle.graal.nodes.*; 60 import com.oracle.graal.nodes.calc.*; 61 import com.oracle.graal.nodes.java.*; 62 import com.oracle.graal.hotspot.*; 63 import com.oracle.graal.hotspot.meta.*; 64 65 /** 66 * This class implements the HSAIL specific portion of the LIR generator. 67 */ 68 public class HSAILLIRGenerator extends LIRGenerator { 69 70 private HotSpotRuntime runtime() { 71 return (HotSpotRuntime) runtime; 72 } 73 74 public static class HSAILSpillMoveFactory implements LIR.SpillMoveFactory { 75 76 @Override 77 public LIRInstruction createMove(AllocatableValue dst, Value src) { 78 if (src instanceof HSAILAddressValue) { 79 return new LeaOp(dst, (HSAILAddressValue) src); 80 } else if (isRegister(src) || isStackSlot(dst)) { 81 return new MoveFromRegOp(dst, src); 82 } else { 83 return new MoveToRegOp(dst, src); 84 } 85 } 86 } 87 88 public HSAILLIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) { 89 super(graph, runtime, target, frameMap, cc, lir); 90 lir.spillMoveFactory = new HSAILSpillMoveFactory(); 91 } 92 93 @Override 116 return true; 117 } 118 } 119 120 @Override 121 public Variable emitMove(Value input) { 122 Variable result = newVariable(input.getKind()); 123 emitMove(result, input); 124 return result; 125 } 126 127 @Override 128 public void emitMove(AllocatableValue dst, Value src) { 129 if (isRegister(src) || isStackSlot(dst)) { 130 append(new MoveFromRegOp(dst, src)); 131 } else { 132 append(new MoveToRegOp(dst, src)); 133 } 134 } 135 136 protected HSAILAddressValue asAddressValue(Value address) { 137 if (address instanceof HSAILAddressValue) { 138 return (HSAILAddressValue) address; 139 } else { 140 return emitAddress(address, 0, Value.ILLEGAL, 0); 141 } 142 } 143 144 public HSAILAddressValue emitAddress(Value base, long displacement, Value index, int scale) { 145 AllocatableValue baseRegister; 146 long finalDisp = displacement; 147 148 if (isConstant(base)) { 149 if (asConstant(base).isNull()) { 150 baseRegister = Value.ILLEGAL; 151 } else if (asConstant(base).getKind() != Kind.Object) { 152 finalDisp += asConstant(base).asLong(); 153 baseRegister = Value.ILLEGAL; 154 } else { 155 baseRegister = load(base); 156 } 157 } else if (base == Value.ILLEGAL) { 158 baseRegister = Value.ILLEGAL; 159 } else { 160 baseRegister = asAllocatable(base); 161 } 162 if (index != Value.ILLEGAL) { 163 if (isConstant(index)) { 172 indexRegister = convertedIndex; 173 } 174 if (baseRegister == Value.ILLEGAL) { 175 baseRegister = asAllocatable(indexRegister); 176 } else { 177 baseRegister = emitAdd(baseRegister, indexRegister); 178 } 179 } 180 } 181 return new HSAILAddressValue(target().wordKind, baseRegister, finalDisp); 182 } 183 184 private HSAILAddressValue asAddress(Value address) { 185 if (address instanceof HSAILAddressValue) { 186 return (HSAILAddressValue) address; 187 } else { 188 return emitAddress(address, 0, Value.ILLEGAL, 0); 189 } 190 } 191 192 private static boolean isCompressCandidate(DeoptimizingNode access) { 193 return access != null && ((HeapAccess) access).compress(); 194 } 195 196 @Override 197 public Variable emitLoad(Kind kind, Value address, DeoptimizingNode access) { 198 HSAILAddressValue loadAddress = asAddressValue(address); 199 Variable result = newVariable(kind); 200 LIRFrameState state = access != null ? state(access) : null; 201 assert access == null || access instanceof HeapAccess; 202 if (runtime().config.useCompressedOops && isCompressCandidate(access)) { 203 Variable scratch = newVariable(Kind.Long); 204 append(new LoadCompressedPointer(kind, result, scratch, loadAddress, state, runtime().config.narrowOopBase, runtime().config.narrowOopShift, runtime().config.logMinObjAlignment)); 205 } else { 206 append(new LoadOp(kind, result, loadAddress, state)); 207 } 208 return result; 209 } 210 211 @Override 212 public void emitStore(Kind kind, Value address, Value inputVal, DeoptimizingNode access) { 213 HSAILAddressValue storeAddress = asAddressValue(address); 214 LIRFrameState state = access != null ? state(access) : null; 215 Variable input = load(inputVal); 216 if (runtime().config.useCompressedOops && isCompressCandidate(access)) { 217 Variable scratch = newVariable(Kind.Long); 218 append(new StoreCompressedPointer(kind, storeAddress, input, scratch, state, runtime().config.narrowOopBase, runtime().config.narrowOopShift, runtime().config.logMinObjAlignment)); 219 } else { 220 append(new StoreOp(kind, storeAddress, input, state)); 221 } 222 } 223 224 @Override 225 public Variable emitAddress(StackSlot address) { 226 throw new InternalError("NYI"); 227 } 228 229 @Override 230 public void emitJump(LabelRef label) { 231 append(new JumpOp(label)); 232 } 233 234 private static HSAILCompare mapKindToCompareOp(Kind kind) { 235 switch (kind) { 236 case Int: 237 return ICMP; 238 case Long: 239 return LCMP; 240 case Float: 241 return FCMP; 478 return result; 479 } 480 481 @Override 482 public Variable emitUDiv(Value a, Value b, DeoptimizingNode deopting) { 483 throw new InternalError("NYI"); 484 } 485 486 @Override 487 public Variable emitURem(Value a, Value b, DeoptimizingNode deopting) { 488 throw new InternalError("NYI"); 489 } 490 491 @Override 492 public Variable emitAnd(Value a, Value b) { 493 Variable result = newVariable(a.getKind()); 494 switch (a.getKind()) { 495 case Int: 496 append(new Op2Stack(IAND, result, a, loadNonConst(b))); 497 break; 498 case Long: 499 append(new Op2Stack(LAND, result, a, loadNonConst(b))); 500 break; 501 default: 502 throw GraalInternalError.shouldNotReachHere(); 503 } 504 return result; 505 } 506 507 @Override 508 public Variable emitOr(Value a, Value b) { 509 throw new InternalError("NYI"); 510 } 511 512 @Override 513 public Variable emitXor(Value a, Value b) { 514 throw new InternalError("NYI"); 515 } 516 517 @Override 518 public Variable emitShl(Value a, Value b) { 519 Variable result = newVariable(a.getKind()); 520 switch (a.getKind()) { 521 case Int: 522 append(new ShiftOp(ISHL, result, a, b)); 523 break; 524 case Long: 525 append(new ShiftOp(LSHL, result, a, b)); 526 break; 527 default: 528 GraalInternalError.shouldNotReachHere(); 529 } 530 return result; 531 } 532 533 @Override 534 public Variable emitShr(Value a, Value b) { 535 throw new InternalError("NYI"); 536 } 537 538 @Override 539 public Variable emitUShr(Value a, Value b) { 540 Variable result = newVariable(a.getKind()); 541 switch (a.getKind()) { 542 case Int: 543 append(new ShiftOp(IUSHR, result, a, b)); 544 break; 545 case Long: 546 append(new ShiftOp(LUSHR, result, a, b)); 547 break; 548 default: 549 GraalInternalError.shouldNotReachHere(); 550 } 551 return result; 552 } 553 554 @Override 555 public Variable emitConvert(ConvertNode.Op opcode, Value inputVal) { 556 Variable input = load(inputVal); 557 Variable result = newVariable(opcode.to); 558 switch (opcode) { 559 case I2F: 560 append(new Op1Stack(I2F, result, input)); 561 break; 562 case I2L: 563 append(new Op1Stack(I2L, result, input)); 564 break; 565 case I2D: 566 append(new Op1Stack(I2D, result, input)); 567 break; 588 append(new ReturnOp(Value.ILLEGAL)); 589 } 590 591 @Override 592 public void emitMembar(int barriers) { 593 throw new InternalError("NYI"); 594 } 595 596 @Override 597 protected void emitDirectCall(DirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { 598 throw new InternalError("NYI"); 599 } 600 601 @Override 602 protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { 603 throw new InternalError("NYI"); 604 } 605 606 @Override 607 protected void emitForeignCall(ForeignCallLinkage linkage, Value result, Value[] arguments, Value[] temps, LIRFrameState info) { 608 String callName = linkage.getDescriptor().getName(); 609 if (callName.equals("createOutOfBoundsException") || callName.equals("createNullPointerException")) { 610 // hack Alert !! 611 switch (arguments.length) { 612 case 0: 613 append(new ForeignCallNoOp0(callName, result)); 614 break; 615 case 1: 616 append(new ForeignCallNoOp1(callName, result, arguments[0])); 617 break; 618 default: 619 throw new InternalError("NYI emitForeignCall"); 620 } 621 622 } else { 623 throw new InternalError("NYI emitForeignCall"); 624 } 625 } 626 627 @Override 628 public void emitBitCount(Variable result, Value value) { 629 if (value.getKind().getStackKind() == Kind.Int) { 630 append(new HSAILBitManipulationOp(IPOPCNT, result, value)); 631 } else { 632 append(new HSAILBitManipulationOp(LPOPCNT, result, value)); 633 } 634 } 635 636 @Override 637 public void emitBitScanForward(Variable result, Value value) { 638 throw new InternalError("NYI"); 639 } 640 641 @Override 642 public void emitBitScanReverse(Variable result, Value value) { 643 throw new InternalError("NYI"); 644 } |