1 /*
   2  * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2019, Arm Limited. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 
  26 package org.graalvm.compiler.core.aarch64.test;
  27 
  28 import static org.junit.Assert.assertArrayEquals;
  29 import static org.junit.Assume.assumeTrue;
  30 
  31 import java.util.ArrayList;
  32 import java.util.List;
  33 
  34 import jdk.internal.vm.compiler.collections.Pair;
  35 import org.graalvm.compiler.asm.aarch64.AArch64Assembler.BarrierKind;
  36 import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler;
  37 import org.graalvm.compiler.code.CompilationResult;
  38 import org.graalvm.compiler.core.gen.LIRGenerationProvider;
  39 import org.graalvm.compiler.core.test.backend.BackendTest;
  40 import org.graalvm.compiler.lir.aarch64.AArch64Move.MembarOp;
  41 import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
  42 import org.graalvm.compiler.lir.asm.CompilationResultBuilderFactory;
  43 import org.graalvm.compiler.lir.gen.LIRGenerationResult;
  44 import org.graalvm.compiler.nodes.StructuredGraph;
  45 import org.junit.Before;
  46 import org.junit.Test;
  47 
  48 import jdk.vm.ci.aarch64.AArch64;
  49 import jdk.vm.ci.code.MemoryBarriers;
  50 import jdk.vm.ci.runtime.JVMCI;
  51 import jdk.vm.ci.runtime.JVMCIBackend;
  52 
  53 public class AArch64MembarOpTest extends BackendTest {
  54 
  55     private final JVMCIBackend providers;
  56     private final CompilationResultBuilder crb;
  57 
  58     public AArch64MembarOpTest() {
  59         this.providers = JVMCI.getRuntime().getHostJVMCIBackend();
  60 
  61         final StructuredGraph graph = parseEager("stub", StructuredGraph.AllowAssumptions.YES);
  62         LIRGenerationResult lirGenRes = getLIRGenerationResult(graph);
  63         CompilationResult compResult = new CompilationResult(graph.compilationId());
  64         this.crb = ((LIRGenerationProvider) getBackend()).newCompilationResultBuilder(lirGenRes, lirGenRes.getFrameMap(), compResult, CompilationResultBuilderFactory.Default);
  65     }
  66 
  67     public void stub() {
  68     }
  69 
  70     @Before
  71     public void checkAArch64() {
  72         assumeTrue("skipping AArch64 specific test", JVMCI.getRuntime().getHostJVMCIBackend().getTarget().arch instanceof AArch64);
  73     }
  74 
  75     @Test
  76     public void runNormalMembarTests() {
  77         List<Pair<Integer, BarrierKind>> cases = new ArrayList<>();
  78         cases.add(Pair.create(MemoryBarriers.LOAD_LOAD, BarrierKind.LOAD_LOAD));
  79         cases.add(Pair.create(MemoryBarriers.LOAD_STORE, BarrierKind.LOAD_LOAD));
  80         cases.add(Pair.create(MemoryBarriers.LOAD_LOAD | MemoryBarriers.LOAD_STORE, BarrierKind.LOAD_LOAD));
  81         cases.add(Pair.create(MemoryBarriers.STORE_LOAD, BarrierKind.ANY_ANY));
  82         cases.add(Pair.create(MemoryBarriers.STORE_LOAD | MemoryBarriers.LOAD_LOAD, BarrierKind.ANY_ANY));
  83         cases.add(Pair.create(MemoryBarriers.STORE_LOAD | MemoryBarriers.LOAD_STORE, BarrierKind.ANY_ANY));
  84         cases.add(Pair.create(MemoryBarriers.STORE_LOAD | MemoryBarriers.LOAD_LOAD | MemoryBarriers.LOAD_STORE, BarrierKind.ANY_ANY));
  85         cases.add(Pair.create(MemoryBarriers.STORE_STORE, BarrierKind.STORE_STORE));
  86         cases.add(Pair.create(MemoryBarriers.STORE_STORE | MemoryBarriers.LOAD_LOAD, BarrierKind.ANY_ANY));
  87         cases.add(Pair.create(MemoryBarriers.STORE_STORE | MemoryBarriers.LOAD_STORE, BarrierKind.ANY_ANY));
  88         cases.add(Pair.create(MemoryBarriers.STORE_STORE | MemoryBarriers.LOAD_LOAD | MemoryBarriers.LOAD_STORE, BarrierKind.ANY_ANY));
  89         cases.add(Pair.create(MemoryBarriers.STORE_STORE | MemoryBarriers.STORE_LOAD, BarrierKind.ANY_ANY));
  90         cases.add(Pair.create(MemoryBarriers.STORE_STORE | MemoryBarriers.STORE_LOAD | MemoryBarriers.LOAD_LOAD, BarrierKind.ANY_ANY));
  91         cases.add(Pair.create(MemoryBarriers.STORE_STORE | MemoryBarriers.STORE_LOAD | MemoryBarriers.LOAD_STORE, BarrierKind.ANY_ANY));
  92         cases.add(Pair.create(MemoryBarriers.STORE_STORE | MemoryBarriers.STORE_LOAD | MemoryBarriers.LOAD_STORE | MemoryBarriers.LOAD_LOAD, BarrierKind.ANY_ANY));
  93 
  94         for (Pair<Integer, BarrierKind> c : cases) {
  95             assertArrayEquals(new MembarOpActual(c.getLeft()).emit(new AArch64MacroAssembler(providers.getTarget())),
  96                             new MembarOpExpected(c.getRight()).emit(new AArch64MacroAssembler(providers.getTarget())));
  97         }
  98     }
  99 
 100     @Test(expected = AssertionError.class)
 101     public void runExceptionalTests() {
 102         new MembarOpActual(16).emit(new AArch64MacroAssembler(providers.getTarget()));
 103     }
 104 
 105     private class MembarOpActual {
 106         private MembarOp op;
 107 
 108         MembarOpActual(int barriers) {
 109             op = new MembarOp(barriers);
 110         }
 111 
 112         byte[] emit(AArch64MacroAssembler masm) {
 113             op.emitCode(crb, masm);
 114             return masm.close(false);
 115         }
 116     }
 117 
 118     private class MembarOpExpected {
 119         private BarrierKind barrierKind;
 120 
 121         MembarOpExpected(BarrierKind barrierKind) {
 122             this.barrierKind = barrierKind;
 123         }
 124 
 125         byte[] emit(AArch64MacroAssembler masm) {
 126             masm.dmb(barrierKind);
 127             return masm.close(false);
 128         }
 129     }
 130 }