1 /*
2 * Copyright (c) 2013, 2018, 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 */
49 import org.graalvm.compiler.lir.aarch64.AArch64ArrayCompareToOp;
50 import org.graalvm.compiler.lir.aarch64.AArch64ArrayEqualsOp;
51 import org.graalvm.compiler.lir.aarch64.AArch64ByteSwapOp;
52 import org.graalvm.compiler.lir.aarch64.AArch64Compare;
53 import org.graalvm.compiler.lir.aarch64.AArch64ControlFlow;
54 import org.graalvm.compiler.lir.aarch64.AArch64ControlFlow.BranchOp;
55 import org.graalvm.compiler.lir.aarch64.AArch64ControlFlow.CompareBranchZeroOp;
56 import org.graalvm.compiler.lir.aarch64.AArch64ControlFlow.CondMoveOp;
57 import org.graalvm.compiler.lir.aarch64.AArch64ControlFlow.CondSetOp;
58 import org.graalvm.compiler.lir.aarch64.AArch64ControlFlow.StrategySwitchOp;
59 import org.graalvm.compiler.lir.aarch64.AArch64ControlFlow.TableSwitchOp;
60 import org.graalvm.compiler.lir.aarch64.AArch64LIRFlagsVersioned;
61 import org.graalvm.compiler.lir.aarch64.AArch64Move;
62 import org.graalvm.compiler.lir.aarch64.AArch64AtomicMove.AtomicReadAndAddOp;
63 import org.graalvm.compiler.lir.aarch64.AArch64AtomicMove.AtomicReadAndAddLSEOp;
64 import org.graalvm.compiler.lir.aarch64.AArch64AtomicMove.CompareAndSwapOp;
65 import org.graalvm.compiler.lir.aarch64.AArch64AtomicMove.AtomicReadAndWriteOp;
66 import org.graalvm.compiler.lir.aarch64.AArch64Move.MembarOp;
67 import org.graalvm.compiler.lir.aarch64.AArch64PauseOp;
68 import org.graalvm.compiler.lir.aarch64.AArch64SpeculativeBarrier;
69 import org.graalvm.compiler.lir.gen.LIRGenerationResult;
70 import org.graalvm.compiler.lir.gen.LIRGenerator;
71 import org.graalvm.compiler.phases.util.Providers;
72
73 import jdk.vm.ci.aarch64.AArch64;
74 import jdk.vm.ci.aarch64.AArch64Kind;
75 import jdk.vm.ci.code.CallingConvention;
76 import jdk.vm.ci.code.RegisterValue;
77 import jdk.vm.ci.meta.AllocatableValue;
78 import jdk.vm.ci.meta.JavaConstant;
79 import jdk.vm.ci.meta.JavaKind;
80 import jdk.vm.ci.meta.PlatformKind;
81 import jdk.vm.ci.meta.PrimitiveConstant;
82 import jdk.vm.ci.meta.Value;
83 import jdk.vm.ci.meta.ValueKind;
84
85 public abstract class AArch64LIRGenerator extends LIRGenerator {
86
87 public AArch64LIRGenerator(LIRKindTool lirKindTool, AArch64ArithmeticLIRGenerator arithmeticLIRGen, MoveFactory moveFactory, Providers providers, LIRGenerationResult lirGenRes) {
88 super(lirKindTool, arithmeticLIRGen, moveFactory, providers, lirGenRes);
513 append(new AArch64ByteSwapOp(result, input));
514 return result;
515 }
516
517 @Override
518 public Variable emitArrayCompareTo(JavaKind kind1, JavaKind kind2, Value array1, Value array2, Value length1, Value length2) {
519 LIRKind resultKind = LIRKind.value(AArch64Kind.DWORD);
520 // DMS TODO: check calling conversion and registers used
521 RegisterValue res = AArch64.r0.asValue(resultKind);
522 RegisterValue cnt1 = AArch64.r1.asValue(length1.getValueKind());
523 RegisterValue cnt2 = AArch64.r2.asValue(length2.getValueKind());
524 emitMove(cnt1, length1);
525 emitMove(cnt2, length2);
526 append(new AArch64ArrayCompareToOp(this, kind1, kind2, res, array1, array2, cnt1, cnt2));
527 Variable result = newVariable(resultKind);
528 emitMove(result, res);
529 return result;
530 }
531
532 @Override
533 public Variable emitArrayEquals(JavaKind kind, Value array1, Value array2, Value length, int constantLength, boolean directPointers) {
534 Variable result = newVariable(LIRKind.value(AArch64Kind.DWORD));
535 append(new AArch64ArrayEqualsOp(this, kind, result, array1, array2, asAllocatable(length), directPointers));
536 return result;
537 }
538
539 @Override
540 protected JavaConstant zapValueForKind(PlatformKind kind) {
541 long dead = 0xDEADDEADDEADDEADL;
542 switch ((AArch64Kind) kind) {
543 case BYTE:
544 return JavaConstant.forByte((byte) dead);
545 case WORD:
546 return JavaConstant.forShort((short) dead);
547 case DWORD:
548 return JavaConstant.forInt((int) dead);
549 case QWORD:
550 return JavaConstant.forLong(dead);
551 case SINGLE:
552 return JavaConstant.forFloat(Float.intBitsToFloat((int) dead));
553 case DOUBLE:
565 * This avoids generating the following code: mov x0, x19 # x19 is fixed thread register ldr x0,
566 * [x0] instead of: ldr x0, [x19].
567 */
568 protected AllocatableValue loadReg(Value val) {
569 if (!(val instanceof Variable || val instanceof RegisterValue)) {
570 return emitMove(val);
571 }
572 return (AllocatableValue) val;
573 }
574
575 @Override
576 public void emitPause() {
577 append(new AArch64PauseOp());
578 }
579
580 public abstract void emitCCall(long address, CallingConvention nativeCallingConvention, Value[] args);
581
582 @Override
583 public void emitSpeculationFence() {
584 append(new AArch64SpeculativeBarrier());
585 }
586 }
|
1 /*
2 * Copyright (c) 2013, 2019, 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 */
49 import org.graalvm.compiler.lir.aarch64.AArch64ArrayCompareToOp;
50 import org.graalvm.compiler.lir.aarch64.AArch64ArrayEqualsOp;
51 import org.graalvm.compiler.lir.aarch64.AArch64ByteSwapOp;
52 import org.graalvm.compiler.lir.aarch64.AArch64Compare;
53 import org.graalvm.compiler.lir.aarch64.AArch64ControlFlow;
54 import org.graalvm.compiler.lir.aarch64.AArch64ControlFlow.BranchOp;
55 import org.graalvm.compiler.lir.aarch64.AArch64ControlFlow.CompareBranchZeroOp;
56 import org.graalvm.compiler.lir.aarch64.AArch64ControlFlow.CondMoveOp;
57 import org.graalvm.compiler.lir.aarch64.AArch64ControlFlow.CondSetOp;
58 import org.graalvm.compiler.lir.aarch64.AArch64ControlFlow.StrategySwitchOp;
59 import org.graalvm.compiler.lir.aarch64.AArch64ControlFlow.TableSwitchOp;
60 import org.graalvm.compiler.lir.aarch64.AArch64LIRFlagsVersioned;
61 import org.graalvm.compiler.lir.aarch64.AArch64Move;
62 import org.graalvm.compiler.lir.aarch64.AArch64AtomicMove.AtomicReadAndAddOp;
63 import org.graalvm.compiler.lir.aarch64.AArch64AtomicMove.AtomicReadAndAddLSEOp;
64 import org.graalvm.compiler.lir.aarch64.AArch64AtomicMove.CompareAndSwapOp;
65 import org.graalvm.compiler.lir.aarch64.AArch64AtomicMove.AtomicReadAndWriteOp;
66 import org.graalvm.compiler.lir.aarch64.AArch64Move.MembarOp;
67 import org.graalvm.compiler.lir.aarch64.AArch64PauseOp;
68 import org.graalvm.compiler.lir.aarch64.AArch64SpeculativeBarrier;
69 import org.graalvm.compiler.lir.aarch64.AArch64ZeroMemoryOp;
70 import org.graalvm.compiler.lir.gen.LIRGenerationResult;
71 import org.graalvm.compiler.lir.gen.LIRGenerator;
72 import org.graalvm.compiler.phases.util.Providers;
73
74 import jdk.vm.ci.aarch64.AArch64;
75 import jdk.vm.ci.aarch64.AArch64Kind;
76 import jdk.vm.ci.code.CallingConvention;
77 import jdk.vm.ci.code.RegisterValue;
78 import jdk.vm.ci.meta.AllocatableValue;
79 import jdk.vm.ci.meta.JavaConstant;
80 import jdk.vm.ci.meta.JavaKind;
81 import jdk.vm.ci.meta.PlatformKind;
82 import jdk.vm.ci.meta.PrimitiveConstant;
83 import jdk.vm.ci.meta.Value;
84 import jdk.vm.ci.meta.ValueKind;
85
86 public abstract class AArch64LIRGenerator extends LIRGenerator {
87
88 public AArch64LIRGenerator(LIRKindTool lirKindTool, AArch64ArithmeticLIRGenerator arithmeticLIRGen, MoveFactory moveFactory, Providers providers, LIRGenerationResult lirGenRes) {
89 super(lirKindTool, arithmeticLIRGen, moveFactory, providers, lirGenRes);
514 append(new AArch64ByteSwapOp(result, input));
515 return result;
516 }
517
518 @Override
519 public Variable emitArrayCompareTo(JavaKind kind1, JavaKind kind2, Value array1, Value array2, Value length1, Value length2) {
520 LIRKind resultKind = LIRKind.value(AArch64Kind.DWORD);
521 // DMS TODO: check calling conversion and registers used
522 RegisterValue res = AArch64.r0.asValue(resultKind);
523 RegisterValue cnt1 = AArch64.r1.asValue(length1.getValueKind());
524 RegisterValue cnt2 = AArch64.r2.asValue(length2.getValueKind());
525 emitMove(cnt1, length1);
526 emitMove(cnt2, length2);
527 append(new AArch64ArrayCompareToOp(this, kind1, kind2, res, array1, array2, cnt1, cnt2));
528 Variable result = newVariable(resultKind);
529 emitMove(result, res);
530 return result;
531 }
532
533 @Override
534 public Variable emitArrayEquals(JavaKind kind, Value array1, Value array2, Value length, boolean directPointers) {
535 Variable result = newVariable(LIRKind.value(AArch64Kind.DWORD));
536 append(new AArch64ArrayEqualsOp(this, kind, result, array1, array2, asAllocatable(length), directPointers));
537 return result;
538 }
539
540 @Override
541 protected JavaConstant zapValueForKind(PlatformKind kind) {
542 long dead = 0xDEADDEADDEADDEADL;
543 switch ((AArch64Kind) kind) {
544 case BYTE:
545 return JavaConstant.forByte((byte) dead);
546 case WORD:
547 return JavaConstant.forShort((short) dead);
548 case DWORD:
549 return JavaConstant.forInt((int) dead);
550 case QWORD:
551 return JavaConstant.forLong(dead);
552 case SINGLE:
553 return JavaConstant.forFloat(Float.intBitsToFloat((int) dead));
554 case DOUBLE:
566 * This avoids generating the following code: mov x0, x19 # x19 is fixed thread register ldr x0,
567 * [x0] instead of: ldr x0, [x19].
568 */
569 protected AllocatableValue loadReg(Value val) {
570 if (!(val instanceof Variable || val instanceof RegisterValue)) {
571 return emitMove(val);
572 }
573 return (AllocatableValue) val;
574 }
575
576 @Override
577 public void emitPause() {
578 append(new AArch64PauseOp());
579 }
580
581 public abstract void emitCCall(long address, CallingConvention nativeCallingConvention, Value[] args);
582
583 @Override
584 public void emitSpeculationFence() {
585 append(new AArch64SpeculativeBarrier());
586 }
587
588 @Override
589 public void emitZeroMemory(Value address, Value length) {
590 // Value address is 8-byte aligned; Value length is multiple of 8.
591 append(new AArch64ZeroMemoryOp(asAllocatable(address), asAllocatable(length), false, -1));
592 }
593 }
|