/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, Arm Limited. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.asm.aarch64.test;
import static org.junit.Assume.assumeTrue;
import java.nio.ByteBuffer;
import org.graalvm.compiler.asm.aarch64.AArch64Assembler;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.test.GraalTest;
import org.junit.Before;
import org.junit.Test;
import jdk.vm.ci.aarch64.AArch64;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.TargetDescription;
import jdk.vm.ci.runtime.JVMCI;
public class AArch64InstructionEncodingTest extends GraalTest {
@Before
public void checkAArch64() {
assumeTrue("skipping non AArch64 specific test", JVMCI.getRuntime().getHostJVMCIBackend().getTarget().arch instanceof AArch64);
}
private abstract class AArch64InstructionEncodingTestCase {
private byte[] actual;
private byte[] expected;
TestProtectedAssembler assembler;
AArch64InstructionEncodingTestCase(int expected) {
this.expected = ByteBuffer.allocate(Integer.BYTES).putInt(expected).array();
TargetDescription target = JVMCI.getRuntime().getHostJVMCIBackend().getTarget();
assembler = new TestProtectedAssembler(target);
}
int getExpected() {
return ByteBuffer.wrap(expected).getInt();
}
int getActual() {
return ByteBuffer.wrap(actual).getInt();
}
void closeAssembler() {
this.actual = assembler.close(true);
}
}
private class CntEncodingTestCase extends AArch64InstructionEncodingTestCase {
CntEncodingTestCase(int expected, int size, Register dst, Register src) {
super(expected);
assembler.cnt(size, dst, src);
closeAssembler();
}
}
private class AddvEncodingTestCase extends AArch64InstructionEncodingTestCase {
AddvEncodingTestCase(int expected, int size, AArch64Assembler.SIMDElementSize laneWidth, Register dst, Register src) {
super(expected);
assembler.addv(size, laneWidth, dst, src);
closeAssembler();
}
}
private class UmovEncodingTestCase extends AArch64InstructionEncodingTestCase {
UmovEncodingTestCase(int expected, int size, Register dst, int srcIdx, Register src) {
super(expected);
assembler.umov(size, dst, srcIdx, src);
closeAssembler();
}
}
private static final int invalidInstructionCode = 0x00000000;
private void assertWrapper(AArch64InstructionEncodingTestCase testCase) {
assertDeepEquals(testCase.getActual(), testCase.getExpected());
}
@Test
public void testCnt() {
assertWrapper(new CntEncodingTestCase(0x0058200e, 64, AArch64.v0, AArch64.v0));
assertWrapper(new CntEncodingTestCase(0x3f58204e, 128, AArch64.v31, AArch64.v1));
}
@Test(expected = AssertionError.class)
@SuppressWarnings("unused")
public void testCntWithInvalidDataSize() {
new CntEncodingTestCase(invalidInstructionCode, 32, AArch64.v5, AArch64.v5);
}
@Test
public void testAddv() {
assertWrapper(new AddvEncodingTestCase(0x20b8310e, 64, AArch64Assembler.SIMDElementSize.Byte, AArch64.v0, AArch64.v1));
assertWrapper(new AddvEncodingTestCase(0x42b8314e, 128, AArch64Assembler.SIMDElementSize.Byte, AArch64.v2, AArch64.v2));
assertWrapper(new AddvEncodingTestCase(0xd2ba710e, 64, AArch64Assembler.SIMDElementSize.HalfWord, AArch64.v18, AArch64.v22));
assertWrapper(new AddvEncodingTestCase(0x77ba714e, 128, AArch64Assembler.SIMDElementSize.HalfWord, AArch64.v23, AArch64.v19));
assertWrapper(new AddvEncodingTestCase(0x18bbb14e, 128, AArch64Assembler.SIMDElementSize.Word, AArch64.v24, AArch64.v24));
}
@Test(expected = AssertionError.class)
@SuppressWarnings("unused")
public void testAddvWithInvalidSizeLaneCombo() {
new AddvEncodingTestCase(invalidInstructionCode, 64, AArch64Assembler.SIMDElementSize.Word, AArch64.v0, AArch64.v1);
}
@Test(expected = AssertionError.class)
@SuppressWarnings("unused")
public void testAddvWithInvalidDataSize() {
new AddvEncodingTestCase(invalidInstructionCode, 32, AArch64Assembler.SIMDElementSize.Word, AArch64.v0, AArch64.v1);
}
@Test(expected = AssertionError.class)
@SuppressWarnings("unused")
public void testAddvWithInvalidLane() {
new AddvEncodingTestCase(invalidInstructionCode, 128, AArch64Assembler.SIMDElementSize.DoubleWord, AArch64.v0, AArch64.v1);
}
@Test
public void testUmov() {
assertWrapper(new UmovEncodingTestCase(0x1f3c084e, 64, AArch64.r31, 0, AArch64.v0));
assertWrapper(new UmovEncodingTestCase(0xe13f184e, 64, AArch64.r1, 1, AArch64.v31));
assertWrapper(new UmovEncodingTestCase(0x5d3c040e, 32, AArch64.r29, 0, AArch64.v2));
assertWrapper(new UmovEncodingTestCase(0x833f1c0e, 32, AArch64.r3, 3, AArch64.v28));
assertWrapper(new UmovEncodingTestCase(0x4b3d020e, 16, AArch64.r11, 0, AArch64.v10));
/**代码未完, 请加载全部代码(NowJava.com).**/