45 import org.graalvm.compiler.lir.aarch64.AArch64ArithmeticLIRGeneratorTool; 46 import org.graalvm.compiler.lir.aarch64.AArch64ArithmeticOp; 47 import org.graalvm.compiler.lir.aarch64.AArch64BitManipulationOp; 48 import org.graalvm.compiler.lir.aarch64.AArch64Move.LoadOp; 49 import org.graalvm.compiler.lir.aarch64.AArch64Move.StoreConstantOp; 50 import org.graalvm.compiler.lir.aarch64.AArch64Move.StoreOp; 51 import org.graalvm.compiler.lir.aarch64.AArch64ReinterpretOp; 52 import org.graalvm.compiler.lir.aarch64.AArch64SignExtendOp; 53 import org.graalvm.compiler.lir.aarch64.AArch64Unary; 54 import org.graalvm.compiler.lir.gen.ArithmeticLIRGenerator; 55 56 import jdk.vm.ci.aarch64.AArch64Kind; 57 import jdk.vm.ci.meta.AllocatableValue; 58 import jdk.vm.ci.meta.JavaConstant; 59 import jdk.vm.ci.meta.PlatformKind; 60 import jdk.vm.ci.meta.Value; 61 import jdk.vm.ci.meta.ValueKind; 62 63 public class AArch64ArithmeticLIRGenerator extends ArithmeticLIRGenerator implements AArch64ArithmeticLIRGeneratorTool { 64 65 @Override 66 public AArch64LIRGenerator getLIRGen() { 67 return (AArch64LIRGenerator) super.getLIRGen(); 68 } 69 70 @Override 71 protected boolean isNumericInteger(PlatformKind kind) { 72 return ((AArch64Kind) kind).isInteger(); 73 } 74 75 @Override 76 protected Variable emitAdd(LIRKind resultKind, Value a, Value b, boolean setFlags) { 77 if (isNumericInteger(a.getPlatformKind())) { 78 AArch64ArithmeticOp op = setFlags ? AArch64ArithmeticOp.ADDS : AArch64ArithmeticOp.ADD; 79 return emitBinary(resultKind, op, true, a, b); 80 } else { 81 assert !setFlags : "Cannot set flags on floating point arithmetic"; 82 return emitBinary(resultKind, AArch64ArithmeticOp.FADD, true, a, b); 83 } 84 } 85 86 @Override 87 protected Variable emitSub(LIRKind resultKind, Value a, Value b, boolean setFlags) { 88 if (isNumericInteger(a.getPlatformKind())) { 89 AArch64ArithmeticOp op = setFlags ? AArch64ArithmeticOp.SUBS : AArch64ArithmeticOp.SUB; 465 Variable result = getLIRGen().newVariable(getLIRGen().toRegisterKind(kind)); 466 getLIRGen().append(new LoadOp((AArch64Kind) kind.getPlatformKind(), result, loadAddress, state)); 467 return result; 468 } 469 470 @Override 471 public void emitStore(ValueKind<?> lirKind, Value address, Value inputVal, LIRFrameState state) { 472 AArch64AddressValue storeAddress = getLIRGen().asAddressValue(address); 473 AArch64Kind kind = (AArch64Kind) lirKind.getPlatformKind(); 474 475 if (isJavaConstant(inputVal) && kind.isInteger()) { 476 JavaConstant c = asJavaConstant(inputVal); 477 if (c.isDefaultForKind()) { 478 // We can load 0 directly into integer registers 479 getLIRGen().append(new StoreConstantOp(kind, storeAddress, c, state)); 480 return; 481 } 482 } 483 AllocatableValue input = asAllocatable(inputVal); 484 getLIRGen().append(new StoreOp(kind, storeAddress, input, state)); 485 } 486 487 @Override 488 public void emitCompareOp(AArch64Kind cmpKind, Variable left, Value right) { 489 throw GraalError.unimplemented(); 490 } 491 492 @Override 493 public Value emitRound(Value value, RoundingMode mode) { 494 AArch64ArithmeticOp op; 495 switch (mode) { 496 case NEAREST: 497 op = AArch64ArithmeticOp.FRINTN; 498 break; 499 case UP: 500 op = AArch64ArithmeticOp.FRINTP; 501 break; 502 case DOWN: 503 op = AArch64ArithmeticOp.FRINTM; 504 break; 505 default: 506 throw GraalError.shouldNotReachHere(); 507 } 508 509 return emitUnary(op, value); | 45 import org.graalvm.compiler.lir.aarch64.AArch64ArithmeticLIRGeneratorTool; 46 import org.graalvm.compiler.lir.aarch64.AArch64ArithmeticOp; 47 import org.graalvm.compiler.lir.aarch64.AArch64BitManipulationOp; 48 import org.graalvm.compiler.lir.aarch64.AArch64Move.LoadOp; 49 import org.graalvm.compiler.lir.aarch64.AArch64Move.StoreConstantOp; 50 import org.graalvm.compiler.lir.aarch64.AArch64Move.StoreOp; 51 import org.graalvm.compiler.lir.aarch64.AArch64ReinterpretOp; 52 import org.graalvm.compiler.lir.aarch64.AArch64SignExtendOp; 53 import org.graalvm.compiler.lir.aarch64.AArch64Unary; 54 import org.graalvm.compiler.lir.gen.ArithmeticLIRGenerator; 55 56 import jdk.vm.ci.aarch64.AArch64Kind; 57 import jdk.vm.ci.meta.AllocatableValue; 58 import jdk.vm.ci.meta.JavaConstant; 59 import jdk.vm.ci.meta.PlatformKind; 60 import jdk.vm.ci.meta.Value; 61 import jdk.vm.ci.meta.ValueKind; 62 63 public class AArch64ArithmeticLIRGenerator extends ArithmeticLIRGenerator implements AArch64ArithmeticLIRGeneratorTool { 64 65 public AArch64ArithmeticLIRGenerator(AllocatableValue nullRegisterValue) { 66 this.nullRegisterValue = nullRegisterValue; 67 } 68 69 private final AllocatableValue nullRegisterValue; 70 71 @Override 72 public AArch64LIRGenerator getLIRGen() { 73 return (AArch64LIRGenerator) super.getLIRGen(); 74 } 75 76 public boolean mustReplaceNullWithNullRegister(JavaConstant nullConstant) { 77 /* Uncompressed null pointers only */ 78 return nullRegisterValue != null && JavaConstant.NULL_POINTER.equals(nullConstant); 79 } 80 81 public AllocatableValue getNullRegisterValue() { 82 return nullRegisterValue; 83 } 84 85 @Override 86 protected boolean isNumericInteger(PlatformKind kind) { 87 return ((AArch64Kind) kind).isInteger(); 88 } 89 90 @Override 91 protected Variable emitAdd(LIRKind resultKind, Value a, Value b, boolean setFlags) { 92 if (isNumericInteger(a.getPlatformKind())) { 93 AArch64ArithmeticOp op = setFlags ? AArch64ArithmeticOp.ADDS : AArch64ArithmeticOp.ADD; 94 return emitBinary(resultKind, op, true, a, b); 95 } else { 96 assert !setFlags : "Cannot set flags on floating point arithmetic"; 97 return emitBinary(resultKind, AArch64ArithmeticOp.FADD, true, a, b); 98 } 99 } 100 101 @Override 102 protected Variable emitSub(LIRKind resultKind, Value a, Value b, boolean setFlags) { 103 if (isNumericInteger(a.getPlatformKind())) { 104 AArch64ArithmeticOp op = setFlags ? AArch64ArithmeticOp.SUBS : AArch64ArithmeticOp.SUB; 480 Variable result = getLIRGen().newVariable(getLIRGen().toRegisterKind(kind)); 481 getLIRGen().append(new LoadOp((AArch64Kind) kind.getPlatformKind(), result, loadAddress, state)); 482 return result; 483 } 484 485 @Override 486 public void emitStore(ValueKind<?> lirKind, Value address, Value inputVal, LIRFrameState state) { 487 AArch64AddressValue storeAddress = getLIRGen().asAddressValue(address); 488 AArch64Kind kind = (AArch64Kind) lirKind.getPlatformKind(); 489 490 if (isJavaConstant(inputVal) && kind.isInteger()) { 491 JavaConstant c = asJavaConstant(inputVal); 492 if (c.isDefaultForKind()) { 493 // We can load 0 directly into integer registers 494 getLIRGen().append(new StoreConstantOp(kind, storeAddress, c, state)); 495 return; 496 } 497 } 498 AllocatableValue input = asAllocatable(inputVal); 499 getLIRGen().append(new StoreOp(kind, storeAddress, input, state)); 500 } 501 502 @Override 503 public Value emitRound(Value value, RoundingMode mode) { 504 AArch64ArithmeticOp op; 505 switch (mode) { 506 case NEAREST: 507 op = AArch64ArithmeticOp.FRINTN; 508 break; 509 case UP: 510 op = AArch64ArithmeticOp.FRINTP; 511 break; 512 case DOWN: 513 op = AArch64ArithmeticOp.FRINTM; 514 break; 515 default: 516 throw GraalError.shouldNotReachHere(); 517 } 518 519 return emitUnary(op, value); |