blob: b59601720f521042d49f8795eb796fbc6e406098 [file] [log] [blame]
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#include "vm/globals.h"
#if defined(TARGET_ARCH_RISCV32) || defined(TARGET_ARCH_RISCV64)
#include "vm/compiler/assembler/assembler.h"
#include "vm/cpu.h"
#include "vm/os.h"
#include "vm/unit_test.h"
#include "vm/virtual_memory.h"
namespace dart {
namespace compiler {
#define __ assembler->
#if defined(PRODUCT)
#define EXPECT_DISASSEMBLY(expected)
#else
#define EXPECT_DISASSEMBLY(expected) \
EXPECT_STREQ(expected, test->RelativeDisassembly())
#endif
// Called from assembler_test.cc.
// RA: return address.
// A0: value.
// A1: growable array.
// A2: current thread.
ASSEMBLER_TEST_GENERATE(StoreIntoObject, assembler) {
__ PushRegister(RA);
__ PushNativeCalleeSavedRegisters();
__ mv(THR, A2);
__ lx(WRITE_BARRIER_MASK, Address(THR, Thread::write_barrier_mask_offset()));
__ StoreIntoObject(A1, FieldAddress(A1, GrowableObjectArray::data_offset()),
A0);
__ PopNativeCalleeSavedRegisters();
__ PopRegister(RA);
__ ret();
}
static intx_t Call(intx_t entry,
intx_t arg0 = 0,
intx_t arg1 = 0,
intx_t arg2 = 0,
intx_t arg3 = 0) {
#if defined(USING_SIMULATOR)
return Simulator::Current()->Call(entry, arg0, arg1, arg2, arg3);
#else
typedef intx_t (*F)(intx_t, intx_t, intx_t, intx_t);
return reinterpret_cast<F>(entry)(arg0, arg1, arg2, arg3);
#endif
}
static float CallF(intx_t entry, intx_t arg0) {
#if defined(USING_SIMULATOR)
return Simulator::Current()->CallF(entry, arg0);
#else
typedef float (*F)(intx_t);
return reinterpret_cast<F>(entry)(arg0);
#endif
}
static float CallF(intx_t entry, intx_t arg0, float arg1) {
#if defined(USING_SIMULATOR)
return Simulator::Current()->CallF(entry, arg0, arg1);
#else
typedef float (*F)(intx_t, float);
return reinterpret_cast<F>(entry)(arg0, arg1);
#endif
}
static float CallF(intx_t entry, double arg0) {
#if defined(USING_SIMULATOR)
return Simulator::Current()->CallF(entry, arg0);
#else
typedef float (*F)(double);
return reinterpret_cast<F>(entry)(arg0);
#endif
}
static float CallF(intx_t entry, float arg0) {
#if defined(USING_SIMULATOR)
return Simulator::Current()->CallF(entry, arg0);
#else
typedef float (*F)(float);
return reinterpret_cast<F>(entry)(arg0);
#endif
}
static float CallF(intx_t entry, float arg0, float arg1) {
#if defined(USING_SIMULATOR)
return Simulator::Current()->CallF(entry, arg0, arg1);
#else
typedef float (*F)(float, float);
return reinterpret_cast<F>(entry)(arg0, arg1);
#endif
}
static float CallF(intx_t entry, float arg0, float arg1, float arg2) {
#if defined(USING_SIMULATOR)
return Simulator::Current()->CallF(entry, arg0, arg1, arg2);
#else
typedef float (*F)(float, float, float);
return reinterpret_cast<F>(entry)(arg0, arg1, arg2);
#endif
}
static intx_t CallI(intx_t entry, float arg0) {
#if defined(USING_SIMULATOR)
return Simulator::Current()->CallI(entry, arg0);
#else
typedef intx_t (*F)(float);
return reinterpret_cast<F>(entry)(arg0);
#endif
}
static intx_t CallI(intx_t entry, float arg0, float arg1) {
#if defined(USING_SIMULATOR)
return Simulator::Current()->CallI(entry, arg0, arg1);
#else
typedef intx_t (*F)(float, float);
return reinterpret_cast<F>(entry)(arg0, arg1);
#endif
}
static double CallD(intx_t entry, intx_t arg0) {
#if defined(USING_SIMULATOR)
return Simulator::Current()->CallD(entry, arg0);
#else
typedef double (*F)(intx_t);
return reinterpret_cast<F>(entry)(arg0);
#endif
}
static double CallD(intx_t entry, intx_t arg0, double arg1) {
#if defined(USING_SIMULATOR)
return Simulator::Current()->CallD(entry, arg0, arg1);
#else
typedef double (*F)(intx_t, double);
return reinterpret_cast<F>(entry)(arg0, arg1);
#endif
}
static double CallD(intx_t entry, float arg0) {
#if defined(USING_SIMULATOR)
return Simulator::Current()->CallD(entry, arg0);
#else
typedef double (*F)(float);
return reinterpret_cast<F>(entry)(arg0);
#endif
}
static double CallD(intx_t entry, double arg0) {
#if defined(USING_SIMULATOR)
return Simulator::Current()->CallD(entry, arg0);
#else
typedef double (*F)(double);
return reinterpret_cast<F>(entry)(arg0);
#endif
}
static double CallD(intx_t entry, double arg0, double arg1) {
#if defined(USING_SIMULATOR)
return Simulator::Current()->CallD(entry, arg0, arg1);
#else
typedef double (*F)(double, double);
return reinterpret_cast<F>(entry)(arg0, arg1);
#endif
}
static double CallD(intx_t entry, double arg0, double arg1, double arg2) {
#if defined(USING_SIMULATOR)
return Simulator::Current()->CallD(entry, arg0, arg1, arg2);
#else
typedef double (*F)(double, double, double);
return reinterpret_cast<F>(entry)(arg0, arg1, arg2);
#endif
}
static intx_t CallI(intx_t entry, double arg0) {
#if defined(USING_SIMULATOR)
return Simulator::Current()->CallI(entry, arg0);
#else
typedef intx_t (*F)(double);
return reinterpret_cast<F>(entry)(arg0);
#endif
}
static intx_t CallI(intx_t entry, double arg0, double arg1) {
#if defined(USING_SIMULATOR)
return Simulator::Current()->CallI(entry, arg0, arg1);
#else
typedef intx_t (*F)(double, double);
return reinterpret_cast<F>(entry)(arg0, arg1);
#endif
}
ASSEMBLER_TEST_GENERATE(LoadUpperImmediate, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ lui(A0, 42 << 16);
__ ret();
}
ASSEMBLER_TEST_RUN(LoadUpperImmediate, test) {
EXPECT_DISASSEMBLY(
"002a0537 lui a0, 2752512\n"
"00008067 ret\n");
EXPECT_EQ(42 << 16, Call(test->entry()));
}
ASSEMBLER_TEST_GENERATE(AddUpperImmediatePC, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ auipc(A0, 0);
__ ret();
}
ASSEMBLER_TEST_RUN(AddUpperImmediatePC, test) {
EXPECT_DISASSEMBLY(
"00000517 auipc a0, 0\n"
"00008067 ret\n");
EXPECT_EQ(test->entry(), static_cast<uintx_t>(Call(test->entry())));
}
ASSEMBLER_TEST_GENERATE(JumpAndLink, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
Label label1, label2;
__ jal(T4, &label1); // Forward.
__ sub(A0, T0, T1);
__ ret();
__ trap();
__ Bind(&label2);
__ li(T1, 7);
__ jalr(ZR, T5);
__ trap();
__ Bind(&label1);
__ li(T0, 4);
__ jal(T5, &label2); // Backward.
__ jalr(ZR, T4);
__ trap();
}
ASSEMBLER_TEST_RUN(JumpAndLink, test) {
EXPECT_DISASSEMBLY(
"01c00eef jal t4, +28\n"
"40628533 sub a0, t0, t1\n"
"00008067 ret\n"
"00000000 trap\n"
"00700313 li t1, 7\n"
"000f0067 jr t5\n"
"00000000 trap\n"
"00400293 li t0, 4\n"
"ff1fff6f jal t5, -16\n"
"000e8067 jr t4\n"
"00000000 trap\n");
EXPECT_EQ(-3, Call(test->entry()));
}
ASSEMBLER_TEST_GENERATE(Jump, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
Label label1, label2;
__ j(&label1); // Forward.
__ trap();
__ Bind(&label2);
__ li(T1, 7);
__ sub(A0, T0, T1);
__ ret();
__ Bind(&label1);
__ li(T0, 4);
__ j(&label2); // Backward.
__ trap();
}
ASSEMBLER_TEST_RUN(Jump, test) {
EXPECT_DISASSEMBLY(
"0140006f j +20\n"
"00000000 trap\n"
"00700313 li t1, 7\n"
"40628533 sub a0, t0, t1\n"
"00008067 ret\n"
"00400293 li t0, 4\n"
"ff1ff06f j -16\n"
"00000000 trap\n");
EXPECT_EQ(-3, Call(test->entry()));
}
ASSEMBLER_TEST_GENERATE(JumpAndLinkRegister, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
/* 00 */ __ jalr(T4, A1, 28); // Forward.
/* 04 */ __ sub(A0, T0, T1);
/* 08 */ __ ret();
/* 12 */ __ trap();
/* 16 */ __ li(T1, 7);
/* 20 */ __ jalr(ZR, T5);
/* 24 */ __ trap();
/* 28 */ __ li(T0, 4);
/* 32 */ __ jalr(T5, A1, 16); // Backward.
/* 36 */ __ jalr(ZR, T4);
/* 40 */ __ trap();
}
ASSEMBLER_TEST_RUN(JumpAndLinkRegister, test) {
EXPECT_DISASSEMBLY(
"01c58ee7 jalr t4, 28(a1)\n"
"40628533 sub a0, t0, t1\n"
"00008067 ret\n"
"00000000 trap\n"
"00700313 li t1, 7\n"
"000f0067 jr t5\n"
"00000000 trap\n"
"00400293 li t0, 4\n"
"01058f67 jalr t5, 16(a1)\n"
"000e8067 jr t4\n"
"00000000 trap\n");
EXPECT_EQ(-3, Call(test->entry(), 0, test->entry()));
}
ASSEMBLER_TEST_GENERATE(JumpRegister, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
/* 00 */ __ jr(A1, 20); // Forward.
/* 04 */ __ trap();
/* 08 */ __ li(T1, 7);
/* 12 */ __ sub(A0, T0, T1);
/* 16 */ __ ret();
/* 20 */ __ li(T0, 4);
/* 24 */ __ jr(A1, 8); // Backward.
/* 28 */ __ trap();
}
ASSEMBLER_TEST_RUN(JumpRegister, test) {
EXPECT_DISASSEMBLY(
"01458067 jr 20(a1)\n"
"00000000 trap\n"
"00700313 li t1, 7\n"
"40628533 sub a0, t0, t1\n"
"00008067 ret\n"
"00400293 li t0, 4\n"
"00858067 jr 8(a1)\n"
"00000000 trap\n");
EXPECT_EQ(-3, Call(test->entry(), 0, test->entry()));
}
ASSEMBLER_TEST_GENERATE(BranchEqualForward, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
Label label;
__ beq(A0, A1, &label);
__ li(A0, 3);
__ ret();
__ Bind(&label);
__ li(A0, 4);
__ ret();
}
ASSEMBLER_TEST_RUN(BranchEqualForward, test) {
EXPECT_DISASSEMBLY(
"00b50663 beq a0, a1, +12\n"
"00300513 li a0, 3\n"
"00008067 ret\n"
"00400513 li a0, 4\n"
"00008067 ret\n");
EXPECT_EQ(4, Call(test->entry(), 1, 1));
EXPECT_EQ(3, Call(test->entry(), 1, 0));
EXPECT_EQ(3, Call(test->entry(), 1, -1));
EXPECT_EQ(3, Call(test->entry(), 0, 1));
EXPECT_EQ(4, Call(test->entry(), 0, 0));
EXPECT_EQ(3, Call(test->entry(), 0, -1));
EXPECT_EQ(3, Call(test->entry(), -1, 1));
EXPECT_EQ(3, Call(test->entry(), -1, 0));
EXPECT_EQ(4, Call(test->entry(), -1, -1));
}
ASSEMBLER_TEST_GENERATE(BranchEqualForwardFar, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
Label label;
__ beq(A0, A1, &label);
__ li(A0, 3);
__ ret();
for (intptr_t i = 0; i < (1 << 13); i++) {
__ ebreak();
}
__ Bind(&label);
__ li(A0, 4);
__ ret();
}
ASSEMBLER_TEST_RUN(BranchEqualForwardFar, test) {
// EXPECT_DISASSEMBLY(constant too big);
EXPECT_EQ(4, Call(test->entry(), 1, 1));
EXPECT_EQ(3, Call(test->entry(), 1, 0));
EXPECT_EQ(3, Call(test->entry(), 1, -1));
EXPECT_EQ(3, Call(test->entry(), 0, 1));
EXPECT_EQ(4, Call(test->entry(), 0, 0));
EXPECT_EQ(3, Call(test->entry(), 0, -1));
EXPECT_EQ(3, Call(test->entry(), -1, 1));
EXPECT_EQ(3, Call(test->entry(), -1, 0));
EXPECT_EQ(4, Call(test->entry(), -1, -1));
}
ASSEMBLER_TEST_GENERATE(BranchNotEqualForward, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
Label label;
__ bne(A0, A1, &label);
__ li(A0, 3);
__ ret();
__ Bind(&label);
__ li(A0, 4);
__ ret();
}
ASSEMBLER_TEST_RUN(BranchNotEqualForward, test) {
EXPECT_DISASSEMBLY(
"00b51663 bne a0, a1, +12\n"
"00300513 li a0, 3\n"
"00008067 ret\n"
"00400513 li a0, 4\n"
"00008067 ret\n");
EXPECT_EQ(3, Call(test->entry(), 1, 1));
EXPECT_EQ(4, Call(test->entry(), 1, 0));
EXPECT_EQ(4, Call(test->entry(), 1, -1));
EXPECT_EQ(4, Call(test->entry(), 0, 1));
EXPECT_EQ(3, Call(test->entry(), 0, 0));
EXPECT_EQ(4, Call(test->entry(), 0, -1));
EXPECT_EQ(4, Call(test->entry(), -1, 1));
EXPECT_EQ(4, Call(test->entry(), -1, 0));
EXPECT_EQ(3, Call(test->entry(), -1, -1));
}
ASSEMBLER_TEST_GENERATE(BranchNotEqualForwardFar, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
Label label;
__ bne(A0, A1, &label);
__ li(A0, 3);
__ ret();
for (intptr_t i = 0; i < (1 << 13); i++) {
__ ebreak();
}
__ Bind(&label);
__ li(A0, 4);
__ ret();
}
ASSEMBLER_TEST_RUN(BranchNotEqualForwardFar, test) {
// EXPECT_DISASSEMBLY(constant too big);
EXPECT_EQ(3, Call(test->entry(), 1, 1));
EXPECT_EQ(4, Call(test->entry(), 1, 0));
EXPECT_EQ(4, Call(test->entry(), 1, -1));
EXPECT_EQ(4, Call(test->entry(), 0, 1));
EXPECT_EQ(3, Call(test->entry(), 0, 0));
EXPECT_EQ(4, Call(test->entry(), 0, -1));
EXPECT_EQ(4, Call(test->entry(), -1, 1));
EXPECT_EQ(4, Call(test->entry(), -1, 0));
EXPECT_EQ(3, Call(test->entry(), -1, -1));
}
ASSEMBLER_TEST_GENERATE(BranchLessThanForward, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
Label label;
__ blt(A0, A1, &label);
__ li(A0, 3);
__ ret();
__ Bind(&label);
__ li(A0, 4);
__ ret();
}
ASSEMBLER_TEST_RUN(BranchLessThanForward, test) {
EXPECT_DISASSEMBLY(
"00b54663 blt a0, a1, +12\n"
"00300513 li a0, 3\n"
"00008067 ret\n"
"00400513 li a0, 4\n"
"00008067 ret\n");
EXPECT_EQ(3, Call(test->entry(), 1, 1));
EXPECT_EQ(3, Call(test->entry(), 1, 0));
EXPECT_EQ(3, Call(test->entry(), 1, -1));
EXPECT_EQ(4, Call(test->entry(), 0, 1));
EXPECT_EQ(3, Call(test->entry(), 0, 0));
EXPECT_EQ(3, Call(test->entry(), 0, -1));
EXPECT_EQ(4, Call(test->entry(), -1, 1));
EXPECT_EQ(4, Call(test->entry(), -1, 0));
EXPECT_EQ(3, Call(test->entry(), -1, -1));
}
ASSEMBLER_TEST_GENERATE(BranchLessThanForwardFar, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
Label label;
__ blt(A0, A1, &label);
__ li(A0, 3);
__ ret();
for (intptr_t i = 0; i < (1 << 13); i++) {
__ ebreak();
}
__ Bind(&label);
__ li(A0, 4);
__ ret();
}
ASSEMBLER_TEST_RUN(BranchLessThanForwardFar, test) {
// EXPECT_DISASSEMBLY(constant too big);
EXPECT_EQ(3, Call(test->entry(), 1, 1));
EXPECT_EQ(3, Call(test->entry(), 1, 0));
EXPECT_EQ(3, Call(test->entry(), 1, -1));
EXPECT_EQ(4, Call(test->entry(), 0, 1));
EXPECT_EQ(3, Call(test->entry(), 0, 0));
EXPECT_EQ(3, Call(test->entry(), 0, -1));
EXPECT_EQ(4, Call(test->entry(), -1, 1));
EXPECT_EQ(4, Call(test->entry(), -1, 0));
EXPECT_EQ(3, Call(test->entry(), -1, -1));
}
ASSEMBLER_TEST_GENERATE(BranchLessOrEqualForward, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
Label label;
__ ble(A0, A1, &label);
__ li(A0, 3);
__ ret();
__ Bind(&label);
__ li(A0, 4);
__ ret();
}
ASSEMBLER_TEST_RUN(BranchLessOrEqualForward, test) {
EXPECT_DISASSEMBLY(
"00a5d663 ble a0, a1, +12\n"
"00300513 li a0, 3\n"
"00008067 ret\n"
"00400513 li a0, 4\n"
"00008067 ret\n");
EXPECT_EQ(4, Call(test->entry(), 1, 1));
EXPECT_EQ(3, Call(test->entry(), 1, 0));
EXPECT_EQ(3, Call(test->entry(), 1, -1));
EXPECT_EQ(4, Call(test->entry(), 0, 1));
EXPECT_EQ(4, Call(test->entry(), 0, 0));
EXPECT_EQ(3, Call(test->entry(), 0, -1));
EXPECT_EQ(4, Call(test->entry(), -1, 1));
EXPECT_EQ(4, Call(test->entry(), -1, 0));
EXPECT_EQ(4, Call(test->entry(), -1, -1));
}
ASSEMBLER_TEST_GENERATE(BranchLessOrEqualForwardFar, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
Label label;
__ ble(A0, A1, &label);
__ li(A0, 3);
__ ret();
for (intptr_t i = 0; i < (1 << 13); i++) {
__ ebreak();
}
__ Bind(&label);
__ li(A0, 4);
__ ret();
}
ASSEMBLER_TEST_RUN(BranchLessOrEqualForwardFar, test) {
// EXPECT_DISASSEMBLY(constant too big);
EXPECT_EQ(4, Call(test->entry(), 1, 1));
EXPECT_EQ(3, Call(test->entry(), 1, 0));
EXPECT_EQ(3, Call(test->entry(), 1, -1));
EXPECT_EQ(4, Call(test->entry(), 0, 1));
EXPECT_EQ(4, Call(test->entry(), 0, 0));
EXPECT_EQ(3, Call(test->entry(), 0, -1));
EXPECT_EQ(4, Call(test->entry(), -1, 1));
EXPECT_EQ(4, Call(test->entry(), -1, 0));
EXPECT_EQ(4, Call(test->entry(), -1, -1));
}
ASSEMBLER_TEST_GENERATE(BranchGreaterThanForward, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
Label label;
__ bgt(A0, A1, &label);
__ li(A0, 3);
__ ret();
__ Bind(&label);
__ li(A0, 4);
__ ret();
}
ASSEMBLER_TEST_RUN(BranchGreaterThanForward, test) {
EXPECT_DISASSEMBLY(
"00a5c663 blt a1, a0, +12\n"
"00300513 li a0, 3\n"
"00008067 ret\n"
"00400513 li a0, 4\n"
"00008067 ret\n");
EXPECT_EQ(3, Call(test->entry(), 1, 1));
EXPECT_EQ(4, Call(test->entry(), 1, 0));
EXPECT_EQ(4, Call(test->entry(), 1, -1));
EXPECT_EQ(3, Call(test->entry(), 0, 1));
EXPECT_EQ(3, Call(test->entry(), 0, 0));
EXPECT_EQ(4, Call(test->entry(), 0, -1));
EXPECT_EQ(3, Call(test->entry(), -1, 1));
EXPECT_EQ(3, Call(test->entry(), -1, 0));
EXPECT_EQ(3, Call(test->entry(), -1, -1));
}
ASSEMBLER_TEST_GENERATE(BranchGreaterOrEqualForward, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
Label label;
__ bge(A0, A1, &label);
__ li(A0, 3);
__ ret();
__ Bind(&label);
__ li(A0, 4);
__ ret();
}
ASSEMBLER_TEST_RUN(BranchGreaterOrEqualForward, test) {
EXPECT_DISASSEMBLY(
"00b55663 ble a1, a0, +12\n"
"00300513 li a0, 3\n"
"00008067 ret\n"
"00400513 li a0, 4\n"
"00008067 ret\n");
EXPECT_EQ(4, Call(test->entry(), 1, 1));
EXPECT_EQ(4, Call(test->entry(), 1, 0));
EXPECT_EQ(4, Call(test->entry(), 1, -1));
EXPECT_EQ(3, Call(test->entry(), 0, 1));
EXPECT_EQ(4, Call(test->entry(), 0, 0));
EXPECT_EQ(4, Call(test->entry(), 0, -1));
EXPECT_EQ(3, Call(test->entry(), -1, 1));
EXPECT_EQ(3, Call(test->entry(), -1, 0));
EXPECT_EQ(4, Call(test->entry(), -1, -1));
}
ASSEMBLER_TEST_GENERATE(BranchLessThanUnsignedForward, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
Label label;
__ bltu(A0, A1, &label);
__ li(A0, 3);
__ ret();
__ Bind(&label);
__ li(A0, 4);
__ ret();
}
ASSEMBLER_TEST_RUN(BranchLessThanUnsignedForward, test) {
EXPECT_DISASSEMBLY(
"00b56663 bltu a0, a1, +12\n"
"00300513 li a0, 3\n"
"00008067 ret\n"
"00400513 li a0, 4\n"
"00008067 ret\n");
EXPECT_EQ(3, Call(test->entry(), 1, 1));
EXPECT_EQ(3, Call(test->entry(), 1, 0));
EXPECT_EQ(4, Call(test->entry(), 1, -1));
EXPECT_EQ(4, Call(test->entry(), 0, 1));
EXPECT_EQ(3, Call(test->entry(), 0, 0));
EXPECT_EQ(4, Call(test->entry(), 0, -1));
EXPECT_EQ(3, Call(test->entry(), -1, 1));
EXPECT_EQ(3, Call(test->entry(), -1, 0));
EXPECT_EQ(3, Call(test->entry(), -1, -1));
}
ASSEMBLER_TEST_GENERATE(BranchLessOrEqualUnsignedForward, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
Label label;
__ bleu(A0, A1, &label);
__ li(A0, 3);
__ ret();
__ Bind(&label);
__ li(A0, 4);
__ ret();
}
ASSEMBLER_TEST_RUN(BranchLessOrEqualUnsignedForward, test) {
EXPECT_DISASSEMBLY(
"00a5f663 bleu a0, a1, +12\n"
"00300513 li a0, 3\n"
"00008067 ret\n"
"00400513 li a0, 4\n"
"00008067 ret\n");
EXPECT_EQ(4, Call(test->entry(), 1, 1));
EXPECT_EQ(3, Call(test->entry(), 1, 0));
EXPECT_EQ(4, Call(test->entry(), 1, -1));
EXPECT_EQ(4, Call(test->entry(), 0, 1));
EXPECT_EQ(4, Call(test->entry(), 0, 0));
EXPECT_EQ(4, Call(test->entry(), 0, -1));
EXPECT_EQ(3, Call(test->entry(), -1, 1));
EXPECT_EQ(3, Call(test->entry(), -1, 0));
EXPECT_EQ(4, Call(test->entry(), -1, -1));
}
ASSEMBLER_TEST_GENERATE(BranchGreaterThanUnsignedForward, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
Label label;
__ bgtu(A0, A1, &label);
__ li(A0, 3);
__ ret();
__ Bind(&label);
__ li(A0, 4);
__ ret();
}
ASSEMBLER_TEST_RUN(BranchGreaterThanUnsignedForward, test) {
EXPECT_DISASSEMBLY(
"00a5e663 bltu a1, a0, +12\n"
"00300513 li a0, 3\n"
"00008067 ret\n"
"00400513 li a0, 4\n"
"00008067 ret\n");
EXPECT_EQ(3, Call(test->entry(), 1, 1));
EXPECT_EQ(4, Call(test->entry(), 1, 0));
EXPECT_EQ(3, Call(test->entry(), 1, -1));
EXPECT_EQ(3, Call(test->entry(), 0, 1));
EXPECT_EQ(3, Call(test->entry(), 0, 0));
EXPECT_EQ(3, Call(test->entry(), 0, -1));
EXPECT_EQ(4, Call(test->entry(), -1, 1));
EXPECT_EQ(4, Call(test->entry(), -1, 0));
EXPECT_EQ(3, Call(test->entry(), -1, -1));
}
ASSEMBLER_TEST_GENERATE(BranchGreaterOrEqualUnsignedForward, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
Label label;
__ bgeu(A0, A1, &label);
__ li(A0, 3);
__ ret();
__ Bind(&label);
__ li(A0, 4);
__ ret();
}
ASSEMBLER_TEST_RUN(BranchGreaterOrEqualUnsignedForward, test) {
EXPECT_DISASSEMBLY(
"00b57663 bleu a1, a0, +12\n"
"00300513 li a0, 3\n"
"00008067 ret\n"
"00400513 li a0, 4\n"
"00008067 ret\n");
EXPECT_EQ(4, Call(test->entry(), 1, 1));
EXPECT_EQ(4, Call(test->entry(), 1, 0));
EXPECT_EQ(3, Call(test->entry(), 1, -1));
EXPECT_EQ(3, Call(test->entry(), 0, 1));
EXPECT_EQ(4, Call(test->entry(), 0, 0));
EXPECT_EQ(3, Call(test->entry(), 0, -1));
EXPECT_EQ(4, Call(test->entry(), -1, 1));
EXPECT_EQ(4, Call(test->entry(), -1, 0));
EXPECT_EQ(4, Call(test->entry(), -1, -1));
}
ASSEMBLER_TEST_GENERATE(LoadByte_0, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ lb(A0, Address(A0, 0));
__ ret();
}
ASSEMBLER_TEST_RUN(LoadByte_0, test) {
EXPECT_DISASSEMBLY(
"00050503 lb a0, 0(a0)\n"
"00008067 ret\n");
uint8_t* values = reinterpret_cast<uint8_t*>(malloc(3 * sizeof(uint8_t)));
values[0] = 0xAB;
values[1] = 0xCD;
values[2] = 0xEF;
EXPECT_EQ(-51, Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
free(values);
}
ASSEMBLER_TEST_GENERATE(LoadByte_Pos, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ lb(A0, Address(A0, 1));
__ ret();
}
ASSEMBLER_TEST_RUN(LoadByte_Pos, test) {
EXPECT_DISASSEMBLY(
"00150503 lb a0, 1(a0)\n"
"00008067 ret\n");
uint8_t* values = reinterpret_cast<uint8_t*>(malloc(3 * sizeof(uint8_t)));
values[0] = 0xAB;
values[1] = 0xCD;
values[2] = 0xEF;
EXPECT_EQ(-17, Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
free(values);
}
ASSEMBLER_TEST_GENERATE(LoadByte_Neg, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ lb(A0, Address(A0, -1));
__ ret();
}
ASSEMBLER_TEST_RUN(LoadByte_Neg, test) {
EXPECT_DISASSEMBLY(
"fff50503 lb a0, -1(a0)\n"
"00008067 ret\n");
uint8_t* values = reinterpret_cast<uint8_t*>(malloc(3 * sizeof(uint8_t)));
values[0] = 0xAB;
values[1] = 0xCD;
values[2] = 0xEF;
EXPECT_EQ(-85, Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
free(values);
}
ASSEMBLER_TEST_GENERATE(LoadByteUnsigned_0, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ lbu(A0, Address(A0, 0));
__ ret();
}
ASSEMBLER_TEST_RUN(LoadByteUnsigned_0, test) {
EXPECT_DISASSEMBLY(
"00054503 lbu a0, 0(a0)\n"
"00008067 ret\n");
uint8_t* values = reinterpret_cast<uint8_t*>(malloc(3 * sizeof(uint8_t)));
values[0] = 0xAB;
values[1] = 0xCD;
values[2] = 0xEF;
EXPECT_EQ(0xCD, Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
free(values);
}
ASSEMBLER_TEST_GENERATE(LoadByteUnsigned_Pos, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ lbu(A0, Address(A0, 1));
__ ret();
}
ASSEMBLER_TEST_RUN(LoadByteUnsigned_Pos, test) {
EXPECT_DISASSEMBLY(
"00154503 lbu a0, 1(a0)\n"
"00008067 ret\n");
uint8_t* values = reinterpret_cast<uint8_t*>(malloc(3 * sizeof(uint8_t)));
values[0] = 0xAB;
values[1] = 0xCD;
values[2] = 0xEF;
EXPECT_EQ(0xEF, Call(test->entry(), reinterpret_cast<intx_t>((&values[1]))));
free(values);
}
ASSEMBLER_TEST_GENERATE(LoadByteUnsigned_Neg, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ lbu(A0, Address(A0, -1));
__ ret();
}
ASSEMBLER_TEST_RUN(LoadByteUnsigned_Neg, test) {
EXPECT_DISASSEMBLY(
"fff54503 lbu a0, -1(a0)\n"
"00008067 ret\n");
uint8_t* values = reinterpret_cast<uint8_t*>(malloc(3 * sizeof(uint8_t)));
values[0] = 0xAB;
values[1] = 0xCD;
values[2] = 0xEF;
EXPECT_EQ(0xAB, Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
}
ASSEMBLER_TEST_GENERATE(LoadHalfword_0, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ lh(A0, Address(A0, 0));
__ ret();
}
ASSEMBLER_TEST_RUN(LoadHalfword_0, test) {
EXPECT_DISASSEMBLY(
"00051503 lh a0, 0(a0)\n"
"00008067 ret\n");
uint16_t* values = reinterpret_cast<uint16_t*>(malloc(3 * sizeof(uint16_t)));
values[0] = 0xAB01;
values[1] = 0xCD02;
values[2] = 0xEF03;
EXPECT_EQ(-13054, Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
}
ASSEMBLER_TEST_GENERATE(LoadHalfword_Pos, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ lh(A0, Address(A0, 2));
__ ret();
}
ASSEMBLER_TEST_RUN(LoadHalfword_Pos, test) {
EXPECT_DISASSEMBLY(
"00251503 lh a0, 2(a0)\n"
"00008067 ret\n");
uint16_t* values = reinterpret_cast<uint16_t*>(malloc(3 * sizeof(uint16_t)));
values[0] = 0xAB01;
values[1] = 0xCD02;
values[2] = 0xEF03;
EXPECT_EQ(-4349, Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
}
ASSEMBLER_TEST_GENERATE(LoadHalfword_Neg, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ lh(A0, Address(A0, -2));
__ ret();
}
ASSEMBLER_TEST_RUN(LoadHalfword_Neg, test) {
EXPECT_DISASSEMBLY(
"ffe51503 lh a0, -2(a0)\n"
"00008067 ret\n");
uint16_t* values = reinterpret_cast<uint16_t*>(malloc(3 * sizeof(uint16_t)));
values[0] = 0xAB01;
values[1] = 0xCD02;
values[2] = 0xEF03;
EXPECT_EQ(-21759, Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
}
ASSEMBLER_TEST_GENERATE(LoadHalfwordUnsigned_0, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ lhu(A0, Address(A0, 0));
__ ret();
}
ASSEMBLER_TEST_RUN(LoadHalfwordUnsigned_0, test) {
EXPECT_DISASSEMBLY(
"00055503 lhu a0, 0(a0)\n"
"00008067 ret\n");
uint16_t* values = reinterpret_cast<uint16_t*>(malloc(3 * sizeof(uint16_t)));
values[0] = 0xAB01;
values[1] = 0xCD02;
values[2] = 0xEF03;
EXPECT_EQ(0xCD02, Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
}
ASSEMBLER_TEST_GENERATE(LoadHalfwordUnsigned_Pos, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ lhu(A0, Address(A0, 2));
__ ret();
}
ASSEMBLER_TEST_RUN(LoadHalfwordUnsigned_Pos, test) {
EXPECT_DISASSEMBLY(
"00255503 lhu a0, 2(a0)\n"
"00008067 ret\n");
uint16_t* values = reinterpret_cast<uint16_t*>(malloc(3 * sizeof(uint16_t)));
values[0] = 0xAB01;
values[1] = 0xCD02;
values[2] = 0xEF03;
EXPECT_EQ(0xEF03, Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
}
ASSEMBLER_TEST_GENERATE(LoadHalfwordUnsigned_Neg, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ lhu(A0, Address(A0, -2));
__ ret();
}
ASSEMBLER_TEST_RUN(LoadHalfwordUnsigned_Neg, test) {
EXPECT_DISASSEMBLY(
"ffe55503 lhu a0, -2(a0)\n"
"00008067 ret\n");
uint16_t* values = reinterpret_cast<uint16_t*>(malloc(3 * sizeof(uint16_t)));
values[0] = 0xAB01;
values[1] = 0xCD02;
values[2] = 0xEF03;
EXPECT_EQ(0xAB01, Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
}
ASSEMBLER_TEST_GENERATE(LoadWord_0, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ lw(A0, Address(A0, 0));
__ ret();
}
ASSEMBLER_TEST_RUN(LoadWord_0, test) {
EXPECT_DISASSEMBLY(
"00052503 lw a0, 0(a0)\n"
"00008067 ret\n");
uint32_t* values = reinterpret_cast<uint32_t*>(malloc(3 * sizeof(uint32_t)));
values[0] = 0xAB010203;
values[1] = 0xCD020405;
values[2] = 0xEF030607;
EXPECT_EQ(-855505915,
Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
}
ASSEMBLER_TEST_GENERATE(LoadWord_Pos, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ lw(A0, Address(A0, 4));
__ ret();
}
ASSEMBLER_TEST_RUN(LoadWord_Pos, test) {
EXPECT_DISASSEMBLY(
"00452503 lw a0, 4(a0)\n"
"00008067 ret\n");
uint32_t* values = reinterpret_cast<uint32_t*>(malloc(3 * sizeof(uint32_t)));
values[0] = 0xAB010203;
values[1] = 0xCD020405;
values[2] = 0xEF030607;
EXPECT_EQ(-285014521,
Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
}
ASSEMBLER_TEST_GENERATE(LoadWord_Neg, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ lw(A0, Address(A0, -4));
__ ret();
}
ASSEMBLER_TEST_RUN(LoadWord_Neg, test) {
EXPECT_DISASSEMBLY(
"ffc52503 lw a0, -4(a0)\n"
"00008067 ret\n");
uint32_t* values = reinterpret_cast<uint32_t*>(malloc(3 * sizeof(uint32_t)));
values[0] = 0xAB010203;
values[1] = 0xCD020405;
values[2] = 0xEF030607;
EXPECT_EQ(-1425997309,
Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
}
ASSEMBLER_TEST_GENERATE(StoreWord_0, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ sw(A1, Address(A0, 0));
__ ret();
}
ASSEMBLER_TEST_RUN(StoreWord_0, test) {
EXPECT_DISASSEMBLY(
"00b52023 sw a1, 0(a0)\n"
"00008067 ret\n");
uint32_t* values = reinterpret_cast<uint32_t*>(malloc(3 * sizeof(uint32_t)));
values[0] = 0;
values[1] = 0;
values[2] = 0;
Call(test->entry(), reinterpret_cast<intx_t>(&values[1]), 0xCD020405);
EXPECT_EQ(0u, values[0]);
EXPECT_EQ(0xCD020405, values[1]);
EXPECT_EQ(0u, values[2]);
}
ASSEMBLER_TEST_GENERATE(StoreWord_Pos, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ sw(A1, Address(A0, 4));
__ ret();
}
ASSEMBLER_TEST_RUN(StoreWord_Pos, test) {
EXPECT_DISASSEMBLY(
"00b52223 sw a1, 4(a0)\n"
"00008067 ret\n");
uint32_t* values = reinterpret_cast<uint32_t*>(malloc(3 * sizeof(uint32_t)));
values[0] = 0;
values[1] = 0;
values[2] = 0;
Call(test->entry(), reinterpret_cast<intx_t>(&values[1]), 0xEF030607);
EXPECT_EQ(0u, values[0]);
EXPECT_EQ(0u, values[1]);
EXPECT_EQ(0xEF030607, values[2]);
}
ASSEMBLER_TEST_GENERATE(StoreWord_Neg, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ sw(A1, Address(A0, -4));
__ ret();
}
ASSEMBLER_TEST_RUN(StoreWord_Neg, test) {
EXPECT_DISASSEMBLY(
"feb52e23 sw a1, -4(a0)\n"
"00008067 ret\n");
uint32_t* values = reinterpret_cast<uint32_t*>(malloc(3 * sizeof(uint32_t)));
values[0] = 0;
values[1] = 0;
values[2] = 0;
Call(test->entry(), reinterpret_cast<intx_t>(&values[1]), 0xAB010203);
EXPECT_EQ(0xAB010203, values[0]);
EXPECT_EQ(0u, values[1]);
EXPECT_EQ(0u, values[2]);
}
#if XLEN >= 64
ASSEMBLER_TEST_GENERATE(LoadWordUnsigned_0, assembler) {
__ lwu(A0, Address(A0, 0));
__ ret();
}
ASSEMBLER_TEST_RUN(LoadWordUnsigned_0, test) {
EXPECT_DISASSEMBLY(
"00056503 lwu a0, 0(a0)\n"
"00008067 ret\n");
uint32_t* values = reinterpret_cast<uint32_t*>(malloc(3 * sizeof(uint32_t)));
values[0] = 0xAB010203;
values[1] = 0xCD020405;
values[2] = 0xEF030607;
EXPECT_EQ(0xCD020405,
Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
}
ASSEMBLER_TEST_GENERATE(LoadWordUnsigned_Pos, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ lwu(A0, Address(A0, 4));
__ ret();
}
ASSEMBLER_TEST_RUN(LoadWordUnsigned_Pos, test) {
EXPECT_DISASSEMBLY(
"00456503 lwu a0, 4(a0)\n"
"00008067 ret\n");
uint32_t* values = reinterpret_cast<uint32_t*>(malloc(3 * sizeof(uint32_t)));
values[0] = 0xAB010203;
values[1] = 0xCD020405;
values[2] = 0xEF030607;
EXPECT_EQ(0xEF030607,
Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
}
ASSEMBLER_TEST_GENERATE(LoadWordUnsigned_Neg, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ lwu(A0, Address(A0, -4));
__ ret();
}
ASSEMBLER_TEST_RUN(LoadWordUnsigned_Neg, test) {
EXPECT_DISASSEMBLY(
"ffc56503 lwu a0, -4(a0)\n"
"00008067 ret\n");
uint32_t* values = reinterpret_cast<uint32_t*>(malloc(3 * sizeof(uint32_t)));
values[0] = 0xAB010203;
values[1] = 0xCD020405;
values[2] = 0xEF030607;
EXPECT_EQ(0xAB010203,
Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
}
ASSEMBLER_TEST_GENERATE(LoadDoubleWord_0, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ ld(A0, Address(A0, 0));
__ ret();
}
ASSEMBLER_TEST_RUN(LoadDoubleWord_0, test) {
EXPECT_DISASSEMBLY(
"00053503 ld a0, 0(a0)\n"
"00008067 ret\n");
uint64_t* values = reinterpret_cast<uint64_t*>(malloc(3 * sizeof(uint64_t)));
values[0] = 0xAB01020304050607;
values[1] = 0xCD02040505060708;
values[2] = 0xEF03060708090A0B;
EXPECT_EQ(-3674369926375274744,
Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
}
ASSEMBLER_TEST_GENERATE(LoadDoubleWord_Pos, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ ld(A0, Address(A0, 8));
__ ret();
}
ASSEMBLER_TEST_RUN(LoadDoubleWord_Pos, test) {
EXPECT_DISASSEMBLY(
"00853503 ld a0, 8(a0)\n"
"00008067 ret\n");
uint64_t* values = reinterpret_cast<uint64_t*>(malloc(3 * sizeof(uint64_t)));
values[0] = 0xAB01020304050607;
values[1] = 0xCD02040505060708;
values[2] = 0xEF03060708090A0B;
EXPECT_EQ(-1224128046445295093,
Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
}
ASSEMBLER_TEST_GENERATE(LoadDoubleWord_Neg, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ ld(A0, Address(A0, -8));
__ ret();
}
ASSEMBLER_TEST_RUN(LoadDoubleWord_Neg, test) {
EXPECT_DISASSEMBLY(
"ff853503 ld a0, -8(a0)\n"
"00008067 ret\n");
uint64_t* values = reinterpret_cast<uint64_t*>(malloc(3 * sizeof(uint64_t)));
values[0] = 0xAB01020304050607;
values[1] = 0xCD02040505060708;
values[2] = 0xEF03060708090A0B;
EXPECT_EQ(-6124611806271568377,
Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
}
ASSEMBLER_TEST_GENERATE(StoreDoubleWord_0, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ sd(A1, Address(A0, 0));
__ ret();
}
ASSEMBLER_TEST_RUN(StoreDoubleWord_0, test) {
EXPECT_DISASSEMBLY(
"00b53023 sd a1, 0(a0)\n"
"00008067 ret\n");
uint64_t* values = reinterpret_cast<uint64_t*>(malloc(3 * sizeof(uint64_t)));
values[0] = 0;
values[1] = 0;
values[2] = 0;
Call(test->entry(), reinterpret_cast<intx_t>(&values[1]), 0xCD02040505060708);
EXPECT_EQ(0u, values[0]);
EXPECT_EQ(0xCD02040505060708, values[1]);
EXPECT_EQ(0u, values[2]);
}
ASSEMBLER_TEST_GENERATE(StoreDoubleWord_Pos, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ sd(A1, Address(A0, 8));
__ ret();
}
ASSEMBLER_TEST_RUN(StoreDoubleWord_Pos, test) {
EXPECT_DISASSEMBLY(
"00b53423 sd a1, 8(a0)\n"
"00008067 ret\n");
uint64_t* values = reinterpret_cast<uint64_t*>(malloc(3 * sizeof(uint64_t)));
values[0] = 0;
values[1] = 0;
values[2] = 0;
Call(test->entry(), reinterpret_cast<intx_t>(&values[1]), 0xEF03060708090A0B);
EXPECT_EQ(0u, values[0]);
EXPECT_EQ(0u, values[1]);
EXPECT_EQ(0xEF03060708090A0B, values[2]);
}
ASSEMBLER_TEST_GENERATE(StoreDoubleWord_Neg, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ sd(A1, Address(A0, -8));
__ ret();
}
ASSEMBLER_TEST_RUN(StoreDoubleWord_Neg, test) {
EXPECT_DISASSEMBLY(
"feb53c23 sd a1, -8(a0)\n"
"00008067 ret\n");
uint64_t* values = reinterpret_cast<uint64_t*>(malloc(3 * sizeof(uint64_t)));
values[0] = 0;
values[1] = 0;
values[2] = 0;
Call(test->entry(), reinterpret_cast<intx_t>(&values[1]), 0xAB01020304050607);
EXPECT_EQ(0xAB01020304050607, values[0]);
EXPECT_EQ(0u, values[1]);
EXPECT_EQ(0u, values[2]);
}
#endif
ASSEMBLER_TEST_GENERATE(AddImmediate1, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ addi(A0, A0, 42);
__ ret();
}
ASSEMBLER_TEST_RUN(AddImmediate1, test) {
EXPECT_DISASSEMBLY(
"02a50513 addi a0, a0, 42\n"
"00008067 ret\n");
EXPECT_EQ(42, Call(test->entry(), 0));
EXPECT_EQ(40, Call(test->entry(), -2));
EXPECT_EQ(0, Call(test->entry(), -42));
}
ASSEMBLER_TEST_GENERATE(AddImmediate2, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ addi(A0, A0, -42);
__ ret();
}
ASSEMBLER_TEST_RUN(AddImmediate2, test) {
EXPECT_DISASSEMBLY(
"fd650513 addi a0, a0, -42\n"
"00008067 ret\n");
EXPECT_EQ(-42, Call(test->entry(), 0));
EXPECT_EQ(-44, Call(test->entry(), -2));
EXPECT_EQ(38, Call(test->entry(), 80));
}
ASSEMBLER_TEST_GENERATE(SetLessThanImmediate1, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ slti(A0, A0, 7);
__ ret();
}
ASSEMBLER_TEST_RUN(SetLessThanImmediate1, test) {
EXPECT_DISASSEMBLY(
"00752513 slti a0, a0, 7\n"
"00008067 ret\n");
EXPECT_EQ(1, Call(test->entry(), 6));
EXPECT_EQ(0, Call(test->entry(), 7));
EXPECT_EQ(0, Call(test->entry(), 8));
EXPECT_EQ(1, Call(test->entry(), -6));
EXPECT_EQ(1, Call(test->entry(), -7));
EXPECT_EQ(1, Call(test->entry(), -8));
}
ASSEMBLER_TEST_GENERATE(SetLessThanImmediate2, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ slti(A0, A0, -7);
__ ret();
}
ASSEMBLER_TEST_RUN(SetLessThanImmediate2, test) {
EXPECT_DISASSEMBLY(
"ff952513 slti a0, a0, -7\n"
"00008067 ret\n");
EXPECT_EQ(0, Call(test->entry(), 6));
EXPECT_EQ(0, Call(test->entry(), 7));
EXPECT_EQ(0, Call(test->entry(), 8));
EXPECT_EQ(0, Call(test->entry(), -6));
EXPECT_EQ(0, Call(test->entry(), -7));
EXPECT_EQ(1, Call(test->entry(), -8));
}
ASSEMBLER_TEST_GENERATE(SetLessThanImmediateUnsigned1, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ sltiu(A0, A0, 7);
__ ret();
}
ASSEMBLER_TEST_RUN(SetLessThanImmediateUnsigned1, test) {
EXPECT_DISASSEMBLY(
"00753513 sltiu a0, a0, 7\n"
"00008067 ret\n");
EXPECT_EQ(1, Call(test->entry(), 6));
EXPECT_EQ(0, Call(test->entry(), 7));
EXPECT_EQ(0, Call(test->entry(), 8));
EXPECT_EQ(0, Call(test->entry(), -6));
EXPECT_EQ(0, Call(test->entry(), -7));
EXPECT_EQ(0, Call(test->entry(), -8));
}
ASSEMBLER_TEST_GENERATE(SetLessThanImmediateUnsigned2, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ sltiu(A0, A0, -7);
__ ret();
}
ASSEMBLER_TEST_RUN(SetLessThanImmediateUnsigned2, test) {
EXPECT_DISASSEMBLY(
"ff953513 sltiu a0, a0, -7\n"
"00008067 ret\n");
EXPECT_EQ(1, Call(test->entry(), 6));
EXPECT_EQ(1, Call(test->entry(), 7));
EXPECT_EQ(1, Call(test->entry(), 8));
EXPECT_EQ(0, Call(test->entry(), -6));
EXPECT_EQ(0, Call(test->entry(), -7));
EXPECT_EQ(1, Call(test->entry(), -8));
}
ASSEMBLER_TEST_GENERATE(XorImmediate1, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ xori(A0, A0, 42);
__ ret();
}
ASSEMBLER_TEST_RUN(XorImmediate1, test) {
EXPECT_DISASSEMBLY(
"02a54513 xori a0, a0, 42\n"
"00008067 ret\n");
EXPECT_EQ(42, Call(test->entry(), 0));
EXPECT_EQ(43, Call(test->entry(), 1));
EXPECT_EQ(32, Call(test->entry(), 10));
EXPECT_EQ(-43, Call(test->entry(), -1));
EXPECT_EQ(-36, Call(test->entry(), -10));
}
ASSEMBLER_TEST_GENERATE(XorImmediate2, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ xori(A0, A0, -42);
__ ret();
}
ASSEMBLER_TEST_RUN(XorImmediate2, test) {
EXPECT_DISASSEMBLY(
"fd654513 xori a0, a0, -42\n"
"00008067 ret\n");
EXPECT_EQ(-42, Call(test->entry(), 0));
EXPECT_EQ(-41, Call(test->entry(), 1));
EXPECT_EQ(-36, Call(test->entry(), 10));
EXPECT_EQ(41, Call(test->entry(), -1));
EXPECT_EQ(32, Call(test->entry(), -10));
}
ASSEMBLER_TEST_GENERATE(OrImmediate1, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ ori(A0, A0, -6);
__ ret();
}
ASSEMBLER_TEST_RUN(OrImmediate1, test) {
EXPECT_DISASSEMBLY(
"ffa56513 ori a0, a0, -6\n"
"00008067 ret\n");
EXPECT_EQ(-6, Call(test->entry(), 0));
EXPECT_EQ(-5, Call(test->entry(), 1));
EXPECT_EQ(-5, Call(test->entry(), 11));
EXPECT_EQ(-1, Call(test->entry(), -1));
EXPECT_EQ(-1, Call(test->entry(), -11));
}
ASSEMBLER_TEST_GENERATE(OrImmediate2, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ ori(A0, A0, 6);
__ ret();
}
ASSEMBLER_TEST_RUN(OrImmediate2, test) {
EXPECT_DISASSEMBLY(
"00656513 ori a0, a0, 6\n"
"00008067 ret\n");
EXPECT_EQ(6, Call(test->entry(), 0));
EXPECT_EQ(7, Call(test->entry(), 1));
EXPECT_EQ(15, Call(test->entry(), 11));
EXPECT_EQ(-1, Call(test->entry(), -1));
EXPECT_EQ(-9, Call(test->entry(), -11));
}
ASSEMBLER_TEST_GENERATE(AndImmediate1, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ andi(A0, A0, -6);
__ ret();
}
ASSEMBLER_TEST_RUN(AndImmediate1, test) {
EXPECT_DISASSEMBLY(
"ffa57513 andi a0, a0, -6\n"
"00008067 ret\n");
EXPECT_EQ(0, Call(test->entry(), 0));
EXPECT_EQ(0, Call(test->entry(), 1));
EXPECT_EQ(10, Call(test->entry(), 11));
EXPECT_EQ(-6, Call(test->entry(), -1));
EXPECT_EQ(-16, Call(test->entry(), -11));
}
ASSEMBLER_TEST_GENERATE(AndImmediate2, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ andi(A0, A0, 6);
__ ret();
}
ASSEMBLER_TEST_RUN(AndImmediate2, test) {
EXPECT_DISASSEMBLY(
"00657513 andi a0, a0, 6\n"
"00008067 ret\n");
EXPECT_EQ(0, Call(test->entry(), 0));
EXPECT_EQ(0, Call(test->entry(), 1));
EXPECT_EQ(2, Call(test->entry(), 11));
EXPECT_EQ(6, Call(test->entry(), -1));
EXPECT_EQ(4, Call(test->entry(), -11));
}
ASSEMBLER_TEST_GENERATE(ShiftLeftLogicalImmediate, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ slli(A0, A0, 2);
__ ret();
}
ASSEMBLER_TEST_RUN(ShiftLeftLogicalImmediate, test) {
EXPECT_DISASSEMBLY(
"00251513 slli a0, a0, 0x2\n"
"00008067 ret\n");
EXPECT_EQ(84, Call(test->entry(), 21));
EXPECT_EQ(4, Call(test->entry(), 1));
EXPECT_EQ(0, Call(test->entry(), 0));
EXPECT_EQ(-4, Call(test->entry(), -1));
EXPECT_EQ(-84, Call(test->entry(), -21));
}
ASSEMBLER_TEST_GENERATE(ShiftLeftLogicalImmediate2, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ slli(A0, A0, XLEN - 1);
__ ret();
}
ASSEMBLER_TEST_RUN(ShiftLeftLogicalImmediate2, test) {
#if XLEN == 32
EXPECT_DISASSEMBLY(
"01f51513 slli a0, a0, 0x1f\n"
"00008067 ret\n");
#elif XLEN == 64
EXPECT_DISASSEMBLY(
"03f51513 slli a0, a0, 0x3f\n"
"00008067 ret\n");
#endif
EXPECT_EQ(0, Call(test->entry(), 2));
EXPECT_EQ(kMinIntX, Call(test->entry(), 1));
EXPECT_EQ(0, Call(test->entry(), 0));
EXPECT_EQ(kMinIntX, Call(test->entry(), -1));
EXPECT_EQ(0, Call(test->entry(), -2));
}
ASSEMBLER_TEST_GENERATE(ShiftRightLogicalImmediate, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ srli(A0, A0, 2);
__ ret();
}
ASSEMBLER_TEST_RUN(ShiftRightLogicalImmediate, test) {
EXPECT_DISASSEMBLY(
"00255513 srli a0, a0, 0x2\n"
"00008067 ret\n");
EXPECT_EQ(5, Call(test->entry(), 21));
EXPECT_EQ(0, Call(test->entry(), 1));
EXPECT_EQ(0, Call(test->entry(), 0));
EXPECT_EQ(static_cast<intx_t>(static_cast<uintx_t>(-1) >> 2),
Call(test->entry(), -1));
EXPECT_EQ(static_cast<intx_t>(static_cast<uintx_t>(-21) >> 2),
Call(test->entry(), -21));
}
ASSEMBLER_TEST_GENERATE(ShiftRightLogicalImmediate2, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ srli(A0, A0, XLEN - 1);
__ ret();
}
ASSEMBLER_TEST_RUN(ShiftRightLogicalImmediate2, test) {
#if XLEN == 32
EXPECT_DISASSEMBLY(
"01f55513 srli a0, a0, 0x1f\n"
"00008067 ret\n");
#elif XLEN == 64
EXPECT_DISASSEMBLY(
"03f55513 srli a0, a0, 0x3f\n"
"00008067 ret\n");
#endif
EXPECT_EQ(0, Call(test->entry(), 21));
EXPECT_EQ(0, Call(test->entry(), 1));
EXPECT_EQ(0, Call(test->entry(), 0));
EXPECT_EQ(1, Call(test->entry(), -1));
EXPECT_EQ(1, Call(test->entry(), -21));
}
ASSEMBLER_TEST_GENERATE(ShiftRightArithmeticImmediate, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ srai(A0, A0, 2);
__ ret();
}
ASSEMBLER_TEST_RUN(ShiftRightArithmeticImmediate, test) {
EXPECT_DISASSEMBLY(
"40255513 srai a0, a0, 0x2\n"
"00008067 ret\n");
EXPECT_EQ(5, Call(test->entry(), 21));
EXPECT_EQ(0, Call(test->entry(), 1));
EXPECT_EQ(0, Call(test->entry(), 0));
EXPECT_EQ(-1, Call(test->entry(), -1));
EXPECT_EQ(-6, Call(test->entry(), -21));
}
ASSEMBLER_TEST_GENERATE(ShiftRightArithmeticImmediate2, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ srai(A0, A0, XLEN - 1);
__ ret();
}
ASSEMBLER_TEST_RUN(ShiftRightArithmeticImmediate2, test) {
#if XLEN == 32
EXPECT_DISASSEMBLY(
"41f55513 srai a0, a0, 0x1f\n" // CHECK
"00008067 ret\n");
#elif XLEN == 64
EXPECT_DISASSEMBLY(
"43f55513 srai a0, a0, 0x3f\n" // CHECK
"00008067 ret\n");
#endif
EXPECT_EQ(0, Call(test->entry(), 21));
EXPECT_EQ(0, Call(test->entry(), 1));
EXPECT_EQ(0, Call(test->entry(), 0));
EXPECT_EQ(-1, Call(test->entry(), -1));
EXPECT_EQ(-1, Call(test->entry(), -21));
}
ASSEMBLER_TEST_GENERATE(Add, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ add(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(Add, test) {
EXPECT_DISASSEMBLY(
"00b50533 add a0, a0, a1\n"
"00008067 ret\n");
EXPECT_EQ(24, Call(test->entry(), 7, 17));
EXPECT_EQ(-10, Call(test->entry(), 7, -17));
EXPECT_EQ(10, Call(test->entry(), -7, 17));
EXPECT_EQ(-24, Call(test->entry(), -7, -17));
EXPECT_EQ(24, Call(test->entry(), 17, 7));
EXPECT_EQ(10, Call(test->entry(), 17, -7));
EXPECT_EQ(-10, Call(test->entry(), -17, 7));
EXPECT_EQ(-24, Call(test->entry(), -17, -7));
}
ASSEMBLER_TEST_GENERATE(Subtract, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ sub(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(Subtract, test) {
EXPECT_DISASSEMBLY(
"40b50533 sub a0, a0, a1\n"
"00008067 ret\n");
EXPECT_EQ(-10, Call(test->entry(), 7, 17));
EXPECT_EQ(24, Call(test->entry(), 7, -17));
EXPECT_EQ(-24, Call(test->entry(), -7, 17));
EXPECT_EQ(10, Call(test->entry(), -7, -17));
EXPECT_EQ(10, Call(test->entry(), 17, 7));
EXPECT_EQ(24, Call(test->entry(), 17, -7));
EXPECT_EQ(-24, Call(test->entry(), -17, 7));
EXPECT_EQ(-10, Call(test->entry(), -17, -7));
}
ASSEMBLER_TEST_GENERATE(ShiftLeftLogical, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ sll(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(ShiftLeftLogical, test) {
EXPECT_DISASSEMBLY(
"00b51533 sll a0, a0, a1\n"
"00008067 ret\n");
EXPECT_EQ(2176, Call(test->entry(), 17, 7));
EXPECT_EQ(-2176, Call(test->entry(), -17, 7));
EXPECT_EQ(34, Call(test->entry(), 17, 1));
EXPECT_EQ(-34, Call(test->entry(), -17, 1));
EXPECT_EQ(17, Call(test->entry(), 17, 0));
EXPECT_EQ(-17, Call(test->entry(), -17, 0));
}
ASSEMBLER_TEST_GENERATE(SetLessThan, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ slt(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(SetLessThan, test) {
EXPECT_DISASSEMBLY(
"00b52533 slt a0, a0, a1\n"
"00008067 ret\n");
EXPECT_EQ(0, Call(test->entry(), 7, 7));
EXPECT_EQ(0, Call(test->entry(), -7, -7));
EXPECT_EQ(1, Call(test->entry(), 7, 17));
EXPECT_EQ(0, Call(test->entry(), 7, -17));
EXPECT_EQ(1, Call(test->entry(), -7, 17));
EXPECT_EQ(0, Call(test->entry(), -7, -17));
EXPECT_EQ(0, Call(test->entry(), 17, 7));
EXPECT_EQ(0, Call(test->entry(), 17, -7));
EXPECT_EQ(1, Call(test->entry(), -17, 7));
EXPECT_EQ(1, Call(test->entry(), -17, -7));
}
ASSEMBLER_TEST_GENERATE(SetLessThanUnsigned, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ sltu(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(SetLessThanUnsigned, test) {
EXPECT_DISASSEMBLY(
"00b53533 sltu a0, a0, a1\n"
"00008067 ret\n");
EXPECT_EQ(0, Call(test->entry(), 7, 7));
EXPECT_EQ(0, Call(test->entry(), -7, -7));
EXPECT_EQ(1, Call(test->entry(), 7, 17));
EXPECT_EQ(1, Call(test->entry(), 7, -17));
EXPECT_EQ(0, Call(test->entry(), -7, 17));
EXPECT_EQ(0, Call(test->entry(), -7, -17));
EXPECT_EQ(0, Call(test->entry(), 17, 7));
EXPECT_EQ(1, Call(test->entry(), 17, -7));
EXPECT_EQ(0, Call(test->entry(), -17, 7));
EXPECT_EQ(1, Call(test->entry(), -17, -7));
}
ASSEMBLER_TEST_GENERATE(Xor, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ xor_(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(Xor, test) {
EXPECT_DISASSEMBLY(
"00b54533 xor a0, a0, a1\n"
"00008067 ret\n");
EXPECT_EQ(22, Call(test->entry(), 7, 17));
EXPECT_EQ(-24, Call(test->entry(), 7, -17));
EXPECT_EQ(-24, Call(test->entry(), -7, 17));
EXPECT_EQ(22, Call(test->entry(), -7, -17));
EXPECT_EQ(22, Call(test->entry(), 17, 7));
EXPECT_EQ(-24, Call(test->entry(), 17, -7));
EXPECT_EQ(-24, Call(test->entry(), -17, 7));
EXPECT_EQ(22, Call(test->entry(), -17, -7));
}
ASSEMBLER_TEST_GENERATE(ShiftRightLogical, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ srl(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(ShiftRightLogical, test) {
EXPECT_DISASSEMBLY(
"00b55533 srl a0, a0, a1\n"
"00008067 ret\n");
EXPECT_EQ(0, Call(test->entry(), 17, 7));
EXPECT_EQ(static_cast<intx_t>(static_cast<uintx_t>(-17) >> 7),
Call(test->entry(), -17, 7));
EXPECT_EQ(8, Call(test->entry(), 17, 1));
EXPECT_EQ(static_cast<intx_t>(static_cast<uintx_t>(-17) >> 1),
Call(test->entry(), -17, 1));
EXPECT_EQ(17, Call(test->entry(), 17, 0));
EXPECT_EQ(-17, Call(test->entry(), -17, 0));
}
ASSEMBLER_TEST_GENERATE(ShiftRightArithmetic, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ sra(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(ShiftRightArithmetic, test) {
EXPECT_DISASSEMBLY(
"40b55533 sra a0, a0, a1\n"
"00008067 ret\n");
EXPECT_EQ(0, Call(test->entry(), 17, 7));
EXPECT_EQ(-1, Call(test->entry(), -17, 7));
EXPECT_EQ(8, Call(test->entry(), 17, 1));
EXPECT_EQ(-9, Call(test->entry(), -17, 1));
EXPECT_EQ(17, Call(test->entry(), 17, 0));
EXPECT_EQ(-17, Call(test->entry(), -17, 0));
}
ASSEMBLER_TEST_GENERATE(Or, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ or_(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(Or, test) {
EXPECT_DISASSEMBLY(
"00b56533 or a0, a0, a1\n"
"00008067 ret\n");
EXPECT_EQ(23, Call(test->entry(), 7, 17));
EXPECT_EQ(-17, Call(test->entry(), 7, -17));
EXPECT_EQ(-7, Call(test->entry(), -7, 17));
EXPECT_EQ(-1, Call(test->entry(), -7, -17));
EXPECT_EQ(23, Call(test->entry(), 17, 7));
EXPECT_EQ(-7, Call(test->entry(), 17, -7));
EXPECT_EQ(-17, Call(test->entry(), -17, 7));
EXPECT_EQ(-1, Call(test->entry(), -17, -7));
}
ASSEMBLER_TEST_GENERATE(And, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ and_(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(And, test) {
EXPECT_DISASSEMBLY(
"00b57533 and a0, a0, a1\n"
"00008067 ret\n");
EXPECT_EQ(1, Call(test->entry(), 7, 17));
EXPECT_EQ(7, Call(test->entry(), 7, -17));
EXPECT_EQ(17, Call(test->entry(), -7, 17));
EXPECT_EQ(-23, Call(test->entry(), -7, -17));
EXPECT_EQ(1, Call(test->entry(), 17, 7));
EXPECT_EQ(17, Call(test->entry(), 17, -7));
EXPECT_EQ(7, Call(test->entry(), -17, 7));
EXPECT_EQ(-23, Call(test->entry(), -17, -7));
}
ASSEMBLER_TEST_GENERATE(Fence, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fence();
__ fence(kRead, kWrite);
__ fence(kInput, kOutput);
__ fence(kMemory, kMemory);
__ fence(kAll, kAll);
__ ret();
}
ASSEMBLER_TEST_RUN(Fence, test) {
EXPECT_DISASSEMBLY(
"0ff0000f fence\n"
"0210000f fence r,w\n"
"0840000f fence i,o\n"
"0330000f fence rw,rw\n"
"0ff0000f fence\n"
"00008067 ret\n");
Call(test->entry());
}
ASSEMBLER_TEST_GENERATE(InstructionFence, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fencei();
__ ret();
}
ASSEMBLER_TEST_RUN(InstructionFence, test) {
EXPECT_DISASSEMBLY(
"0000100f fence.i\n"
"00008067 ret\n");
Call(test->entry());
}
ASSEMBLER_TEST_GENERATE(EnvironmentCall, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ ecall();
__ ret();
}
ASSEMBLER_TEST_RUN(EnvironmentCall, test) {
EXPECT_DISASSEMBLY(
"00000073 ecall\n"
"00008067 ret\n");
// Not running: would trap.
}
ASSEMBLER_TEST_GENERATE(EnvironmentBreak, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ ebreak();
__ ret();
}
ASSEMBLER_TEST_RUN(EnvironmentBreak, test) {
EXPECT_DISASSEMBLY(
"00100073 ebreak\n"
"00008067 ret\n");
// Not running: would trap.
}
ASSEMBLER_TEST_GENERATE(ControlStatusRegisters, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ csrrw(T0, 0x123, S1);
__ csrrs(T1, 0x123, S2);
__ csrrc(T2, 0x123, S3);
__ csrr(T3, 0x123);
__ csrw(0x123, S4);
__ csrs(0x123, S5);
__ csrc(0x123, S6);
__ csrrwi(T1, 0x123, 1);
__ csrrsi(T2, 0x123, 2);
__ csrrci(T3, 0x123, 3);
__ csrwi(0x123, 4);
__ csrsi(0x123, 5);
__ csrci(0x123, 6);
__ ret();
}
ASSEMBLER_TEST_RUN(ControlStatusRegisters, test) {
EXPECT_DISASSEMBLY(
"123492f3 csrrw t0, 0x123, thr\n"
"12392373 csrrs t1, 0x123, s2\n"
"1239b3f3 csrrc t2, 0x123, s3\n"
"12302e73 csrr t3, 0x123\n"
"123a1073 csrw 0x123, s4\n"
"123aa073 csrs 0x123, s5\n"
"123b3073 csrc 0x123, s6\n"
"1230d373 csrrwi t1, 0x123, 1\n"
"123163f3 csrrsi t2, 0x123, 2\n"
"1231fe73 csrrci t3, 0x123, 3\n"
"12325073 csrwi 0x123, 4\n"
"1232e073 csrsi 0x123, 5\n"
"12337073 csrci 0x123, 6\n"
"00008067 ret\n");
// Not running: would trap.
}
ASSEMBLER_TEST_GENERATE(Nop, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ nop();
__ ret();
}
ASSEMBLER_TEST_RUN(Nop, test) {
EXPECT_DISASSEMBLY(
"00000013 nop\n"
"00008067 ret\n");
EXPECT_EQ(123, Call(test->entry(), 123));
}
ASSEMBLER_TEST_GENERATE(Move, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ mv(A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(Move, test) {
EXPECT_DISASSEMBLY(
"00058513 mv a0, a1\n"
"00008067 ret\n");
EXPECT_EQ(36, Call(test->entry(), 42, 36));
}
ASSEMBLER_TEST_GENERATE(Not, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ not_(A0, A0);
__ ret();
}
ASSEMBLER_TEST_RUN(Not, test) {
EXPECT_DISASSEMBLY(
"fff54513 not a0, a0\n"
"00008067 ret\n");
EXPECT_EQ(~42, Call(test->entry(), 42));
EXPECT_EQ(~-42, Call(test->entry(), -42));
}
ASSEMBLER_TEST_GENERATE(Negate, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ neg(A0, A0);
__ ret();
}
ASSEMBLER_TEST_RUN(Negate, test) {
EXPECT_DISASSEMBLY(
"40a00533 neg a0, a0\n"
"00008067 ret\n");
EXPECT_EQ(-42, Call(test->entry(), 42));
EXPECT_EQ(42, Call(test->entry(), -42));
}
ASSEMBLER_TEST_GENERATE(SetNotEqualToZero, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ snez(A0, A0);
__ ret();
}
ASSEMBLER_TEST_RUN(SetNotEqualToZero, test) {
EXPECT_DISASSEMBLY(
"00a03533 snez a0, a0\n"
"00008067 ret\n");
EXPECT_EQ(1, Call(test->entry(), -42));
EXPECT_EQ(0, Call(test->entry(), 0));
EXPECT_EQ(1, Call(test->entry(), 42));
}
ASSEMBLER_TEST_GENERATE(SetEqualToZero, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ seqz(A0, A0);
__ ret();
}
ASSEMBLER_TEST_RUN(SetEqualToZero, test) {
EXPECT_DISASSEMBLY(
"00153513 seqz a0, a0\n"
"00008067 ret\n");
EXPECT_EQ(0, Call(test->entry(), -42));
EXPECT_EQ(1, Call(test->entry(), 0));
EXPECT_EQ(0, Call(test->entry(), 42));
}
ASSEMBLER_TEST_GENERATE(SetLessThanZero, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ sltz(A0, A0);
__ ret();
}
ASSEMBLER_TEST_RUN(SetLessThanZero, test) {
EXPECT_DISASSEMBLY(
"00052533 sltz a0, a0\n"
"00008067 ret\n");
EXPECT_EQ(1, Call(test->entry(), -42));
EXPECT_EQ(0, Call(test->entry(), 0));
EXPECT_EQ(0, Call(test->entry(), 42));
}
ASSEMBLER_TEST_GENERATE(SetGreaterThanZero, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ sgtz(A0, A0);
__ ret();
}
ASSEMBLER_TEST_RUN(SetGreaterThanZero, test) {
EXPECT_DISASSEMBLY(
"00a02533 sgtz a0, a0\n"
"00008067 ret\n");
EXPECT_EQ(0, Call(test->entry(), -42));
EXPECT_EQ(0, Call(test->entry(), 0));
EXPECT_EQ(1, Call(test->entry(), 42));
}
ASSEMBLER_TEST_GENERATE(BranchEqualZero, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
Label label;
__ beqz(A0, &label);
__ li(A0, 3);
__ ret();
__ Bind(&label);
__ li(A0, 4);
__ ret();
}
ASSEMBLER_TEST_RUN(BranchEqualZero, test) {
EXPECT_DISASSEMBLY(
"00050663 beqz a0, +12\n"
"00300513 li a0, 3\n"
"00008067 ret\n"
"00400513 li a0, 4\n"
"00008067 ret\n");
EXPECT_EQ(3, Call(test->entry(), -42));
EXPECT_EQ(4, Call(test->entry(), 0));
EXPECT_EQ(3, Call(test->entry(), 42));
}
ASSEMBLER_TEST_GENERATE(BranchNotEqualZero, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
Label label;
__ bnez(A0, &label);
__ li(A0, 3);
__ ret();
__ Bind(&label);
__ li(A0, 4);
__ ret();
}
ASSEMBLER_TEST_RUN(BranchNotEqualZero, test) {
EXPECT_DISASSEMBLY(
"00051663 bnez a0, +12\n"
"00300513 li a0, 3\n"
"00008067 ret\n"
"00400513 li a0, 4\n"
"00008067 ret\n");
EXPECT_EQ(4, Call(test->entry(), -42));
EXPECT_EQ(3, Call(test->entry(), 0));
EXPECT_EQ(4, Call(test->entry(), 42));
}
ASSEMBLER_TEST_GENERATE(BranchLessOrEqualZero, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
Label label;
__ blez(A0, &label);
__ li(A0, 3);
__ ret();
__ Bind(&label);
__ li(A0, 4);
__ ret();
}
ASSEMBLER_TEST_RUN(BranchLessOrEqualZero, test) {
EXPECT_DISASSEMBLY(
"00a05663 blez a0, +12\n"
"00300513 li a0, 3\n"
"00008067 ret\n"
"00400513 li a0, 4\n"
"00008067 ret\n");
EXPECT_EQ(4, Call(test->entry(), -42));
EXPECT_EQ(4, Call(test->entry(), 0));
EXPECT_EQ(3, Call(test->entry(), 42));
}
ASSEMBLER_TEST_GENERATE(BranchGreaterOrEqualZero, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
Label label;
__ bgez(A0, &label);
__ li(A0, 3);
__ ret();
__ Bind(&label);
__ li(A0, 4);
__ ret();
}
ASSEMBLER_TEST_RUN(BranchGreaterOrEqualZero, test) {
EXPECT_DISASSEMBLY(
"00055663 bgez a0, +12\n"
"00300513 li a0, 3\n"
"00008067 ret\n"
"00400513 li a0, 4\n"
"00008067 ret\n");
EXPECT_EQ(3, Call(test->entry(), -42));
EXPECT_EQ(4, Call(test->entry(), 0));
EXPECT_EQ(4, Call(test->entry(), 42));
}
ASSEMBLER_TEST_GENERATE(BranchLessThanZero, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
Label label;
__ bltz(A0, &label);
__ li(A0, 3);
__ ret();
__ Bind(&label);
__ li(A0, 4);
__ ret();
}
ASSEMBLER_TEST_RUN(BranchLessThanZero, test) {
EXPECT_DISASSEMBLY(
"00054663 bltz a0, +12\n"
"00300513 li a0, 3\n"
"00008067 ret\n"
"00400513 li a0, 4\n"
"00008067 ret\n");
EXPECT_EQ(4, Call(test->entry(), -42));
EXPECT_EQ(3, Call(test->entry(), 0));
EXPECT_EQ(3, Call(test->entry(), 42));
}
ASSEMBLER_TEST_GENERATE(BranchGreaterThanZero, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
Label label;
__ bgtz(A0, &label);
__ li(A0, 3);
__ ret();
__ Bind(&label);
__ li(A0, 4);
__ ret();
}
ASSEMBLER_TEST_RUN(BranchGreaterThanZero, test) {
EXPECT_DISASSEMBLY(
"00a04663 bgtz a0, +12\n"
"00300513 li a0, 3\n"
"00008067 ret\n"
"00400513 li a0, 4\n"
"00008067 ret\n");
EXPECT_EQ(3, Call(test->entry(), -42));
EXPECT_EQ(3, Call(test->entry(), 0));
EXPECT_EQ(4, Call(test->entry(), 42));
}
#if XLEN >= 64
ASSEMBLER_TEST_GENERATE(AddImmediateWord1, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ addiw(A0, A0, 42);
__ ret();
}
ASSEMBLER_TEST_RUN(AddImmediateWord1, test) {
EXPECT_DISASSEMBLY(
"02a5051b addiw a0, a0, 42\n"
"00008067 ret\n");
EXPECT_EQ(42, Call(test->entry(), 0));
EXPECT_EQ(40, Call(test->entry(), -2));
EXPECT_EQ(0, Call(test->entry(), -42));
}
ASSEMBLER_TEST_GENERATE(AddImmediateWord2, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ addiw(A0, A0, -42);
__ ret();
}
ASSEMBLER_TEST_RUN(AddImmediateWord2, test) {
EXPECT_DISASSEMBLY(
"fd65051b addiw a0, a0, -42\n"
"00008067 ret\n");
EXPECT_EQ(-42, Call(test->entry(), 0));
EXPECT_EQ(-44, Call(test->entry(), -2));
EXPECT_EQ(38, Call(test->entry(), 80));
}
ASSEMBLER_TEST_GENERATE(ShiftLeftLogicalImmediateWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ slliw(A0, A0, 2);
__ ret();
}
ASSEMBLER_TEST_RUN(ShiftLeftLogicalImmediateWord, test) {
EXPECT_DISASSEMBLY(
"0025151b slliw a0, a0, 0x2\n"
"00008067 ret\n");
EXPECT_EQ(84, Call(test->entry(), 21));
EXPECT_EQ(4, Call(test->entry(), 1));
EXPECT_EQ(0, Call(test->entry(), 0));
EXPECT_EQ(-4, Call(test->entry(), -1));
EXPECT_EQ(-84, Call(test->entry(), -21));
}
ASSEMBLER_TEST_GENERATE(ShiftRightLogicalImmediateWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ srliw(A0, A0, 2);
__ ret();
}
ASSEMBLER_TEST_RUN(ShiftRightLogicalImmediateWord, test) {
EXPECT_DISASSEMBLY(
"0025551b srliw a0, a0, 0x2\n"
"00008067 ret\n");
EXPECT_EQ(5, Call(test->entry(), 21));
EXPECT_EQ(0, Call(test->entry(), 1));
EXPECT_EQ(0, Call(test->entry(), 0));
EXPECT_EQ(sign_extend(static_cast<uint32_t>(-1) >> 2),
Call(test->entry(), -1));
EXPECT_EQ(sign_extend(static_cast<uint32_t>(-21) >> 2),
Call(test->entry(), -21));
}
ASSEMBLER_TEST_GENERATE(ShiftRightArithmeticImmediateWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ sraiw(A0, A0, 2);
__ ret();
}
ASSEMBLER_TEST_RUN(ShiftRightArithmeticImmediateWord, test) {
EXPECT_DISASSEMBLY(
"4025551b sraiw a0, a0, 0x2\n"
"00008067 ret\n");
EXPECT_EQ(5, Call(test->entry(), 21));
EXPECT_EQ(0, Call(test->entry(), 1));
EXPECT_EQ(0, Call(test->entry(), 0));
EXPECT_EQ(-1, Call(test->entry(), -1));
EXPECT_EQ(-6, Call(test->entry(), -21));
}
ASSEMBLER_TEST_GENERATE(AddWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ addw(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(AddWord, test) {
EXPECT_DISASSEMBLY(
"00b5053b addw a0, a0, a1\n"
"00008067 ret\n");
EXPECT_EQ(24, Call(test->entry(), 7, 17));
EXPECT_EQ(-10, Call(test->entry(), 7, -17));
EXPECT_EQ(10, Call(test->entry(), -7, 17));
EXPECT_EQ(-24, Call(test->entry(), -7, -17));
EXPECT_EQ(24, Call(test->entry(), 17, 7));
EXPECT_EQ(10, Call(test->entry(), 17, -7));
EXPECT_EQ(-10, Call(test->entry(), -17, 7));
EXPECT_EQ(-24, Call(test->entry(), -17, -7));
EXPECT_EQ(3, Call(test->entry(), 0x200000002, 0x100000001));
}
ASSEMBLER_TEST_GENERATE(SubtractWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ subw(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(SubtractWord, test) {
EXPECT_DISASSEMBLY(
"40b5053b subw a0, a0, a1\n"
"00008067 ret\n");
EXPECT_EQ(-10, Call(test->entry(), 7, 17));
EXPECT_EQ(24, Call(test->entry(), 7, -17));
EXPECT_EQ(-24, Call(test->entry(), -7, 17));
EXPECT_EQ(10, Call(test->entry(), -7, -17));
EXPECT_EQ(10, Call(test->entry(), 17, 7));
EXPECT_EQ(24, Call(test->entry(), 17, -7));
EXPECT_EQ(-24, Call(test->entry(), -17, 7));
EXPECT_EQ(-10, Call(test->entry(), -17, -7));
EXPECT_EQ(1, Call(test->entry(), 0x200000002, 0x100000001));
}
ASSEMBLER_TEST_GENERATE(ShiftLeftLogicalWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ sllw(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(ShiftLeftLogicalWord, test) {
EXPECT_DISASSEMBLY(
"00b5153b sllw a0, a0, a1\n"
"00008067 ret\n");
EXPECT_EQ(2176, Call(test->entry(), 17, 7));
EXPECT_EQ(-2176, Call(test->entry(), -17, 7));
EXPECT_EQ(34, Call(test->entry(), 17, 1));
EXPECT_EQ(-34, Call(test->entry(), -17, 1));
EXPECT_EQ(17, Call(test->entry(), 17, 0));
EXPECT_EQ(-17, Call(test->entry(), -17, 0));
EXPECT_EQ(0x10, Call(test->entry(), 0x10000001, 4));
}
ASSEMBLER_TEST_GENERATE(ShiftRightLogicalWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ srlw(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(ShiftRightLogicalWord, test) {
EXPECT_DISASSEMBLY(
"00b5553b srlw a0, a0, a1\n"
"00008067 ret\n");
EXPECT_EQ(0, Call(test->entry(), 17, 7));
EXPECT_EQ(sign_extend(static_cast<uint32_t>(-17) >> 7),
Call(test->entry(), -17, 7));
EXPECT_EQ(8, Call(test->entry(), 17, 1));
EXPECT_EQ(sign_extend(static_cast<uint32_t>(-17) >> 1),
Call(test->entry(), -17, 1));
EXPECT_EQ(17, Call(test->entry(), 17, 0));
EXPECT_EQ(-17, Call(test->entry(), -17, 0));
}
ASSEMBLER_TEST_GENERATE(ShiftRightArithmeticWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ sraw(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(ShiftRightArithmeticWord, test) {
EXPECT_DISASSEMBLY(
"40b5553b sraw a0, a0, a1\n"
"00008067 ret\n");
EXPECT_EQ(0, Call(test->entry(), 17, 7));
EXPECT_EQ(-1, Call(test->entry(), -17, 7));
EXPECT_EQ(8, Call(test->entry(), 17, 1));
EXPECT_EQ(-9, Call(test->entry(), -17, 1));
EXPECT_EQ(17, Call(test->entry(), 17, 0));
EXPECT_EQ(-17, Call(test->entry(), -17, 0));
}
ASSEMBLER_TEST_GENERATE(NegateWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ negw(A0, A0);
__ ret();
}
ASSEMBLER_TEST_RUN(NegateWord, test) {
EXPECT_DISASSEMBLY(
"40a0053b negw a0, a0\n"
"00008067 ret\n");
EXPECT_EQ(0, Call(test->entry(), 0));
EXPECT_EQ(-42, Call(test->entry(), 42));
EXPECT_EQ(42, Call(test->entry(), -42));
EXPECT_EQ(1, Call(test->entry(), 0x10FFFFFFFF));
}
ASSEMBLER_TEST_GENERATE(SignExtendWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ sextw(A0, A0);
__ ret();
}
ASSEMBLER_TEST_RUN(SignExtendWord, test) {
EXPECT_DISASSEMBLY(
"0005051b sext.w a0, a0\n"
"00008067 ret\n");
EXPECT_EQ(0, Call(test->entry(), 0));
EXPECT_EQ(42, Call(test->entry(), 42));
EXPECT_EQ(-42, Call(test->entry(), -42));
EXPECT_EQ(-1, Call(test->entry(), 0x10FFFFFFFF));
}
#endif // XLEN >= 64
ASSEMBLER_TEST_GENERATE(Multiply, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ mul(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(Multiply, test) {
EXPECT_DISASSEMBLY(
"02b50533 mul a0, a0, a1\n"
"00008067 ret\n");
EXPECT_EQ(68, Call(test->entry(), 4, 17));
EXPECT_EQ(-68, Call(test->entry(), -4, 17));
EXPECT_EQ(-68, Call(test->entry(), 4, -17));
EXPECT_EQ(68, Call(test->entry(), -4, -17));
EXPECT_EQ(68, Call(test->entry(), 17, 4));
EXPECT_EQ(-68, Call(test->entry(), -17, 4));
EXPECT_EQ(-68, Call(test->entry(), 17, -4));
EXPECT_EQ(68, Call(test->entry(), -17, -4));
}
ASSEMBLER_TEST_GENERATE(MultiplyHigh, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ mulh(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(MultiplyHigh, test) {
EXPECT_DISASSEMBLY(
"02b51533 mulh a0, a0, a1\n"
"00008067 ret\n");
EXPECT_EQ(0, Call(test->entry(), 4, 17));
EXPECT_EQ(-1, Call(test->entry(), -4, 17));
EXPECT_EQ(-1, Call(test->entry(), 4, -17));
EXPECT_EQ(0, Call(test->entry(), -4, -17));
EXPECT_EQ(0, Call(test->entry(), 17, 4));
EXPECT_EQ(-1, Call(test->entry(), -17, 4));
EXPECT_EQ(-1, Call(test->entry(), 17, -4));
EXPECT_EQ(0, Call(test->entry(), -17, -4));
}
ASSEMBLER_TEST_GENERATE(MultiplyHighSignedUnsigned, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ mulhsu(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(MultiplyHighSignedUnsigned, test) {
EXPECT_DISASSEMBLY(
"02b52533 mulhsu a0, a0, a1\n"
"00008067 ret\n");
EXPECT_EQ(0, Call(test->entry(), 4, 17));
EXPECT_EQ(-1, Call(test->entry(), -4, 17));
EXPECT_EQ(3, Call(test->entry(), 4, -17));
EXPECT_EQ(-4, Call(test->entry(), -4, -17));
EXPECT_EQ(0, Call(test->entry(), 17, 4));
EXPECT_EQ(-1, Call(test->entry(), -17, 4));
EXPECT_EQ(16, Call(test->entry(), 17, -4));
EXPECT_EQ(-17, Call(test->entry(), -17, -4));
}
ASSEMBLER_TEST_GENERATE(MultiplyHighUnsigned, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ mulhu(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(MultiplyHighUnsigned, test) {
EXPECT_DISASSEMBLY(
"02b53533 mulhu a0, a0, a1\n"
"00008067 ret\n");
EXPECT_EQ(0, Call(test->entry(), 4, 17));
EXPECT_EQ(16, Call(test->entry(), -4, 17));
EXPECT_EQ(3, Call(test->entry(), 4, -17));
EXPECT_EQ(-21, Call(test->entry(), -4, -17));
EXPECT_EQ(0, Call(test->entry(), 17, 4));
EXPECT_EQ(3, Call(test->entry(), -17, 4));
EXPECT_EQ(16, Call(test->entry(), 17, -4));
EXPECT_EQ(-21, Call(test->entry(), -17, -4));
}
ASSEMBLER_TEST_GENERATE(Divide, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ div(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(Divide, test) {
EXPECT_DISASSEMBLY(
"02b54533 div a0, a0, a1\n"
"00008067 ret\n");
EXPECT_EQ(0, Call(test->entry(), 4, 17));
EXPECT_EQ(0, Call(test->entry(), -4, 17));
EXPECT_EQ(0, Call(test->entry(), 4, -17));
EXPECT_EQ(0, Call(test->entry(), -4, -17));
EXPECT_EQ(4, Call(test->entry(), 17, 4));
EXPECT_EQ(-4, Call(test->entry(), -17, 4));
EXPECT_EQ(-4, Call(test->entry(), 17, -4));
EXPECT_EQ(4, Call(test->entry(), -17, -4));
}
ASSEMBLER_TEST_GENERATE(DivideUnsigned, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ divu(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(DivideUnsigned, test) {
EXPECT_DISASSEMBLY(
"02b55533 divu a0, a0, a1\n"
"00008067 ret\n");
EXPECT_EQ(0, Call(test->entry(), 4, 17));
#if XLEN == 32
EXPECT_EQ(252645134, Call(test->entry(), -4, 17));
#else
EXPECT_EQ(1085102592571150094, Call(test->entry(), -4, 17));
#endif
EXPECT_EQ(0, Call(test->entry(), 4, -17));
EXPECT_EQ(1, Call(test->entry(), -4, -17));
EXPECT_EQ(4, Call(test->entry(), 17, 4));
#if XLEN == 32
EXPECT_EQ(1073741819, Call(test->entry(), -17, 4));
#else
EXPECT_EQ(4611686018427387899, Call(test->entry(), -17, 4));
#endif
EXPECT_EQ(0, Call(test->entry(), 17, -4));
EXPECT_EQ(0, Call(test->entry(), -17, -4));
}
ASSEMBLER_TEST_GENERATE(Remainder, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ rem(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(Remainder, test) {
EXPECT_DISASSEMBLY(
"02b56533 rem a0, a0, a1\n"
"00008067 ret\n");
EXPECT_EQ(4, Call(test->entry(), 4, 17));
EXPECT_EQ(-4, Call(test->entry(), -4, 17));
EXPECT_EQ(4, Call(test->entry(), 4, -17));
EXPECT_EQ(-4, Call(test->entry(), -4, -17));
EXPECT_EQ(1, Call(test->entry(), 17, 4));
EXPECT_EQ(-1, Call(test->entry(), -17, 4));
EXPECT_EQ(1, Call(test->entry(), 17, -4));
EXPECT_EQ(-1, Call(test->entry(), -17, -4));
}
ASSEMBLER_TEST_GENERATE(RemainderUnsigned, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ remu(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(RemainderUnsigned, test) {
EXPECT_DISASSEMBLY(
"02b57533 remu a0, a0, a1\n"
"00008067 ret\n");
EXPECT_EQ(4, Call(test->entry(), 4, 17));
EXPECT_EQ(14, Call(test->entry(), -4, 17));
EXPECT_EQ(4, Call(test->entry(), 4, -17));
EXPECT_EQ(13, Call(test->entry(), -4, -17));
EXPECT_EQ(1, Call(test->entry(), 17, 4));
EXPECT_EQ(3, Call(test->entry(), -17, 4));
EXPECT_EQ(17, Call(test->entry(), 17, -4));
EXPECT_EQ(-17, Call(test->entry(), -17, -4));
}
#if XLEN >= 64
ASSEMBLER_TEST_GENERATE(MultiplyWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ mulw(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(MultiplyWord, test) {
EXPECT_DISASSEMBLY(
"02b5053b mulw a0, a0, a1\n"
"00008067 ret\n");
EXPECT_EQ(68, Call(test->entry(), 4, 17));
EXPECT_EQ(-68, Call(test->entry(), -4, 17));
EXPECT_EQ(-68, Call(test->entry(), 4, -17));
EXPECT_EQ(68, Call(test->entry(), -4, -17));
EXPECT_EQ(68, Call(test->entry(), 17, 4));
EXPECT_EQ(-68, Call(test->entry(), -17, 4));
EXPECT_EQ(-68, Call(test->entry(), 17, -4));
EXPECT_EQ(68, Call(test->entry(), -17, -4));
}
ASSEMBLER_TEST_GENERATE(DivideWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ divw(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(DivideWord, test) {
EXPECT_DISASSEMBLY(
"02b5453b divw a0, a0, a1\n"
"00008067 ret\n");
EXPECT_EQ(0, Call(test->entry(), 4, 17));
EXPECT_EQ(0, Call(test->entry(), -4, 17));
EXPECT_EQ(0, Call(test->entry(), 4, -17));
EXPECT_EQ(0, Call(test->entry(), -4, -17));
EXPECT_EQ(4, Call(test->entry(), 17, 4));
EXPECT_EQ(-4, Call(test->entry(), -17, 4));
EXPECT_EQ(-4, Call(test->entry(), 17, -4));
EXPECT_EQ(4, Call(test->entry(), -17, -4));
}
ASSEMBLER_TEST_GENERATE(DivideUnsignedWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ divuw(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(DivideUnsignedWord, test) {
EXPECT_DISASSEMBLY(
"02b5553b divuw a0, a0, a1\n"
"00008067 ret\n");
EXPECT_EQ(0, Call(test->entry(), 4, 17));
EXPECT_EQ(252645134, Call(test->entry(), -4, 17));
EXPECT_EQ(0, Call(test->entry(), 4, -17));
EXPECT_EQ(1, Call(test->entry(), -4, -17));
EXPECT_EQ(4, Call(test->entry(), 17, 4));
EXPECT_EQ(1073741819, Call(test->entry(), -17, 4));
EXPECT_EQ(0, Call(test->entry(), 17, -4));
EXPECT_EQ(0, Call(test->entry(), -17, -4));
}
ASSEMBLER_TEST_GENERATE(RemainderWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ remw(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(RemainderWord, test) {
EXPECT_DISASSEMBLY(
"02b5653b remw a0, a0, a1\n"
"00008067 ret\n");
EXPECT_EQ(4, Call(test->entry(), 4, 17));
EXPECT_EQ(-4, Call(test->entry(), -4, 17));
EXPECT_EQ(4, Call(test->entry(), 4, -17));
EXPECT_EQ(-4, Call(test->entry(), -4, -17));
EXPECT_EQ(1, Call(test->entry(), 17, 4));
EXPECT_EQ(-1, Call(test->entry(), -17, 4));
EXPECT_EQ(1, Call(test->entry(), 17, -4));
EXPECT_EQ(-1, Call(test->entry(), -17, -4));
}
ASSEMBLER_TEST_GENERATE(RemainderUnsignedWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ remuw(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(RemainderUnsignedWord, test) {
EXPECT_DISASSEMBLY(
"02b5753b remuw a0, a0, a1\n"
"00008067 ret\n");
EXPECT_EQ(4, Call(test->entry(), 4, 17));
EXPECT_EQ(14, Call(test->entry(), -4, 17));
EXPECT_EQ(4, Call(test->entry(), 4, -17));
EXPECT_EQ(13, Call(test->entry(), -4, -17));
EXPECT_EQ(1, Call(test->entry(), 17, 4));
EXPECT_EQ(3, Call(test->entry(), -17, 4));
EXPECT_EQ(17, Call(test->entry(), 17, -4));
EXPECT_EQ(-17, Call(test->entry(), -17, -4));
}
#endif
ASSEMBLER_TEST_GENERATE(LoadReserveStoreConditionalWord_Success, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ lrw(T0, Address(A0));
__ addi(T0, T0, 1);
__ scw(A0, T0, Address(A0));
__ ret();
}
ASSEMBLER_TEST_RUN(LoadReserveStoreConditionalWord_Success, test) {
EXPECT_DISASSEMBLY(
"100522af lr.w t0, (a0)\n"
"00128293 addi t0, t0, 1\n"
"1855252f sc.w a0, t0, (a0)\n"
"00008067 ret\n");
int32_t* value = reinterpret_cast<int32_t*>(malloc(sizeof(int32_t)));
*value = 0b1100;
EXPECT_EQ(0, Call(test->entry(), reinterpret_cast<intx_t>(value)));
EXPECT_EQ(0b1101, *value);
}
ASSEMBLER_TEST_GENERATE(LoadReserveStoreConditionalWord_Failure, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ li(T0, 42);
__ scw(A0, T0, Address(A0));
__ ret();
}
ASSEMBLER_TEST_RUN(LoadReserveStoreConditionalWord_Failure, test) {
EXPECT_DISASSEMBLY(
"02a00293 li t0, 42\n"
"1855252f sc.w a0, t0, (a0)\n"
"00008067 ret\n");
int32_t* value = reinterpret_cast<int32_t*>(malloc(sizeof(int32_t)));
*value = 0b1100;
EXPECT_EQ(false, 0 == Call(test->entry(), reinterpret_cast<intx_t>(value)));
EXPECT_EQ(0b1100, *value);
}
ASSEMBLER_TEST_GENERATE(AmoSwapWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ amoswapw(A0, A1, Address(A0));
__ ret();
}
ASSEMBLER_TEST_RUN(AmoSwapWord, test) {
EXPECT_DISASSEMBLY(
"08b5252f amoswap.w a0, a1, (a0)\n"
"00008067 ret\n");
int32_t* value = reinterpret_cast<int32_t*>(malloc(sizeof(int32_t)));
*value = 0b1100;
EXPECT_EQ(0b1100,
Call(test->entry(), reinterpret_cast<intx_t>(value), 0b1010));
EXPECT_EQ(0b1010, *value);
}
ASSEMBLER_TEST_GENERATE(AmoAddWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ amoaddw(A0, A1, Address(A0));
__ ret();
}
ASSEMBLER_TEST_RUN(AmoAddWord, test) {
EXPECT_DISASSEMBLY(
"00b5252f amoadd.w a0, a1, (a0)\n"
"00008067 ret\n");
int32_t* value = reinterpret_cast<int32_t*>(malloc(sizeof(int32_t)));
*value = 42;
EXPECT_EQ(42, Call(test->entry(), reinterpret_cast<intx_t>(value), 10));
EXPECT_EQ(52, *value);
}
ASSEMBLER_TEST_GENERATE(AmoXorWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ amoxorw(A0, A1, Address(A0));
__ ret();
}
ASSEMBLER_TEST_RUN(AmoXorWord, test) {
EXPECT_DISASSEMBLY(
"20b5252f amoxor.w a0, a1, (a0)\n"
"00008067 ret\n");
int32_t* value = reinterpret_cast<int32_t*>(malloc(sizeof(int32_t)));
*value = 0b1100;
EXPECT_EQ(0b1100,
Call(test->entry(), reinterpret_cast<intx_t>(value), 0b1010));
EXPECT_EQ(0b0110, *value);
}
ASSEMBLER_TEST_GENERATE(AmoAndWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ amoandw(A0, A1, Address(A0));
__ ret();
}
ASSEMBLER_TEST_RUN(AmoAndWord, test) {
EXPECT_DISASSEMBLY(
"60b5252f amoand.w a0, a1, (a0)\n"
"00008067 ret\n");
int32_t* value = reinterpret_cast<int32_t*>(malloc(sizeof(int32_t)));
*value = 0b1100;
EXPECT_EQ(0b1100,
Call(test->entry(), reinterpret_cast<intx_t>(value), 0b1010));
EXPECT_EQ(0b1000, *value);
}
ASSEMBLER_TEST_GENERATE(AmoOrWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ amoorw(A0, A1, Address(A0));
__ ret();
}
ASSEMBLER_TEST_RUN(AmoOrWord, test) {
EXPECT_DISASSEMBLY(
"40b5252f amoor.w a0, a1, (a0)\n"
"00008067 ret\n");
int32_t* value = reinterpret_cast<int32_t*>(malloc(sizeof(int32_t)));
*value = 0b1100;
EXPECT_EQ(0b1100,
Call(test->entry(), reinterpret_cast<intx_t>(value), 0b1010));
EXPECT_EQ(0b1110, *value);
}
ASSEMBLER_TEST_GENERATE(AmoMinWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ amominw(A0, A1, Address(A0));
__ ret();
}
ASSEMBLER_TEST_RUN(AmoMinWord, test) {
EXPECT_DISASSEMBLY(
"80b5252f amomin.w a0, a1, (a0)\n"
"00008067 ret\n");
int32_t* value = reinterpret_cast<int32_t*>(malloc(sizeof(int32_t)));
*value = -7;
EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -4));
EXPECT_EQ(-7, *value);
EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -7));
EXPECT_EQ(-7, *value);
EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -11));
EXPECT_EQ(-11, *value);
}
ASSEMBLER_TEST_GENERATE(AmoMaxWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ amomaxw(A0, A1, Address(A0));
__ ret();
}
ASSEMBLER_TEST_RUN(AmoMaxWord, test) {
EXPECT_DISASSEMBLY(
"a0b5252f amomax.w a0, a1, (a0)\n"
"00008067 ret\n");
int32_t* value = reinterpret_cast<int32_t*>(malloc(sizeof(int32_t)));
*value = -7;
EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -11));
EXPECT_EQ(-7, *value);
EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -7));
EXPECT_EQ(-7, *value);
EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -4));
EXPECT_EQ(-4, *value);
}
ASSEMBLER_TEST_GENERATE(AmoMinUnsignedWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ amominuw(A0, A1, Address(A0));
__ ret();
}
ASSEMBLER_TEST_RUN(AmoMinUnsignedWord, test) {
EXPECT_DISASSEMBLY(
"c0b5252f amominu.w a0, a1, (a0)\n"
"00008067 ret\n");
int32_t* value = reinterpret_cast<int32_t*>(malloc(sizeof(int32_t)));
*value = -7;
EXPECT_EQ(sign_extend(static_cast<uint32_t>(-7)),
Call(test->entry(), reinterpret_cast<intx_t>(value), -4));
EXPECT_EQ(-7, *value);
EXPECT_EQ(sign_extend(static_cast<uint32_t>(-7)),
Call(test->entry(), reinterpret_cast<intx_t>(value), -7));
EXPECT_EQ(-7, *value);
EXPECT_EQ(sign_extend(static_cast<uint32_t>(-7)),
Call(test->entry(), reinterpret_cast<intx_t>(value), -11));
EXPECT_EQ(-11, *value);
}
ASSEMBLER_TEST_GENERATE(AmoMaxUnsignedWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ amomaxuw(A0, A1, Address(A0));
__ ret();
}
ASSEMBLER_TEST_RUN(AmoMaxUnsignedWord, test) {
EXPECT_DISASSEMBLY(
"e0b5252f amomaxu.w a0, a1, (a0)\n"
"00008067 ret\n");
int32_t* value = reinterpret_cast<int32_t*>(malloc(sizeof(int32_t)));
*value = -7;
EXPECT_EQ(sign_extend(static_cast<uint32_t>(-7)),
Call(test->entry(), reinterpret_cast<intx_t>(value), -11));
EXPECT_EQ(-7, *value);
EXPECT_EQ(sign_extend(static_cast<uint32_t>(-7)),
Call(test->entry(), reinterpret_cast<intx_t>(value), -7));
EXPECT_EQ(-7, *value);
EXPECT_EQ(sign_extend(static_cast<uint32_t>(-7)),
Call(test->entry(), reinterpret_cast<intx_t>(value), -4));
EXPECT_EQ(-4, *value);
}
#if XLEN >= 64
ASSEMBLER_TEST_GENERATE(LoadReserveStoreConditionalDoubleWord_Success,
assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ lrd(T0, Address(A0));
__ addi(T0, T0, 1);
__ scd(A0, T0, Address(A0));
__ ret();
}
ASSEMBLER_TEST_RUN(LoadReserveStoreConditionalDoubleWord_Success, test) {
EXPECT_DISASSEMBLY(
"100532af lr.d t0, (a0)\n"
"00128293 addi t0, t0, 1\n"
"1855352f sc.d a0, t0, (a0)\n"
"00008067 ret\n");
int64_t* value = reinterpret_cast<int64_t*>(malloc(sizeof(int64_t)));
*value = 0b1100;
EXPECT_EQ(0, Call(test->entry(), reinterpret_cast<intx_t>(value)));
EXPECT_EQ(0b1101, *value);
}
ASSEMBLER_TEST_GENERATE(LoadReserveStoreConditionalDoubleWord_Failure,
assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ li(T0, 42);
__ scd(A0, T0, Address(A0));
__ ret();
}
ASSEMBLER_TEST_RUN(LoadReserveStoreConditionalDoubleWord_Failure, test) {
EXPECT_DISASSEMBLY(
"02a00293 li t0, 42\n"
"1855352f sc.d a0, t0, (a0)\n"
"00008067 ret\n");
int64_t* value = reinterpret_cast<int64_t*>(malloc(sizeof(int64_t)));
*value = 0b1100;
EXPECT_EQ(false, 0 == Call(test->entry(), reinterpret_cast<intx_t>(value)));
EXPECT_EQ(0b1100, *value);
}
ASSEMBLER_TEST_GENERATE(AmoSwapDoubleWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ amoswapd(A0, A1, Address(A0));
__ ret();
}
ASSEMBLER_TEST_RUN(AmoSwapDoubleWord, test) {
EXPECT_DISASSEMBLY(
"08b5352f amoswap.d a0, a1, (a0)\n"
"00008067 ret\n");
int64_t* value = reinterpret_cast<int64_t*>(malloc(sizeof(int64_t)));
*value = 0b1100;
EXPECT_EQ(0b1100,
Call(test->entry(), reinterpret_cast<intx_t>(value), 0b1010));
EXPECT_EQ(0b1010, *value);
}
ASSEMBLER_TEST_GENERATE(AmoAddDoubleWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ amoaddd(A0, A1, Address(A0));
__ ret();
}
ASSEMBLER_TEST_RUN(AmoAddDoubleWord, test) {
EXPECT_DISASSEMBLY(
"00b5352f amoadd.d a0, a1, (a0)\n"
"00008067 ret\n");
int64_t* value = reinterpret_cast<int64_t*>(malloc(sizeof(int64_t)));
*value = 42;
EXPECT_EQ(42, Call(test->entry(), reinterpret_cast<intx_t>(value), 10));
EXPECT_EQ(52, *value);
}
ASSEMBLER_TEST_GENERATE(AmoXorDoubleWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ amoxord(A0, A1, Address(A0));
__ ret();
}
ASSEMBLER_TEST_RUN(AmoXorDoubleWord, test) {
EXPECT_DISASSEMBLY(
"20b5352f amoxor.d a0, a1, (a0)\n"
"00008067 ret\n");
int64_t* value = reinterpret_cast<int64_t*>(malloc(sizeof(int64_t)));
*value = 0b1100;
EXPECT_EQ(0b1100,
Call(test->entry(), reinterpret_cast<intx_t>(value), 0b1010));
EXPECT_EQ(0b0110, *value);
}
ASSEMBLER_TEST_GENERATE(AmoAndDoubleWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ amoandd(A0, A1, Address(A0));
__ ret();
}
ASSEMBLER_TEST_RUN(AmoAndDoubleWord, test) {
EXPECT_DISASSEMBLY(
"60b5352f amoand.d a0, a1, (a0)\n"
"00008067 ret\n");
int64_t* value = reinterpret_cast<int64_t*>(malloc(sizeof(int64_t)));
*value = 0b1100;
EXPECT_EQ(0b1100,
Call(test->entry(), reinterpret_cast<intx_t>(value), 0b1010));
EXPECT_EQ(0b1000, *value);
}
ASSEMBLER_TEST_GENERATE(AmoOrDoubleWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ amoord(A0, A1, Address(A0));
__ ret();
}
ASSEMBLER_TEST_RUN(AmoOrDoubleWord, test) {
EXPECT_DISASSEMBLY(
"40b5352f amoor.d a0, a1, (a0)\n"
"00008067 ret\n");
int64_t* value = reinterpret_cast<int64_t*>(malloc(sizeof(int64_t)));
*value = 0b1100;
EXPECT_EQ(0b1100,
Call(test->entry(), reinterpret_cast<intx_t>(value), 0b1010));
EXPECT_EQ(0b1110, *value);
}
ASSEMBLER_TEST_GENERATE(AmoMinDoubleWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ amomind(A0, A1, Address(A0));
__ ret();
}
ASSEMBLER_TEST_RUN(AmoMinDoubleWord, test) {
EXPECT_DISASSEMBLY(
"80b5352f amomin.d a0, a1, (a0)\n"
"00008067 ret\n");
int64_t* value = reinterpret_cast<int64_t*>(malloc(sizeof(int64_t)));
*value = -7;
EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -4));
EXPECT_EQ(-7, *value);
EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -7));
EXPECT_EQ(-7, *value);
EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -11));
EXPECT_EQ(-11, *value);
}
ASSEMBLER_TEST_GENERATE(AmoMaxDoubleWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ amomaxd(A0, A1, Address(A0));
__ ret();
}
ASSEMBLER_TEST_RUN(AmoMaxDoubleWord, test) {
EXPECT_DISASSEMBLY(
"a0b5352f amomax.d a0, a1, (a0)\n"
"00008067 ret\n");
int64_t* value = reinterpret_cast<int64_t*>(malloc(sizeof(int64_t)));
*value = -7;
EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -11));
EXPECT_EQ(-7, *value);
EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -7));
EXPECT_EQ(-7, *value);
EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -4));
EXPECT_EQ(-4, *value);
}
ASSEMBLER_TEST_GENERATE(AmoMinUnsignedDoubleWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ amominud(A0, A1, Address(A0));
__ ret();
}
ASSEMBLER_TEST_RUN(AmoMinUnsignedDoubleWord, test) {
EXPECT_DISASSEMBLY(
"c0b5352f amominu.d a0, a1, (a0)\n"
"00008067 ret\n");
int64_t* value = reinterpret_cast<int64_t*>(malloc(sizeof(int64_t)));
*value = -7;
EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -4));
EXPECT_EQ(-7, *value);
EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -7));
EXPECT_EQ(-7, *value);
EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -11));
EXPECT_EQ(-11, *value);
}
ASSEMBLER_TEST_GENERATE(AmoMaxUnsignedDoubleWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ amomaxud(A0, A1, Address(A0));
__ ret();
}
ASSEMBLER_TEST_RUN(AmoMaxUnsignedDoubleWord, test) {
EXPECT_DISASSEMBLY(
"e0b5352f amomaxu.d a0, a1, (a0)\n"
"00008067 ret\n");
int64_t* value = reinterpret_cast<int64_t*>(malloc(sizeof(int64_t)));
*value = -7;
EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -11));
EXPECT_EQ(-7, *value);
EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -7));
EXPECT_EQ(-7, *value);
EXPECT_EQ(-7, Call(test->entry(), reinterpret_cast<intx_t>(value), -4));
EXPECT_EQ(-4, *value);
}
#endif
ASSEMBLER_TEST_GENERATE(LoadSingleFloat, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ flw(FA0, Address(A0, 1 * sizeof(float)));
__ ret();
}
ASSEMBLER_TEST_RUN(LoadSingleFloat, test) {
EXPECT_DISASSEMBLY(
"00452507 flw fa0, 4(a0)\n"
"00008067 ret\n");
float* data = reinterpret_cast<float*>(malloc(3 * sizeof(float)));
data[0] = 1.7f;
data[1] = 2.8f;
data[2] = 3.9f;
EXPECT_EQ(data[1], CallF(test->entry(), reinterpret_cast<intx_t>(data)));
}
ASSEMBLER_TEST_GENERATE(StoreSingleFloat, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fsw(FA0, Address(A0, 1 * sizeof(float)));
__ ret();
}
ASSEMBLER_TEST_RUN(StoreSingleFloat, test) {
EXPECT_DISASSEMBLY(
"00a52227 fsw fa0, 4(a0)\n"
"00008067 ret\n");
float* data = reinterpret_cast<float*>(malloc(3 * sizeof(float)));
data[0] = 1.7f;
data[1] = 2.8f;
data[2] = 3.9f;
CallF(test->entry(), reinterpret_cast<intx_t>(data), 4.2f);
EXPECT_EQ(4.2f, data[1]);
}
ASSEMBLER_TEST_GENERATE(SingleMultiplyAdd, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fmadds(FA0, FA0, FA1, FA2);
__ ret();
}
ASSEMBLER_TEST_RUN(SingleMultiplyAdd, test) {
EXPECT_DISASSEMBLY(
"60b50543 fmadd.s fa0, fa0, fa1, fa2\n"
"00008067 ret\n");
EXPECT_EQ(22.0, CallF(test->entry(), 3.0, 5.0, 7.0));
EXPECT_EQ(-8.0, CallF(test->entry(), -3.0, 5.0, 7.0));
EXPECT_EQ(-8.0, CallF(test->entry(), 3.0, -5.0, 7.0));
EXPECT_EQ(8.0, CallF(test->entry(), 3.0, 5.0, -7.0));
EXPECT_EQ(26.0, CallF(test->entry(), 7.0, 3.0, 5.0));
EXPECT_EQ(-16.0, CallF(test->entry(), -7.0, 3.0, 5.0));
EXPECT_EQ(-16.0, CallF(test->entry(), 7.0, -3.0, 5.0));
EXPECT_EQ(16.0, CallF(test->entry(), 7.0, 3.0, -5.0));
}
ASSEMBLER_TEST_GENERATE(SingleMultiplySubtract, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fmsubs(FA0, FA0, FA1, FA2);
__ ret();
}
ASSEMBLER_TEST_RUN(SingleMultiplySubtract, test) {
EXPECT_DISASSEMBLY(
"60b50547 fmsub.s fa0, fa0, fa1, fa2\n"
"00008067 ret\n");
EXPECT_EQ(8.0, CallF(test->entry(), 3.0, 5.0, 7.0));
EXPECT_EQ(-22.0, CallF(test->entry(), -3.0, 5.0, 7.0));
EXPECT_EQ(-22.0, CallF(test->entry(), 3.0, -5.0, 7.0));
EXPECT_EQ(22.0, CallF(test->entry(), 3.0, 5.0, -7.0));
EXPECT_EQ(16.0, CallF(test->entry(), 7.0, 3.0, 5.0));
EXPECT_EQ(-26.0, CallF(test->entry(), -7.0, 3.0, 5.0));
EXPECT_EQ(-26.0, CallF(test->entry(), 7.0, -3.0, 5.0));
EXPECT_EQ(26.0, CallF(test->entry(), 7.0, 3.0, -5.0));
}
ASSEMBLER_TEST_GENERATE(SingleNegateMultiplySubtract, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fnmsubs(FA0, FA0, FA1, FA2);
__ ret();
}
ASSEMBLER_TEST_RUN(SingleNegateMultiplySubtract, test) {
EXPECT_DISASSEMBLY(
"60b5054b fnmsub.s fa0, fa0, fa1, fa2\n"
"00008067 ret\n");
EXPECT_EQ(-8.0, CallF(test->entry(), 3.0, 5.0, 7.0));
EXPECT_EQ(22.0, CallF(test->entry(), -3.0, 5.0, 7.0));
EXPECT_EQ(22.0, CallF(test->entry(), 3.0, -5.0, 7.0));
EXPECT_EQ(-22.0, CallF(test->entry(), 3.0, 5.0, -7.0));
EXPECT_EQ(-16.0, CallF(test->entry(), 7.0, 3.0, 5.0));
EXPECT_EQ(26.0, CallF(test->entry(), -7.0, 3.0, 5.0));
EXPECT_EQ(26.0, CallF(test->entry(), 7.0, -3.0, 5.0));
EXPECT_EQ(-26.0, CallF(test->entry(), 7.0, 3.0, -5.0));
}
ASSEMBLER_TEST_GENERATE(SingleNegateMultiplyAdd, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fnmadds(FA0, FA0, FA1, FA2);
__ ret();
}
ASSEMBLER_TEST_RUN(SingleNegateMultiplyAdd, test) {
EXPECT_DISASSEMBLY(
"60b5054f fnmadd.s fa0, fa0, fa1, fa2\n"
"00008067 ret\n");
EXPECT_EQ(-22.0, CallF(test->entry(), 3.0, 5.0, 7.0));
EXPECT_EQ(8.0, CallF(test->entry(), -3.0, 5.0, 7.0));
EXPECT_EQ(8.0, CallF(test->entry(), 3.0, -5.0, 7.0));
EXPECT_EQ(-8.0, CallF(test->entry(), 3.0, 5.0, -7.0));
EXPECT_EQ(-26.0, CallF(test->entry(), 7.0, 3.0, 5.0));
EXPECT_EQ(16.0, CallF(test->entry(), -7.0, 3.0, 5.0));
EXPECT_EQ(16.0, CallF(test->entry(), 7.0, -3.0, 5.0));
EXPECT_EQ(-16.0, CallF(test->entry(), 7.0, 3.0, -5.0));
}
ASSEMBLER_TEST_GENERATE(SingleAdd, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fadds(FA0, FA0, FA1);
__ ret();
}
ASSEMBLER_TEST_RUN(SingleAdd, test) {
EXPECT_DISASSEMBLY(
"00b50553 fadd.s fa0, fa0, fa1\n"
"00008067 ret\n");
EXPECT_EQ(8.0f, CallF(test->entry(), 3.0f, 5.0f));
EXPECT_EQ(2.0f, CallF(test->entry(), -3.0f, 5.0f));
EXPECT_EQ(-2.0f, CallF(test->entry(), 3.0f, -5.0f));
EXPECT_EQ(-8.0f, CallF(test->entry(), -3.0f, -5.0f));
EXPECT_EQ(10.0f, CallF(test->entry(), 7.0f, 3.0f));
EXPECT_EQ(-4.0f, CallF(test->entry(), -7.0f, 3.0f));
EXPECT_EQ(4.0f, CallF(test->entry(), 7.0f, -3.0f));
EXPECT_EQ(-10.0f, CallF(test->entry(), -7.0f, -3.0f));
}
ASSEMBLER_TEST_GENERATE(SingleSubtract, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fsubs(FA0, FA0, FA1);
__ ret();
}
ASSEMBLER_TEST_RUN(SingleSubtract, test) {
EXPECT_DISASSEMBLY(
"08b50553 fsub.s fa0, fa0, fa1\n"
"00008067 ret\n");
EXPECT_EQ(-2.0f, CallF(test->entry(), 3.0f, 5.0f));
EXPECT_EQ(-8.0f, CallF(test->entry(), -3.0f, 5.0f));
EXPECT_EQ(8.0f, CallF(test->entry(), 3.0f, -5.0f));
EXPECT_EQ(2.0f, CallF(test->entry(), -3.0f, -5.0f));
EXPECT_EQ(4.0f, CallF(test->entry(), 7.0f, 3.0f));
EXPECT_EQ(-10.0f, CallF(test->entry(), -7.0f, 3.0f));
EXPECT_EQ(10.0f, CallF(test->entry(), 7.0f, -3.0f));
EXPECT_EQ(-4.0f, CallF(test->entry(), -7.0f, -3.0f));
}
ASSEMBLER_TEST_GENERATE(SingleMultiply, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fmuls(FA0, FA0, FA1);
__ ret();
}
ASSEMBLER_TEST_RUN(SingleMultiply, test) {
EXPECT_DISASSEMBLY(
"10b50553 fmul.s fa0, fa0, fa1\n"
"00008067 ret\n");
EXPECT_EQ(15.0f, CallF(test->entry(), 3.0f, 5.0f));
EXPECT_EQ(-15.0f, CallF(test->entry(), -3.0f, 5.0f));
EXPECT_EQ(-15.0f, CallF(test->entry(), 3.0f, -5.0f));
EXPECT_EQ(15.0f, CallF(test->entry(), -3.0f, -5.0f));
EXPECT_EQ(21.0f, CallF(test->entry(), 7.0f, 3.0f));
EXPECT_EQ(-21.0f, CallF(test->entry(), -7.0f, 3.0f));
EXPECT_EQ(-21.0f, CallF(test->entry(), 7.0f, -3.0f));
EXPECT_EQ(21.0f, CallF(test->entry(), -7.0f, -3.0f));
}
ASSEMBLER_TEST_GENERATE(SingleDivide, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fdivs(FA0, FA0, FA1);
__ ret();
}
ASSEMBLER_TEST_RUN(SingleDivide, test) {
EXPECT_DISASSEMBLY(
"18b50553 fdiv.s fa0, fa0, fa1\n"
"00008067 ret\n");
EXPECT_EQ(2.0f, CallF(test->entry(), 10.0f, 5.0f));
EXPECT_EQ(-2.0f, CallF(test->entry(), -10.0f, 5.0f));
EXPECT_EQ(-2.0f, CallF(test->entry(), 10.0f, -5.0f));
EXPECT_EQ(2.0f, CallF(test->entry(), -10.0f, -5.0f));
}
ASSEMBLER_TEST_GENERATE(SingleSquareRoot, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fsqrts(FA0, FA0);
__ ret();
}
ASSEMBLER_TEST_RUN(SingleSquareRoot, test) {
EXPECT_DISASSEMBLY(
"58050553 fsqrt.s fa0, fa0\n"
"00008067 ret\n");
EXPECT_EQ(0.0f, CallF(test->entry(), 0.0f));
EXPECT_EQ(1.0f, CallF(test->entry(), 1.0f));
EXPECT_EQ(2.0f, CallF(test->entry(), 4.0f));
EXPECT_EQ(3.0f, CallF(test->entry(), 9.0f));
}
ASSEMBLER_TEST_GENERATE(SingleSignInject, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fsgnjs(FA0, FA0, FA1);
__ ret();
}
ASSEMBLER_TEST_RUN(SingleSignInject, test) {
EXPECT_DISASSEMBLY(
"20b50553 fsgnj.s fa0, fa0, fa1\n"
"00008067 ret\n");
EXPECT_EQ(3.0f, CallF(test->entry(), 3.0f, 5.0f));
EXPECT_EQ(3.0f, CallF(test->entry(), -3.0f, 5.0f));
EXPECT_EQ(-3.0f, CallF(test->entry(), 3.0f, -5.0f));
EXPECT_EQ(-3.0f, CallF(test->entry(), -3.0f, -5.0f));
}
ASSEMBLER_TEST_GENERATE(SingleNegatedSignInject, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fsgnjns(FA0, FA0, FA1);
__ ret();
}
ASSEMBLER_TEST_RUN(SingleNegatedSignInject, test) {
EXPECT_DISASSEMBLY(
"20b51553 fsgnjn.s fa0, fa0, fa1\n"
"00008067 ret\n");
EXPECT_EQ(-3.0f, CallF(test->entry(), 3.0f, 5.0f));
EXPECT_EQ(-3.0f, CallF(test->entry(), -3.0f, 5.0f));
EXPECT_EQ(3.0f, CallF(test->entry(), 3.0f, -5.0f));
EXPECT_EQ(3.0f, CallF(test->entry(), -3.0f, -5.0f));
}
ASSEMBLER_TEST_GENERATE(SingleXorSignInject, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fsgnjxs(FA0, FA0, FA1);
__ ret();
}
ASSEMBLER_TEST_RUN(SingleXorSignInject, test) {
EXPECT_DISASSEMBLY(
"20b52553 fsgnjx.s fa0, fa0, fa1\n"
"00008067 ret\n");
EXPECT_EQ(3.0f, CallF(test->entry(), 3.0f, 5.0f));
EXPECT_EQ(-3.0f, CallF(test->entry(), -3.0f, 5.0f));
EXPECT_EQ(-3.0f, CallF(test->entry(), 3.0f, -5.0f));
EXPECT_EQ(3.0f, CallF(test->entry(), -3.0f, -5.0f));
}
ASSEMBLER_TEST_GENERATE(SingleMin, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fmins(FA0, FA0, FA1);
__ ret();
}
ASSEMBLER_TEST_RUN(SingleMin, test) {
EXPECT_DISASSEMBLY(
"28b50553 fmin.s fa0, fa0, fa1\n"
"00008067 ret\n");
EXPECT_EQ(1.0f, CallF(test->entry(), 3.0f, 1.0f));
EXPECT_EQ(3.0f, CallF(test->entry(), 3.0f, 3.0f));
EXPECT_EQ(3.0f, CallF(test->entry(), 3.0f, 5.0f));
EXPECT_EQ(-1.0f, CallF(test->entry(), 3.0f, -1.0f));
EXPECT_EQ(-3.0f, CallF(test->entry(), 3.0f, -3.0f));
EXPECT_EQ(-5.0f, CallF(test->entry(), 3.0f, -5.0f));
EXPECT_EQ(-3.0f, CallF(test->entry(), -3.0f, 1.0f));
EXPECT_EQ(-3.0f, CallF(test->entry(), -3.0f, 3.0f));
EXPECT_EQ(-3.0f, CallF(test->entry(), -3.0f, 5.0f));
EXPECT_EQ(-3.0f, CallF(test->entry(), -3.0f, -1.0f));
EXPECT_EQ(-3.0f, CallF(test->entry(), -3.0f, -3.0f));
EXPECT_EQ(-5.0f, CallF(test->entry(), -3.0f, -5.0f));
float qNAN = std::numeric_limits<float>::quiet_NaN();
EXPECT_EQ(3.0f, CallF(test->entry(), 3.0f, qNAN));
EXPECT_EQ(3.0f, CallF(test->entry(), qNAN, 3.0f));
EXPECT_EQ(-3.0f, CallF(test->entry(), -3.0f, qNAN));
EXPECT_EQ(-3.0f, CallF(test->entry(), qNAN, -3.0f));
}
ASSEMBLER_TEST_GENERATE(SingleMax, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fmaxs(FA0, FA0, FA1);
__ ret();
}
ASSEMBLER_TEST_RUN(SingleMax, test) {
EXPECT_DISASSEMBLY(
"28b51553 fmax.s fa0, fa0, fa1\n"
"00008067 ret\n");
EXPECT_EQ(3.0f, CallF(test->entry(), 3.0f, 1.0f));
EXPECT_EQ(3.0f, CallF(test->entry(), 3.0f, 3.0f));
EXPECT_EQ(5.0f, CallF(test->entry(), 3.0f, 5.0f));
EXPECT_EQ(3.0f, CallF(test->entry(), 3.0f, -1.0f));
EXPECT_EQ(3.0f, CallF(test->entry(), 3.0f, -3.0f));
EXPECT_EQ(3.0f, CallF(test->entry(), 3.0f, -5.0f));
EXPECT_EQ(1.0f, CallF(test->entry(), -3.0f, 1.0f));
EXPECT_EQ(3.0f, CallF(test->entry(), -3.0f, 3.0f));
EXPECT_EQ(5.0f, CallF(test->entry(), -3.0f, 5.0f));
EXPECT_EQ(-1.0f, CallF(test->entry(), -3.0f, -1.0f));
EXPECT_EQ(-3.0f, CallF(test->entry(), -3.0f, -3.0f));
EXPECT_EQ(-3.0f, CallF(test->entry(), -3.0f, -5.0f));
float qNAN = std::numeric_limits<float>::quiet_NaN();
EXPECT_EQ(3.0f, CallF(test->entry(), 3.0f, qNAN));
EXPECT_EQ(3.0f, CallF(test->entry(), qNAN, 3.0f));
EXPECT_EQ(-3.0f, CallF(test->entry(), -3.0f, qNAN));
EXPECT_EQ(-3.0f, CallF(test->entry(), qNAN, -3.0f));
}
ASSEMBLER_TEST_GENERATE(SingleEqual, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ feqs(A0, FA0, FA1);
__ ret();
}
ASSEMBLER_TEST_RUN(SingleEqual, test) {
EXPECT_DISASSEMBLY(
"a0b52553 feq.s a0, fa0, fa1\n"
"00008067 ret\n");
EXPECT_EQ(0, CallI(test->entry(), 3.0f, 1.0f));
EXPECT_EQ(1, CallI(test->entry(), 3.0f, 3.0f));
EXPECT_EQ(0, CallI(test->entry(), 3.0f, 5.0f));
EXPECT_EQ(0, CallI(test->entry(), 3.0f, -1.0f));
EXPECT_EQ(0, CallI(test->entry(), 3.0f, -3.0f));
EXPECT_EQ(0, CallI(test->entry(), 3.0f, -5.0f));
EXPECT_EQ(0, CallI(test->entry(), -3.0f, 1.0f));
EXPECT_EQ(0, CallI(test->entry(), -3.0f, 3.0f));
EXPECT_EQ(0, CallI(test->entry(), -3.0f, 5.0f));
EXPECT_EQ(0, CallI(test->entry(), -3.0f, -1.0f));
EXPECT_EQ(1, CallI(test->entry(), -3.0f, -3.0f));
EXPECT_EQ(0, CallI(test->entry(), -3.0f, -5.0f));
float qNAN = std::numeric_limits<float>::quiet_NaN();
EXPECT_EQ(0, CallI(test->entry(), 3.0f, qNAN));
EXPECT_EQ(0, CallI(test->entry(), qNAN, 3.0f));
EXPECT_EQ(0, CallI(test->entry(), -3.0f, qNAN));
EXPECT_EQ(0, CallI(test->entry(), qNAN, -3.0f));
}
ASSEMBLER_TEST_GENERATE(SingleLessThan, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ flts(A0, FA0, FA1);
__ ret();
}
ASSEMBLER_TEST_RUN(SingleLessThan, test) {
EXPECT_DISASSEMBLY(
"a0b51553 flt.s a0, fa0, fa1\n"
"00008067 ret\n");
EXPECT_EQ(0, CallI(test->entry(), 3.0f, 1.0f));
EXPECT_EQ(0, CallI(test->entry(), 3.0f, 3.0f));
EXPECT_EQ(1, CallI(test->entry(), 3.0f, 5.0f));
EXPECT_EQ(0, CallI(test->entry(), 3.0f, -1.0f));
EXPECT_EQ(0, CallI(test->entry(), 3.0f, -3.0f));
EXPECT_EQ(0, CallI(test->entry(), 3.0f, -5.0f));
EXPECT_EQ(1, CallI(test->entry(), -3.0f, 1.0f));
EXPECT_EQ(1, CallI(test->entry(), -3.0f, 3.0f));
EXPECT_EQ(1, CallI(test->entry(), -3.0f, 5.0f));
EXPECT_EQ(1, CallI(test->entry(), -3.0f, -1.0f));
EXPECT_EQ(0, CallI(test->entry(), -3.0f, -3.0f));
EXPECT_EQ(0, CallI(test->entry(), -3.0f, -5.0f));
float qNAN = std::numeric_limits<float>::quiet_NaN();
EXPECT_EQ(0, CallI(test->entry(), 3.0f, qNAN));
EXPECT_EQ(0, CallI(test->entry(), qNAN, 3.0f));
EXPECT_EQ(0, CallI(test->entry(), -3.0f, qNAN));
EXPECT_EQ(0, CallI(test->entry(), qNAN, -3.0f));
}
ASSEMBLER_TEST_GENERATE(SingleLessOrEqual, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fles(A0, FA0, FA1);
__ ret();
}
ASSEMBLER_TEST_RUN(SingleLessOrEqual, test) {
EXPECT_DISASSEMBLY(
"a0b50553 fle.s a0, fa0, fa1\n"
"00008067 ret\n");
EXPECT_EQ(0, CallI(test->entry(), 3.0f, 1.0f));
EXPECT_EQ(1, CallI(test->entry(), 3.0f, 3.0f));
EXPECT_EQ(1, CallI(test->entry(), 3.0f, 5.0f));
EXPECT_EQ(0, CallI(test->entry(), 3.0f, -1.0f));
EXPECT_EQ(0, CallI(test->entry(), 3.0f, -3.0f));
EXPECT_EQ(0, CallI(test->entry(), 3.0f, -5.0f));
EXPECT_EQ(1, CallI(test->entry(), -3.0f, 1.0f));
EXPECT_EQ(1, CallI(test->entry(), -3.0f, 3.0f));
EXPECT_EQ(1, CallI(test->entry(), -3.0f, 5.0f));
EXPECT_EQ(1, CallI(test->entry(), -3.0f, -1.0f));
EXPECT_EQ(1, CallI(test->entry(), -3.0f, -3.0f));
EXPECT_EQ(0, CallI(test->entry(), -3.0f, -5.0f));
float qNAN = std::numeric_limits<float>::quiet_NaN();
EXPECT_EQ(0, CallI(test->entry(), 3.0f, qNAN));
EXPECT_EQ(0, CallI(test->entry(), qNAN, 3.0f));
EXPECT_EQ(0, CallI(test->entry(), -3.0f, qNAN));
EXPECT_EQ(0, CallI(test->entry(), qNAN, -3.0f));
}
ASSEMBLER_TEST_GENERATE(SingleClassify, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fclasss(A0, FA0);
__ ret();
}
ASSEMBLER_TEST_RUN(SingleClassify, test) {
EXPECT_DISASSEMBLY(
"e0051553 fclass.s a0, fa0\n"
"00008067 ret\n");
// Neg infinity
EXPECT_EQ(1 << 0,
CallI(test->entry(), -std::numeric_limits<float>::infinity()));
// Neg normal
EXPECT_EQ(1 << 1, CallI(test->entry(), -1.0f));
// Neg subnormal
EXPECT_EQ(1 << 2,
CallI(test->entry(), -std::numeric_limits<float>::min() / 2.0f));
// Neg zero
EXPECT_EQ(1 << 3, CallI(test->entry(), -0.0f));
// Pos zero
EXPECT_EQ(1 << 4, CallI(test->entry(), 0.0f));
// Pos subnormal
EXPECT_EQ(1 << 5,
CallI(test->entry(), std::numeric_limits<float>::min() / 2.0f));
// Pos normal
EXPECT_EQ(1 << 6, CallI(test->entry(), 1.0f));
// Pos infinity
EXPECT_EQ(1 << 7,
CallI(test->entry(), std::numeric_limits<float>::infinity()));
// Signaling NaN
EXPECT_EQ(1 << 8,
CallI(test->entry(), std::numeric_limits<float>::signaling_NaN()));
// Queit NaN
EXPECT_EQ(1 << 9,
CallI(test->entry(), std::numeric_limits<float>::quiet_NaN()));
}
ASSEMBLER_TEST_GENERATE(ConvertSingleToWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fcvtws(A0, FA0);
__ ret();
}
ASSEMBLER_TEST_RUN(ConvertSingleToWord, test) {
EXPECT_DISASSEMBLY(
"c0050553 fcvt.w.s a0, fa0\n"
"00008067 ret\n");
EXPECT_EQ(-42, CallI(test->entry(), static_cast<float>(-42)));
EXPECT_EQ(0, CallI(test->entry(), static_cast<float>(0)));
EXPECT_EQ(42, CallI(test->entry(), static_cast<float>(42)));
EXPECT_EQ(sign_extend(kMinInt32),
CallI(test->entry(), static_cast<float>(kMinInt32)));
EXPECT_EQ(sign_extend(kMaxInt32),
CallI(test->entry(), static_cast<float>(kMaxInt32)));
EXPECT_EQ(sign_extend(kMaxInt32),
CallI(test->entry(), static_cast<float>(kMaxUint32)));
EXPECT_EQ(sign_extend(kMinInt32),
CallI(test->entry(), static_cast<float>(kMinInt64)));
EXPECT_EQ(sign_extend(kMaxInt32),
CallI(test->entry(), static_cast<float>(kMaxInt64)));
EXPECT_EQ(sign_extend(kMaxInt32),
CallI(test->entry(), static_cast<float>(kMaxUint64)));
EXPECT_EQ(sign_extend(kMinInt32),
CallI(test->entry(), -std::numeric_limits<float>::infinity()));
EXPECT_EQ(sign_extend(kMaxInt32),
CallI(test->entry(), std::numeric_limits<float>::infinity()));
EXPECT_EQ(sign_extend(kMaxInt32),
CallI(test->entry(), std::numeric_limits<float>::signaling_NaN()));
}
ASSEMBLER_TEST_GENERATE(ConvertSingleToWord_RNE, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fcvtws(A0, FA0, RNE);
__ ret();
}
ASSEMBLER_TEST_RUN(ConvertSingleToWord_RNE, test) {
EXPECT_DISASSEMBLY(
"c0050553 fcvt.w.s a0, fa0\n"
"00008067 ret\n");
EXPECT_EQ(-44, CallI(test->entry(), -43.6f));
EXPECT_EQ(-44, CallI(test->entry(), -43.5f));
EXPECT_EQ(-43, CallI(test->entry(), -43.4f));
EXPECT_EQ(-43, CallI(test->entry(), -43.0f));
EXPECT_EQ(-43, CallI(test->entry(), -42.6f));
EXPECT_EQ(-42, CallI(test->entry(), -42.5f));
EXPECT_EQ(-42, CallI(test->entry(), -42.4f));
EXPECT_EQ(-42, CallI(test->entry(), -42.0f));
EXPECT_EQ(0, CallI(test->entry(), -0.0f));
EXPECT_EQ(0, CallI(test->entry(), +0.0f));
EXPECT_EQ(42, CallI(test->entry(), 42.0f));
EXPECT_EQ(42, CallI(test->entry(), 42.4f));
EXPECT_EQ(42, CallI(test->entry(), 42.5f));
EXPECT_EQ(43, CallI(test->entry(), 42.6f));
EXPECT_EQ(43, CallI(test->entry(), 43.0f));
EXPECT_EQ(43, CallI(test->entry(), 43.4f));
EXPECT_EQ(44, CallI(test->entry(), 43.5f));
EXPECT_EQ(44, CallI(test->entry(), 43.6f));
}
ASSEMBLER_TEST_GENERATE(ConvertSingleToWord_RTZ, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fcvtws(A0, FA0, RTZ);
__ ret();
}
ASSEMBLER_TEST_RUN(ConvertSingleToWord_RTZ, test) {
EXPECT_DISASSEMBLY(
"c0051553 fcvt.w.s a0, fa0, rtz\n"
"00008067 ret\n");
EXPECT_EQ(-43, CallI(test->entry(), -43.6f));
EXPECT_EQ(-43, CallI(test->entry(), -43.5f));
EXPECT_EQ(-43, CallI(test->entry(), -43.4f));
EXPECT_EQ(-43, CallI(test->entry(), -43.0f));
EXPECT_EQ(-42, CallI(test->entry(), -42.6f));
EXPECT_EQ(-42, CallI(test->entry(), -42.5f));
EXPECT_EQ(-42, CallI(test->entry(), -42.4f));
EXPECT_EQ(-42, CallI(test->entry(), -42.0f));
EXPECT_EQ(0, CallI(test->entry(), -0.0f));
EXPECT_EQ(0, CallI(test->entry(), +0.0f));
EXPECT_EQ(42, CallI(test->entry(), 42.0f));
EXPECT_EQ(42, CallI(test->entry(), 42.4f));
EXPECT_EQ(42, CallI(test->entry(), 42.5f));
EXPECT_EQ(42, CallI(test->entry(), 42.6f));
EXPECT_EQ(43, CallI(test->entry(), 43.0f));
EXPECT_EQ(43, CallI(test->entry(), 43.4f));
EXPECT_EQ(43, CallI(test->entry(), 43.5f));
EXPECT_EQ(43, CallI(test->entry(), 43.6f));
}
ASSEMBLER_TEST_GENERATE(ConvertSingleToWord_RDN, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fcvtws(A0, FA0, RDN);
__ ret();
}
ASSEMBLER_TEST_RUN(ConvertSingleToWord_RDN, test) {
EXPECT_DISASSEMBLY(
"c0052553 fcvt.w.s a0, fa0, rdn\n"
"00008067 ret\n");
EXPECT_EQ(-44, CallI(test->entry(), -43.6f));
EXPECT_EQ(-44, CallI(test->entry(), -43.5f));
EXPECT_EQ(-44, CallI(test->entry(), -43.4f));
EXPECT_EQ(-43, CallI(test->entry(), -43.0f));
EXPECT_EQ(-43, CallI(test->entry(), -42.6f));
EXPECT_EQ(-43, CallI(test->entry(), -42.5f));
EXPECT_EQ(-43, CallI(test->entry(), -42.4f));
EXPECT_EQ(-42, CallI(test->entry(), -42.0f));
EXPECT_EQ(0, CallI(test->entry(), -0.0f));
EXPECT_EQ(0, CallI(test->entry(), +0.0f));
EXPECT_EQ(42, CallI(test->entry(), 42.0f));
EXPECT_EQ(42, CallI(test->entry(), 42.4f));
EXPECT_EQ(42, CallI(test->entry(), 42.5f));
EXPECT_EQ(42, CallI(test->entry(), 42.6f));
EXPECT_EQ(43, CallI(test->entry(), 43.0f));
EXPECT_EQ(43, CallI(test->entry(), 43.4f));
EXPECT_EQ(43, CallI(test->entry(), 43.5f));
EXPECT_EQ(43, CallI(test->entry(), 43.6f));
}
ASSEMBLER_TEST_GENERATE(ConvertSingleToWord_RUP, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fcvtws(A0, FA0, RUP);
__ ret();
}
ASSEMBLER_TEST_RUN(ConvertSingleToWord_RUP, test) {
EXPECT_DISASSEMBLY(
"c0053553 fcvt.w.s a0, fa0, rup\n"
"00008067 ret\n");
EXPECT_EQ(-43, CallI(test->entry(), -43.6f));
EXPECT_EQ(-43, CallI(test->entry(), -43.5f));
EXPECT_EQ(-43, CallI(test->entry(), -43.4f));
EXPECT_EQ(-43, CallI(test->entry(), -43.0f));
EXPECT_EQ(-42, CallI(test->entry(), -42.6f));
EXPECT_EQ(-42, CallI(test->entry(), -42.5f));
EXPECT_EQ(-42, CallI(test->entry(), -42.4f));
EXPECT_EQ(-42, CallI(test->entry(), -42.0f));
EXPECT_EQ(0, CallI(test->entry(), -0.0f));
EXPECT_EQ(0, CallI(test->entry(), +0.0f));
EXPECT_EQ(42, CallI(test->entry(), 42.0f));
EXPECT_EQ(43, CallI(test->entry(), 42.4f));
EXPECT_EQ(43, CallI(test->entry(), 42.5f));
EXPECT_EQ(43, CallI(test->entry(), 42.6f));
EXPECT_EQ(43, CallI(test->entry(), 43.0f));
EXPECT_EQ(44, CallI(test->entry(), 43.5f));
EXPECT_EQ(44, CallI(test->entry(), 43.5f));
EXPECT_EQ(44, CallI(test->entry(), 43.6f));
}
ASSEMBLER_TEST_GENERATE(ConvertSingleToWord_RMM, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fcvtws(A0, FA0, RMM);
__ ret();
}
ASSEMBLER_TEST_RUN(ConvertSingleToWord_RMM, test) {
EXPECT_DISASSEMBLY(
"c0054553 fcvt.w.s a0, fa0, rmm\n"
"00008067 ret\n");
EXPECT_EQ(-44, CallI(test->entry(), -43.6f));
EXPECT_EQ(-44, CallI(test->entry(), -43.5f));
EXPECT_EQ(-43, CallI(test->entry(), -43.4f));
EXPECT_EQ(-43, CallI(test->entry(), -43.0f));
EXPECT_EQ(-43, CallI(test->entry(), -42.6f));
EXPECT_EQ(-43, CallI(test->entry(), -42.5f));
EXPECT_EQ(-42, CallI(test->entry(), -42.4f));
EXPECT_EQ(-42, CallI(test->entry(), -42.0f));
EXPECT_EQ(0, CallI(test->entry(), -0.0f));
EXPECT_EQ(0, CallI(test->entry(), +0.0f));
EXPECT_EQ(42, CallI(test->entry(), 42.0f));
EXPECT_EQ(42, CallI(test->entry(), 42.4f));
EXPECT_EQ(43, CallI(test->entry(), 42.5f));
EXPECT_EQ(43, CallI(test->entry(), 42.6f));
EXPECT_EQ(43, CallI(test->entry(), 43.0f));
EXPECT_EQ(43, CallI(test->entry(), 43.4f));
EXPECT_EQ(44, CallI(test->entry(), 43.5f));
EXPECT_EQ(44, CallI(test->entry(), 43.6f));
}
ASSEMBLER_TEST_GENERATE(ConvertSingleToUnsignedWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fcvtwus(A0, FA0);
__ ret();
}
ASSEMBLER_TEST_RUN(ConvertSingleToUnsignedWord, test) {
EXPECT_DISASSEMBLY(
"c0150553 fcvt.wu.s a0, fa0\n"
"00008067 ret\n");
EXPECT_EQ(0, CallI(test->entry(), static_cast<float>(-42)));
EXPECT_EQ(0, CallI(test->entry(), static_cast<float>(0)));
EXPECT_EQ(42, CallI(test->entry(), static_cast<float>(42)));
EXPECT_EQ(sign_extend(0),
CallI(test->entry(), static_cast<float>(kMinInt32)));
// float loss of precision
EXPECT_EQ(-2147483648, CallI(test->entry(), static_cast<float>(kMaxInt32)));
EXPECT_EQ(sign_extend(kMaxUint32),
CallI(test->entry(), static_cast<float>(kMaxUint32)));
EXPECT_EQ(sign_extend(0),
CallI(test->entry(), static_cast<float>(kMinInt64)));
EXPECT_EQ(sign_extend(kMaxUint32),
CallI(test->entry(), static_cast<float>(kMaxInt64)));
EXPECT_EQ(sign_extend(kMaxUint32),
CallI(test->entry(), static_cast<float>(kMaxUint64)));
EXPECT_EQ(sign_extend(0),
CallI(test->entry(), -std::numeric_limits<float>::infinity()));
EXPECT_EQ(sign_extend(kMaxUint32),
CallI(test->entry(), std::numeric_limits<float>::infinity()));
EXPECT_EQ(sign_extend(kMaxUint32),
CallI(test->entry(), std::numeric_limits<float>::signaling_NaN()));
}
ASSEMBLER_TEST_GENERATE(ConvertWordToSingle, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fcvtsw(FA0, A0);
__ ret();
}
ASSEMBLER_TEST_RUN(ConvertWordToSingle, test) {
EXPECT_DISASSEMBLY(
"d0050553 fcvt.s.w fa0, a0\n"
"00008067 ret\n");
EXPECT_EQ(-42.0f, CallF(test->entry(), sign_extend(-42)));
EXPECT_EQ(0.0f, CallF(test->entry(), sign_extend(0)));
EXPECT_EQ(42.0f, CallF(test->entry(), sign_extend(42)));
EXPECT_EQ(static_cast<float>(kMinInt32),
CallF(test->entry(), sign_extend(kMinInt32)));
EXPECT_EQ(static_cast<float>(kMaxInt32),
CallF(test->entry(), sign_extend(kMaxInt32)));
EXPECT_EQ(-1.0f, CallF(test->entry(), sign_extend(kMaxUint32)));
}
ASSEMBLER_TEST_GENERATE(ConvertUnsignedWordToSingle, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fcvtswu(FA0, A0);
__ ret();
}
ASSEMBLER_TEST_RUN(ConvertUnsignedWordToSingle, test) {
EXPECT_DISASSEMBLY(
"d0150553 fcvt.s.wu fa0, a0\n"
"00008067 ret\n");
EXPECT_EQ(
static_cast<float>(static_cast<uint32_t>(static_cast<int32_t>(-42))),
CallF(test->entry(), sign_extend(-42)));
EXPECT_EQ(0.0f, CallF(test->entry(), sign_extend(0)));
EXPECT_EQ(42.0f, CallF(test->entry(), sign_extend(42)));
EXPECT_EQ(static_cast<float>(static_cast<uint32_t>(kMinInt32)),
CallF(test->entry(), sign_extend(kMinInt32)));
EXPECT_EQ(static_cast<float>(kMaxInt32),
CallF(test->entry(), sign_extend(kMaxInt32)));
EXPECT_EQ(static_cast<float>(kMaxUint32),
CallF(test->entry(), sign_extend(kMaxUint32)));
}
ASSEMBLER_TEST_GENERATE(SingleMove, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fmvs(FA0, FA1);
__ ret();
}
ASSEMBLER_TEST_RUN(SingleMove, test) {
EXPECT_DISASSEMBLY(
"20b58553 fmv.s fa0, fa1\n"
"00008067 ret\n");
EXPECT_EQ(36.0f, CallF(test->entry(), 42.0f, 36.0f));
EXPECT_EQ(std::numeric_limits<float>::infinity(),
CallF(test->entry(), -std::numeric_limits<float>::infinity(),
std::numeric_limits<float>::infinity()));
}
ASSEMBLER_TEST_GENERATE(SingleAbsoluteValue, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fabss(FA0, FA0);
__ ret();
}
ASSEMBLER_TEST_RUN(SingleAbsoluteValue, test) {
EXPECT_DISASSEMBLY(
"20a52553 fabs.s fa0, fa0\n"
"00008067 ret\n");
EXPECT_EQ(0.0f, CallF(test->entry(), 0.0f));
EXPECT_EQ(0.0f, CallF(test->entry(), -0.0f));
EXPECT_EQ(42.0f, CallF(test->entry(), 42.0f));
EXPECT_EQ(42.0f, CallF(test->entry(), -42.0f));
EXPECT_EQ(std::numeric_limits<float>::infinity(),
CallF(test->entry(), std::numeric_limits<float>::infinity()));
EXPECT_EQ(std::numeric_limits<float>::infinity(),
CallF(test->entry(), -std::numeric_limits<float>::infinity()));
}
ASSEMBLER_TEST_GENERATE(SingleNegate, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fnegs(FA0, FA0);
__ ret();
}
ASSEMBLER_TEST_RUN(SingleNegate, test) {
EXPECT_DISASSEMBLY(
"20a51553 fneg.s fa0, fa0\n"
"00008067 ret\n");
EXPECT_EQ(-0.0f, CallF(test->entry(), 0.0f));
EXPECT_EQ(0.0f, CallF(test->entry(), -0.0f));
EXPECT_EQ(-42.0f, CallF(test->entry(), 42.0f));
EXPECT_EQ(42.0f, CallF(test->entry(), -42.0f));
EXPECT_EQ(-std::numeric_limits<float>::infinity(),
CallF(test->entry(), std::numeric_limits<float>::infinity()));
EXPECT_EQ(std::numeric_limits<float>::infinity(),
CallF(test->entry(), -std::numeric_limits<float>::infinity()));
}
ASSEMBLER_TEST_GENERATE(BitCastSingleToInteger, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fmvxw(A0, FA0);
__ ret();
}
ASSEMBLER_TEST_RUN(BitCastSingleToInteger, test) {
EXPECT_DISASSEMBLY(
"e0050553 fmv.x.w a0, fa0\n"
"00008067 ret\n");
EXPECT_EQ(bit_cast<int32_t>(0.0f), CallI(test->entry(), 0.0f));
EXPECT_EQ(bit_cast<int32_t>(-0.0f), CallI(test->entry(), -0.0f));
EXPECT_EQ(bit_cast<int32_t>(42.0f), CallI(test->entry(), 42.0f));
EXPECT_EQ(bit_cast<int32_t>(-42.0f), CallI(test->entry(), -42.0f));
EXPECT_EQ(bit_cast<int32_t>(std::numeric_limits<float>::quiet_NaN()),
CallI(test->entry(), std::numeric_limits<float>::quiet_NaN()));
EXPECT_EQ(bit_cast<int32_t>(std::numeric_limits<float>::signaling_NaN()),
CallI(test->entry(), std::numeric_limits<float>::signaling_NaN()));
EXPECT_EQ(bit_cast<int32_t>(std::numeric_limits<float>::infinity()),
CallI(test->entry(), std::numeric_limits<float>::infinity()));
EXPECT_EQ(bit_cast<int32_t>(-std::numeric_limits<float>::infinity()),
CallI(test->entry(), -std::numeric_limits<float>::infinity()));
}
ASSEMBLER_TEST_GENERATE(BitCastIntegerToSingle, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fmvwx(FA0, A0);
__ ret();
}
ASSEMBLER_TEST_RUN(BitCastIntegerToSingle, test) {
EXPECT_DISASSEMBLY(
"f0050553 fmv.w.x fa0, a0\n"
"00008067 ret\n");
EXPECT_EQ(0.0f, CallF(test->entry(), sign_extend(bit_cast<int32_t>(0.0f))));
EXPECT_EQ(-0.0f, CallF(test->entry(), sign_extend(bit_cast<int32_t>(-0.0f))));
EXPECT_EQ(42.0f, CallF(test->entry(), sign_extend(bit_cast<int32_t>(42.0f))));
EXPECT_EQ(-42.0f,
CallF(test->entry(), sign_extend(bit_cast<int32_t>(-42.0f))));
EXPECT_EQ(true, isnan(CallF(test->entry(),
sign_extend(bit_cast<int32_t>(
std::numeric_limits<float>::quiet_NaN())))));
EXPECT_EQ(true,
isnan(CallF(test->entry(),
sign_extend(bit_cast<int32_t>(
std::numeric_limits<float>::signaling_NaN())))));
EXPECT_EQ(std::numeric_limits<float>::infinity(),
CallF(test->entry(), sign_extend(bit_cast<int32_t>(
std::numeric_limits<float>::infinity()))));
EXPECT_EQ(
-std::numeric_limits<float>::infinity(),
CallF(test->entry(), sign_extend(bit_cast<int32_t>(
-std::numeric_limits<float>::infinity()))));
}
#if XLEN >= 64
ASSEMBLER_TEST_GENERATE(ConvertSingleToDoubleWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fcvtls(A0, FA0);
__ ret();
}
ASSEMBLER_TEST_RUN(ConvertSingleToDoubleWord, test) {
EXPECT_DISASSEMBLY(
"c0250553 fcvt.l.s a0, fa0\n"
"00008067 ret\n");
EXPECT_EQ(-42, CallI(test->entry(), static_cast<float>(-42)));
EXPECT_EQ(0, CallI(test->entry(), static_cast<float>(0)));
EXPECT_EQ(42, CallI(test->entry(), static_cast<float>(42)));
EXPECT_EQ(static_cast<int64_t>(kMinInt32),
CallI(test->entry(), static_cast<float>(kMinInt32)));
// float loses precision:
EXPECT_EQ(static_cast<int64_t>(kMaxInt32) + 1,
CallI(test->entry(), static_cast<float>(kMaxInt32)));
EXPECT_EQ(static_cast<int64_t>(kMaxUint32) + 1,
CallI(test->entry(), static_cast<float>(kMaxUint32)));
EXPECT_EQ(kMinInt64, CallI(test->entry(), static_cast<float>(kMinInt64)));
EXPECT_EQ(kMaxInt64, CallI(test->entry(), static_cast<float>(kMaxInt64)));
EXPECT_EQ(kMaxInt64, CallI(test->entry(), static_cast<float>(kMaxUint64)));
EXPECT_EQ(kMinInt64,
CallI(test->entry(), -std::numeric_limits<float>::infinity()));
EXPECT_EQ(kMaxInt64,
CallI(test->entry(), std::numeric_limits<float>::infinity()));
EXPECT_EQ(kMaxInt64,
CallI(test->entry(), std::numeric_limits<float>::signaling_NaN()));
}
ASSEMBLER_TEST_GENERATE(ConvertSingleToUnsignedDoubleWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fcvtlus(A0, FA0);
__ ret();
}
ASSEMBLER_TEST_RUN(ConvertSingleToUnsignedDoubleWord, test) {
EXPECT_DISASSEMBLY(
"c0350553 fcvt.lu.s a0, fa0\n"
"00008067 ret\n");
EXPECT_EQ(0, CallI(test->entry(), static_cast<float>(-42)));
EXPECT_EQ(0, CallI(test->entry(), static_cast<float>(0)));
EXPECT_EQ(42, CallI(test->entry(), static_cast<float>(42)));
EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(0)),
CallI(test->entry(), static_cast<float>(kMinInt32)));
EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(kMaxInt32) + 1),
CallI(test->entry(), static_cast<float>(kMaxInt32)));
EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(kMaxUint32) + 1),
CallI(test->entry(), static_cast<float>(kMaxUint32)));
EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(0)),
CallI(test->entry(), static_cast<float>(kMinInt64)));
EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(kMaxInt64) + 1),
CallI(test->entry(), static_cast<float>(kMaxInt64)));
EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(kMaxUint64)),
CallI(test->entry(), static_cast<float>(kMaxUint64)));
EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(0)),
CallI(test->entry(), -std::numeric_limits<float>::infinity()));
EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(kMaxUint64)),
CallI(test->entry(), std::numeric_limits<float>::infinity()));
EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(kMaxUint64)),
CallI(test->entry(), std::numeric_limits<float>::signaling_NaN()));
}
ASSEMBLER_TEST_GENERATE(ConvertDoubleWordToSingle, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fcvtsl(FA0, A0);
__ ret();
}
ASSEMBLER_TEST_RUN(ConvertDoubleWordToSingle, test) {
EXPECT_DISASSEMBLY(
"d0250553 fcvt.s.l fa0, a0\n"
"00008067 ret\n");
EXPECT_EQ(0.0f, CallF(test->entry(), sign_extend(0)));
EXPECT_EQ(42.0f, CallF(test->entry(), sign_extend(42)));
EXPECT_EQ(-42.0f, CallF(test->entry(), sign_extend(-42)));
EXPECT_EQ(static_cast<float>(kMinInt32),
CallF(test->entry(), sign_extend(kMinInt32)));
EXPECT_EQ(static_cast<float>(kMaxInt32),
CallF(test->entry(), sign_extend(kMaxInt32)));
EXPECT_EQ(static_cast<float>(sign_extend(kMaxUint32)),
CallF(test->entry(), sign_extend(kMaxUint32)));
EXPECT_EQ(static_cast<float>(kMinInt64),
CallF(test->entry(), sign_extend(kMinInt64)));
EXPECT_EQ(static_cast<float>(kMaxInt64),
CallF(test->entry(), sign_extend(kMaxInt64)));
EXPECT_EQ(static_cast<float>(sign_extend(kMaxUint64)),
CallF(test->entry(), sign_extend(kMaxUint64)));
}
ASSEMBLER_TEST_GENERATE(ConvertUnsignedDoubleWordToSingle, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fcvtslu(FA0, A0);
__ ret();
}
ASSEMBLER_TEST_RUN(ConvertUnsignedDoubleWordToSingle, test) {
EXPECT_DISASSEMBLY(
"d0350553 fcvt.s.lu fa0, a0\n"
"00008067 ret\n");
EXPECT_EQ(0.0f, CallF(test->entry(), sign_extend(0)));
EXPECT_EQ(42.0f, CallF(test->entry(), sign_extend(42)));
EXPECT_EQ(static_cast<float>(static_cast<uint64_t>(sign_extend(-42))),
CallF(test->entry(), sign_extend(-42)));
EXPECT_EQ(static_cast<float>(static_cast<uint64_t>(sign_extend(kMinInt32))),
CallF(test->entry(), sign_extend(kMinInt32)));
EXPECT_EQ(static_cast<float>(static_cast<uint64_t>(sign_extend(kMaxInt32))),
CallF(test->entry(), sign_extend(kMaxInt32)));
EXPECT_EQ(static_cast<float>(static_cast<uint64_t>(sign_extend(kMaxUint32))),
CallF(test->entry(), sign_extend(kMaxUint32)));
EXPECT_EQ(static_cast<float>(static_cast<uint64_t>(sign_extend(kMinInt64))),
CallF(test->entry(), sign_extend(kMinInt64)));
EXPECT_EQ(static_cast<float>(static_cast<uint64_t>(sign_extend(kMaxInt64))),
CallF(test->entry(), sign_extend(kMaxInt64)));
EXPECT_EQ(static_cast<float>(kMaxUint64),
CallF(test->entry(), sign_extend(kMaxUint64)));
}
#endif
ASSEMBLER_TEST_GENERATE(LoadDoubleFloat, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fld(FA0, Address(A0, 1 * sizeof(double)));
__ ret();
}
ASSEMBLER_TEST_RUN(LoadDoubleFloat, test) {
EXPECT_DISASSEMBLY(
"00853507 fld fa0, 8(a0)\n"
"00008067 ret\n");
double* data = reinterpret_cast<double*>(malloc(3 * sizeof(double)));
data[0] = 1.7;
data[1] = 2.8;
data[2] = 3.9;
EXPECT_EQ(data[1], CallD(test->entry(), reinterpret_cast<intx_t>(data)));
}
ASSEMBLER_TEST_GENERATE(StoreDoubleFloat, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fsd(FA0, Address(A0, 1 * sizeof(double)));
__ ret();
}
ASSEMBLER_TEST_RUN(StoreDoubleFloat, test) {
EXPECT_DISASSEMBLY(
"00a53427 fsd fa0, 8(a0)\n"
"00008067 ret\n");
double* data = reinterpret_cast<double*>(malloc(3 * sizeof(double)));
data[0] = 1.7;
data[1] = 2.8;
data[2] = 3.9;
CallD(test->entry(), reinterpret_cast<intx_t>(data), 4.2);
EXPECT_EQ(4.2, data[1]);
}
ASSEMBLER_TEST_GENERATE(DoubleMultiplyAdd, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fmaddd(FA0, FA0, FA1, FA2);
__ ret();
}
ASSEMBLER_TEST_RUN(DoubleMultiplyAdd, test) {
EXPECT_DISASSEMBLY(
"62b50543 fmadd.d fa0, fa0, fa1, fa2\n"
"00008067 ret\n");
EXPECT_EQ(22.0, CallD(test->entry(), 3.0, 5.0, 7.0));
EXPECT_EQ(-8.0, CallD(test->entry(), -3.0, 5.0, 7.0));
EXPECT_EQ(-8.0, CallD(test->entry(), 3.0, -5.0, 7.0));
EXPECT_EQ(8.0, CallD(test->entry(), 3.0, 5.0, -7.0));
EXPECT_EQ(26.0, CallD(test->entry(), 7.0, 3.0, 5.0));
EXPECT_EQ(-16.0, CallD(test->entry(), -7.0, 3.0, 5.0));
EXPECT_EQ(-16.0, CallD(test->entry(), 7.0, -3.0, 5.0));
EXPECT_EQ(16.0, CallD(test->entry(), 7.0, 3.0, -5.0));
}
ASSEMBLER_TEST_GENERATE(DoubleMultiplySubtract, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fmsubd(FA0, FA0, FA1, FA2);
__ ret();
}
ASSEMBLER_TEST_RUN(DoubleMultiplySubtract, test) {
EXPECT_DISASSEMBLY(
"62b50547 fmsub.d fa0, fa0, fa1, fa2\n"
"00008067 ret\n");
EXPECT_EQ(8.0, CallD(test->entry(), 3.0, 5.0, 7.0));
EXPECT_EQ(-22.0, CallD(test->entry(), -3.0, 5.0, 7.0));
EXPECT_EQ(-22.0, CallD(test->entry(), 3.0, -5.0, 7.0));
EXPECT_EQ(22.0, CallD(test->entry(), 3.0, 5.0, -7.0));
EXPECT_EQ(16.0, CallD(test->entry(), 7.0, 3.0, 5.0));
EXPECT_EQ(-26.0, CallD(test->entry(), -7.0, 3.0, 5.0));
EXPECT_EQ(-26.0, CallD(test->entry(), 7.0, -3.0, 5.0));
EXPECT_EQ(26.0, CallD(test->entry(), 7.0, 3.0, -5.0));
}
ASSEMBLER_TEST_GENERATE(DoubleNegateMultiplySubtract, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fnmsubd(FA0, FA0, FA1, FA2);
__ ret();
}
ASSEMBLER_TEST_RUN(DoubleNegateMultiplySubtract, test) {
EXPECT_DISASSEMBLY(
"62b5054b fnmsub.d fa0, fa0, fa1, fa2\n"
"00008067 ret\n");
EXPECT_EQ(-8.0, CallD(test->entry(), 3.0, 5.0, 7.0));
EXPECT_EQ(22.0, CallD(test->entry(), -3.0, 5.0, 7.0));
EXPECT_EQ(22.0, CallD(test->entry(), 3.0, -5.0, 7.0));
EXPECT_EQ(-22.0, CallD(test->entry(), 3.0, 5.0, -7.0));
EXPECT_EQ(-16.0, CallD(test->entry(), 7.0, 3.0, 5.0));
EXPECT_EQ(26.0, CallD(test->entry(), -7.0, 3.0, 5.0));
EXPECT_EQ(26.0, CallD(test->entry(), 7.0, -3.0, 5.0));
EXPECT_EQ(-26.0, CallD(test->entry(), 7.0, 3.0, -5.0));
}
ASSEMBLER_TEST_GENERATE(DoubleNegateMultiplyAdd, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fnmaddd(FA0, FA0, FA1, FA2);
__ ret();
}
ASSEMBLER_TEST_RUN(DoubleNegateMultiplyAdd, test) {
EXPECT_DISASSEMBLY(
"62b5054f fnmadd.d fa0, fa0, fa1, fa2\n"
"00008067 ret\n");
EXPECT_EQ(-22.0, CallD(test->entry(), 3.0, 5.0, 7.0));
EXPECT_EQ(8.0, CallD(test->entry(), -3.0, 5.0, 7.0));
EXPECT_EQ(8.0, CallD(test->entry(), 3.0, -5.0, 7.0));
EXPECT_EQ(-8.0, CallD(test->entry(), 3.0, 5.0, -7.0));
EXPECT_EQ(-26.0, CallD(test->entry(), 7.0, 3.0, 5.0));
EXPECT_EQ(16.0, CallD(test->entry(), -7.0, 3.0, 5.0));
EXPECT_EQ(16.0, CallD(test->entry(), 7.0, -3.0, 5.0));
EXPECT_EQ(-16.0, CallD(test->entry(), 7.0, 3.0, -5.0));
}
ASSEMBLER_TEST_GENERATE(DoubleAdd, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ faddd(FA0, FA0, FA1);
__ ret();
}
ASSEMBLER_TEST_RUN(DoubleAdd, test) {
EXPECT_DISASSEMBLY(
"02b50553 fadd.d fa0, fa0, fa1\n"
"00008067 ret\n");
EXPECT_EQ(8.0, CallD(test->entry(), 3.0, 5.0));
EXPECT_EQ(2.0, CallD(test->entry(), -3.0, 5.0));
EXPECT_EQ(-2.0, CallD(test->entry(), 3.0, -5.0));
EXPECT_EQ(-8.0, CallD(test->entry(), -3.0, -5.0));
EXPECT_EQ(10.0, CallD(test->entry(), 7.0, 3.0));
EXPECT_EQ(-4.0, CallD(test->entry(), -7.0, 3.0));
EXPECT_EQ(4.0, CallD(test->entry(), 7.0, -3.0));
EXPECT_EQ(-10.0, CallD(test->entry(), -7.0, -3.0));
}
ASSEMBLER_TEST_GENERATE(DoubleSubtract, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fsubd(FA0, FA0, FA1);
__ ret();
}
ASSEMBLER_TEST_RUN(DoubleSubtract, test) {
EXPECT_DISASSEMBLY(
"0ab50553 fsub.d fa0, fa0, fa1\n"
"00008067 ret\n");
EXPECT_EQ(-2.0, CallD(test->entry(), 3.0, 5.0));
EXPECT_EQ(-8.0, CallD(test->entry(), -3.0, 5.0));
EXPECT_EQ(8.0, CallD(test->entry(), 3.0, -5.0));
EXPECT_EQ(2.0, CallD(test->entry(), -3.0, -5.0));
EXPECT_EQ(4.0, CallD(test->entry(), 7.0, 3.0));
EXPECT_EQ(-10.0, CallD(test->entry(), -7.0, 3.0));
EXPECT_EQ(10.0, CallD(test->entry(), 7.0, -3.0));
EXPECT_EQ(-4.0, CallD(test->entry(), -7.0, -3.0));
}
ASSEMBLER_TEST_GENERATE(DoubleMultiply, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fmuld(FA0, FA0, FA1);
__ ret();
}
ASSEMBLER_TEST_RUN(DoubleMultiply, test) {
EXPECT_DISASSEMBLY(
"12b50553 fmul.d fa0, fa0, fa1\n"
"00008067 ret\n");
EXPECT_EQ(15.0, CallD(test->entry(), 3.0, 5.0));
EXPECT_EQ(-15.0, CallD(test->entry(), -3.0, 5.0));
EXPECT_EQ(-15.0, CallD(test->entry(), 3.0, -5.0));
EXPECT_EQ(15.0, CallD(test->entry(), -3.0, -5.0));
EXPECT_EQ(21.0, CallD(test->entry(), 7.0, 3.0));
EXPECT_EQ(-21.0, CallD(test->entry(), -7.0, 3.0));
EXPECT_EQ(-21.0, CallD(test->entry(), 7.0, -3.0));
EXPECT_EQ(21.0, CallD(test->entry(), -7.0, -3.0));
}
ASSEMBLER_TEST_GENERATE(DoubleDivide, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fdivd(FA0, FA0, FA1);
__ ret();
}
ASSEMBLER_TEST_RUN(DoubleDivide, test) {
EXPECT_DISASSEMBLY(
"1ab50553 fdiv.d fa0, fa0, fa1\n"
"00008067 ret\n");
EXPECT_EQ(2.0, CallD(test->entry(), 10.0, 5.0));
EXPECT_EQ(-2.0, CallD(test->entry(), -10.0, 5.0));
EXPECT_EQ(-2.0, CallD(test->entry(), 10.0, -5.0));
EXPECT_EQ(2.0, CallD(test->entry(), -10.0, -5.0));
}
ASSEMBLER_TEST_GENERATE(DoubleSquareRoot, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fsqrtd(FA0, FA0);
__ ret();
}
ASSEMBLER_TEST_RUN(DoubleSquareRoot, test) {
EXPECT_DISASSEMBLY(
"5a050553 fsqrt.d fa0, fa0\n"
"00008067 ret\n");
EXPECT_EQ(0.0, CallD(test->entry(), 0.0));
EXPECT_EQ(1.0, CallD(test->entry(), 1.0));
EXPECT_EQ(2.0, CallD(test->entry(), 4.0));
EXPECT_EQ(3.0, CallD(test->entry(), 9.0));
}
ASSEMBLER_TEST_GENERATE(DoubleSignInject, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fsgnjd(FA0, FA0, FA1);
__ ret();
}
ASSEMBLER_TEST_RUN(DoubleSignInject, test) {
EXPECT_DISASSEMBLY(
"22b50553 fsgnj.d fa0, fa0, fa1\n"
"00008067 ret\n");
EXPECT_EQ(3.0, CallD(test->entry(), 3.0, 5.0));
EXPECT_EQ(3.0, CallD(test->entry(), -3.0, 5.0));
EXPECT_EQ(-3.0, CallD(test->entry(), 3.0, -5.0));
EXPECT_EQ(-3.0, CallD(test->entry(), -3.0, -5.0));
}
ASSEMBLER_TEST_GENERATE(DoubleNegatedSignInject, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fsgnjnd(FA0, FA0, FA1);
__ ret();
}
ASSEMBLER_TEST_RUN(DoubleNegatedSignInject, test) {
EXPECT_DISASSEMBLY(
"22b51553 fsgnjn.d fa0, fa0, fa1\n"
"00008067 ret\n");
EXPECT_EQ(-3.0, CallD(test->entry(), 3.0, 5.0));
EXPECT_EQ(-3.0, CallD(test->entry(), -3.0, 5.0));
EXPECT_EQ(3.0, CallD(test->entry(), 3.0, -5.0));
EXPECT_EQ(3.0, CallD(test->entry(), -3.0, -5.0));
}
ASSEMBLER_TEST_GENERATE(DoubleXorSignInject, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fsgnjxd(FA0, FA0, FA1);
__ ret();
}
ASSEMBLER_TEST_RUN(DoubleXorSignInject, test) {
EXPECT_DISASSEMBLY(
"22b52553 fsgnjx.d fa0, fa0, fa1\n"
"00008067 ret\n");
EXPECT_EQ(3.0, CallD(test->entry(), 3.0, 5.0));
EXPECT_EQ(-3.0, CallD(test->entry(), -3.0, 5.0));
EXPECT_EQ(-3.0, CallD(test->entry(), 3.0, -5.0));
EXPECT_EQ(3.0, CallD(test->entry(), -3.0, -5.0));
}
ASSEMBLER_TEST_GENERATE(DoubleMin, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fmind(FA0, FA0, FA1);
__ ret();
}
ASSEMBLER_TEST_RUN(DoubleMin, test) {
EXPECT_DISASSEMBLY(
"2ab50553 fmin.d fa0, fa0, fa1\n"
"00008067 ret\n");
EXPECT_EQ(1.0, CallD(test->entry(), 3.0, 1.0));
EXPECT_EQ(3.0, CallD(test->entry(), 3.0, 3.0));
EXPECT_EQ(3.0, CallD(test->entry(), 3.0, 5.0));
EXPECT_EQ(-1.0, CallD(test->entry(), 3.0, -1.0));
EXPECT_EQ(-3.0, CallD(test->entry(), 3.0, -3.0));
EXPECT_EQ(-5.0, CallD(test->entry(), 3.0, -5.0));
EXPECT_EQ(-3.0, CallD(test->entry(), -3.0, 1.0));
EXPECT_EQ(-3.0, CallD(test->entry(), -3.0, 3.0));
EXPECT_EQ(-3.0, CallD(test->entry(), -3.0, 5.0));
EXPECT_EQ(-3.0, CallD(test->entry(), -3.0, -1.0));
EXPECT_EQ(-3.0, CallD(test->entry(), -3.0, -3.0));
EXPECT_EQ(-5.0, CallD(test->entry(), -3.0, -5.0));
double qNAN = std::numeric_limits<double>::quiet_NaN();
EXPECT_EQ(3.0, CallD(test->entry(), 3.0, qNAN));
EXPECT_EQ(3.0, CallD(test->entry(), qNAN, 3.0));
EXPECT_EQ(-3.0, CallD(test->entry(), -3.0, qNAN));
EXPECT_EQ(-3.0, CallD(test->entry(), qNAN, -3.0));
}
ASSEMBLER_TEST_GENERATE(DoubleMax, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fmaxd(FA0, FA0, FA1);
__ ret();
}
ASSEMBLER_TEST_RUN(DoubleMax, test) {
EXPECT_DISASSEMBLY(
"2ab51553 fmax.d fa0, fa0, fa1\n"
"00008067 ret\n");
EXPECT_EQ(3.0, CallD(test->entry(), 3.0, 1.0));
EXPECT_EQ(3.0, CallD(test->entry(), 3.0, 3.0));
EXPECT_EQ(5.0, CallD(test->entry(), 3.0, 5.0));
EXPECT_EQ(3.0, CallD(test->entry(), 3.0, -1.0));
EXPECT_EQ(3.0, CallD(test->entry(), 3.0, -3.0));
EXPECT_EQ(3.0, CallD(test->entry(), 3.0, -5.0));
EXPECT_EQ(1.0, CallD(test->entry(), -3.0, 1.0));
EXPECT_EQ(3.0, CallD(test->entry(), -3.0, 3.0));
EXPECT_EQ(5.0, CallD(test->entry(), -3.0, 5.0));
EXPECT_EQ(-1.0, CallD(test->entry(), -3.0, -1.0));
EXPECT_EQ(-3.0, CallD(test->entry(), -3.0, -3.0));
EXPECT_EQ(-3.0, CallD(test->entry(), -3.0, -5.0));
double qNAN = std::numeric_limits<double>::quiet_NaN();
EXPECT_EQ(3.0, CallD(test->entry(), 3.0, qNAN));
EXPECT_EQ(3.0, CallD(test->entry(), qNAN, 3.0));
EXPECT_EQ(-3.0, CallD(test->entry(), -3.0, qNAN));
EXPECT_EQ(-3.0, CallD(test->entry(), qNAN, -3.0));
}
ASSEMBLER_TEST_GENERATE(DoubleToSingle, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fcvtsd(FA0, FA0);
__ ret();
}
ASSEMBLER_TEST_RUN(DoubleToSingle, test) {
EXPECT_DISASSEMBLY(
"40150553 fcvt.s.d fa0, fa0\n"
"00008067 ret\n");
EXPECT_EQ(0.0f, CallF(test->entry(), 0.0));
EXPECT_EQ(42.0f, CallF(test->entry(), 42.0));
EXPECT_EQ(-42.0f, CallF(test->entry(), -42.0));
EXPECT_EQ(true, isnan(CallF(test->entry(),
std::numeric_limits<double>::quiet_NaN())));
EXPECT_EQ(true, isnan(CallF(test->entry(),
std::numeric_limits<double>::signaling_NaN())));
EXPECT_EQ(std::numeric_limits<float>::infinity(),
CallF(test->entry(), std::numeric_limits<double>::infinity()));
EXPECT_EQ(-std::numeric_limits<float>::infinity(),
CallF(test->entry(), -std::numeric_limits<double>::infinity()));
}
ASSEMBLER_TEST_GENERATE(SingleToDouble, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fcvtds(FA0, FA0);
__ ret();
}
ASSEMBLER_TEST_RUN(SingleToDouble, test) {
EXPECT_DISASSEMBLY(
"42050553 fcvt.d.s fa0, fa0\n"
"00008067 ret\n");
EXPECT_EQ(0.0, CallD(test->entry(), 0.0f));
EXPECT_EQ(42.0, CallD(test->entry(), 42.0f));
EXPECT_EQ(-42.0, CallD(test->entry(), -42.0f));
EXPECT_EQ(true, isnan(CallD(test->entry(),
std::numeric_limits<float>::quiet_NaN())));
EXPECT_EQ(true, isnan(CallD(test->entry(),
std::numeric_limits<float>::signaling_NaN())));
EXPECT_EQ(std::numeric_limits<double>::infinity(),
CallD(test->entry(), std::numeric_limits<float>::infinity()));
EXPECT_EQ(-std::numeric_limits<double>::infinity(),
CallD(test->entry(), -std::numeric_limits<float>::infinity()));
}
ASSEMBLER_TEST_GENERATE(NaNBoxing, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ ret();
}
ASSEMBLER_TEST_RUN(NaNBoxing, test) {
EXPECT_DISASSEMBLY("00008067 ret\n");
EXPECT_EQ(true, isnan(CallD(test->entry(), 42.0f)));
}
ASSEMBLER_TEST_GENERATE(DoubleEqual, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ feqd(A0, FA0, FA1);
__ ret();
}
ASSEMBLER_TEST_RUN(DoubleEqual, test) {
EXPECT_DISASSEMBLY(
"a2b52553 feq.d a0, fa0, fa1\n"
"00008067 ret\n");
EXPECT_EQ(0, CallI(test->entry(), 3.0, 1.0));
EXPECT_EQ(1, CallI(test->entry(), 3.0, 3.0));
EXPECT_EQ(0, CallI(test->entry(), 3.0, 5.0));
EXPECT_EQ(0, CallI(test->entry(), 3.0, -1.0));
EXPECT_EQ(0, CallI(test->entry(), 3.0, -3.0));
EXPECT_EQ(0, CallI(test->entry(), 3.0, -5.0));
EXPECT_EQ(0, CallI(test->entry(), -3.0, 1.0));
EXPECT_EQ(0, CallI(test->entry(), -3.0, 3.0));
EXPECT_EQ(0, CallI(test->entry(), -3.0, 5.0));
EXPECT_EQ(0, CallI(test->entry(), -3.0, -1.0));
EXPECT_EQ(1, CallI(test->entry(), -3.0, -3.0));
EXPECT_EQ(0, CallI(test->entry(), -3.0, -5.0));
double qNAN = std::numeric_limits<double>::quiet_NaN();
EXPECT_EQ(0, CallI(test->entry(), 3.0, qNAN));
EXPECT_EQ(0, CallI(test->entry(), qNAN, 3.0));
EXPECT_EQ(0, CallI(test->entry(), -3.0, qNAN));
EXPECT_EQ(0, CallI(test->entry(), qNAN, -3.0));
}
ASSEMBLER_TEST_GENERATE(DoubleLessThan, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fltd(A0, FA0, FA1);
__ ret();
}
ASSEMBLER_TEST_RUN(DoubleLessThan, test) {
EXPECT_DISASSEMBLY(
"a2b51553 flt.d a0, fa0, fa1\n"
"00008067 ret\n");
EXPECT_EQ(0, CallI(test->entry(), 3.0, 1.0));
EXPECT_EQ(0, CallI(test->entry(), 3.0, 3.0));
EXPECT_EQ(1, CallI(test->entry(), 3.0, 5.0));
EXPECT_EQ(0, CallI(test->entry(), 3.0, -1.0));
EXPECT_EQ(0, CallI(test->entry(), 3.0, -3.0));
EXPECT_EQ(0, CallI(test->entry(), 3.0, -5.0));
EXPECT_EQ(1, CallI(test->entry(), -3.0, 1.0));
EXPECT_EQ(1, CallI(test->entry(), -3.0, 3.0));
EXPECT_EQ(1, CallI(test->entry(), -3.0, 5.0));
EXPECT_EQ(1, CallI(test->entry(), -3.0, -1.0));
EXPECT_EQ(0, CallI(test->entry(), -3.0, -3.0));
EXPECT_EQ(0, CallI(test->entry(), -3.0, -5.0));
double qNAN = std::numeric_limits<double>::quiet_NaN();
EXPECT_EQ(0, CallI(test->entry(), 3.0, qNAN));
EXPECT_EQ(0, CallI(test->entry(), qNAN, 3.0));
EXPECT_EQ(0, CallI(test->entry(), -3.0, qNAN));
EXPECT_EQ(0, CallI(test->entry(), qNAN, -3.0));
}
ASSEMBLER_TEST_GENERATE(DoubleLessOrEqual, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fled(A0, FA0, FA1);
__ ret();
}
ASSEMBLER_TEST_RUN(DoubleLessOrEqual, test) {
EXPECT_DISASSEMBLY(
"a2b50553 fle.d a0, fa0, fa1\n"
"00008067 ret\n");
EXPECT_EQ(0, CallI(test->entry(), 3.0, 1.0));
EXPECT_EQ(1, CallI(test->entry(), 3.0, 3.0));
EXPECT_EQ(1, CallI(test->entry(), 3.0, 5.0));
EXPECT_EQ(0, CallI(test->entry(), 3.0, -1.0));
EXPECT_EQ(0, CallI(test->entry(), 3.0, -3.0));
EXPECT_EQ(0, CallI(test->entry(), 3.0, -5.0));
EXPECT_EQ(1, CallI(test->entry(), -3.0, 1.0));
EXPECT_EQ(1, CallI(test->entry(), -3.0, 3.0));
EXPECT_EQ(1, CallI(test->entry(), -3.0, 5.0));
EXPECT_EQ(1, CallI(test->entry(), -3.0, -1.0));
EXPECT_EQ(1, CallI(test->entry(), -3.0, -3.0));
EXPECT_EQ(0, CallI(test->entry(), -3.0, -5.0));
double qNAN = std::numeric_limits<double>::quiet_NaN();
EXPECT_EQ(0, CallI(test->entry(), 3.0, qNAN));
EXPECT_EQ(0, CallI(test->entry(), qNAN, 3.0));
EXPECT_EQ(0, CallI(test->entry(), -3.0, qNAN));
EXPECT_EQ(0, CallI(test->entry(), qNAN, -3.0));
}
ASSEMBLER_TEST_GENERATE(DoubleClassify, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fclassd(A0, FA0);
__ ret();
}
ASSEMBLER_TEST_RUN(DoubleClassify, test) {
EXPECT_DISASSEMBLY(
"e2051553 fclass.d a0, fa0\n"
"00008067 ret\n");
// Neg infinity
EXPECT_EQ(1 << 0,
CallI(test->entry(), -std::numeric_limits<double>::infinity()));
// Neg normal
EXPECT_EQ(1 << 1, CallI(test->entry(), -1.0));
// Neg subnormal
EXPECT_EQ(1 << 2,
CallI(test->entry(), -std::numeric_limits<double>::min() / 2.0));
// Neg zero
EXPECT_EQ(1 << 3, CallI(test->entry(), -0.0));
// Pos zero
EXPECT_EQ(1 << 4, CallI(test->entry(), 0.0));
// Pos subnormal
EXPECT_EQ(1 << 5,
CallI(test->entry(), std::numeric_limits<double>::min() / 2.0));
// Pos normal
EXPECT_EQ(1 << 6, CallI(test->entry(), 1.0));
// Pos infinity
EXPECT_EQ(1 << 7,
CallI(test->entry(), std::numeric_limits<double>::infinity()));
// Signaling NaN
EXPECT_EQ(1 << 8,
CallI(test->entry(), std::numeric_limits<double>::signaling_NaN()));
// Queit NaN
EXPECT_EQ(1 << 9,
CallI(test->entry(), std::numeric_limits<double>::quiet_NaN()));
}
ASSEMBLER_TEST_GENERATE(ConvertDoubleToWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fcvtwd(A0, FA0);
__ ret();
}
ASSEMBLER_TEST_RUN(ConvertDoubleToWord, test) {
EXPECT_DISASSEMBLY(
"c2050553 fcvt.w.d a0, fa0\n"
"00008067 ret\n");
EXPECT_EQ(-42, CallI(test->entry(), static_cast<double>(-42)));
EXPECT_EQ(0, CallI(test->entry(), static_cast<double>(0)));
EXPECT_EQ(42, CallI(test->entry(), static_cast<double>(42)));
EXPECT_EQ(sign_extend(kMinInt32),
CallI(test->entry(), static_cast<double>(kMinInt32)));
EXPECT_EQ(sign_extend(kMaxInt32),
CallI(test->entry(), static_cast<double>(kMaxInt32)));
EXPECT_EQ(sign_extend(kMaxInt32),
CallI(test->entry(), static_cast<double>(kMaxUint32)));
EXPECT_EQ(sign_extend(kMinInt32),
CallI(test->entry(), static_cast<double>(kMinInt64)));
EXPECT_EQ(sign_extend(kMaxInt32),
CallI(test->entry(), static_cast<double>(kMaxInt64)));
EXPECT_EQ(sign_extend(kMaxInt32),
CallI(test->entry(), static_cast<double>(kMaxUint64)));
EXPECT_EQ(sign_extend(kMinInt32),
CallI(test->entry(), -std::numeric_limits<double>::infinity()));
EXPECT_EQ(sign_extend(kMaxInt32),
CallI(test->entry(), std::numeric_limits<double>::infinity()));
EXPECT_EQ(sign_extend(kMaxInt32),
CallI(test->entry(), std::numeric_limits<double>::signaling_NaN()));
}
ASSEMBLER_TEST_GENERATE(ConvertDoubleToUnsignedWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fcvtwud(A0, FA0);
__ ret();
}
ASSEMBLER_TEST_RUN(ConvertDoubleToUnsignedWord, test) {
EXPECT_DISASSEMBLY(
"c2150553 fcvt.wu.d a0, fa0\n"
"00008067 ret\n");
EXPECT_EQ(0, CallI(test->entry(), static_cast<double>(-42)));
EXPECT_EQ(0, CallI(test->entry(), static_cast<double>(0)));
EXPECT_EQ(42, CallI(test->entry(), static_cast<double>(42)));
EXPECT_EQ(sign_extend(0),
CallI(test->entry(), static_cast<double>(kMinInt32)));
EXPECT_EQ(sign_extend(kMaxInt32),
CallI(test->entry(), static_cast<double>(kMaxInt32)));
EXPECT_EQ(sign_extend(kMaxUint32),
CallI(test->entry(), static_cast<double>(kMaxUint32)));
EXPECT_EQ(sign_extend(0),
CallI(test->entry(), static_cast<double>(kMinInt64)));
EXPECT_EQ(sign_extend(kMaxUint32),
CallI(test->entry(), static_cast<double>(kMaxInt64)));
EXPECT_EQ(sign_extend(kMaxUint32),
CallI(test->entry(), static_cast<double>(kMaxUint64)));
EXPECT_EQ(sign_extend(0),
CallI(test->entry(), -std::numeric_limits<double>::infinity()));
EXPECT_EQ(sign_extend(kMaxUint32),
CallI(test->entry(), std::numeric_limits<double>::infinity()));
EXPECT_EQ(sign_extend(kMaxUint32),
CallI(test->entry(), std::numeric_limits<double>::signaling_NaN()));
}
ASSEMBLER_TEST_GENERATE(ConvertWordToDouble, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fcvtdw(FA0, A0);
__ ret();
}
ASSEMBLER_TEST_RUN(ConvertWordToDouble, test) {
EXPECT_DISASSEMBLY(
"d2050553 fcvt.d.w fa0, a0\n"
"00008067 ret\n");
EXPECT_EQ(-42.0, CallD(test->entry(), sign_extend(-42)));
EXPECT_EQ(0.0, CallD(test->entry(), sign_extend(0)));
EXPECT_EQ(42.0, CallD(test->entry(), sign_extend(42)));
EXPECT_EQ(static_cast<double>(kMinInt32),
CallD(test->entry(), sign_extend(kMinInt32)));
EXPECT_EQ(static_cast<double>(kMaxInt32),
CallD(test->entry(), sign_extend(kMaxInt32)));
EXPECT_EQ(-1.0, CallD(test->entry(), sign_extend(kMaxUint32)));
}
ASSEMBLER_TEST_GENERATE(ConvertUnsignedWordToDouble, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fcvtdwu(FA0, A0);
__ ret();
}
ASSEMBLER_TEST_RUN(ConvertUnsignedWordToDouble, test) {
EXPECT_DISASSEMBLY(
"d2150553 fcvt.d.wu fa0, a0\n"
"00008067 ret\n");
EXPECT_EQ(
static_cast<double>(static_cast<uint32_t>(static_cast<int32_t>(-42))),
CallD(test->entry(), sign_extend(-42)));
EXPECT_EQ(0.0, CallD(test->entry(), sign_extend(0)));
EXPECT_EQ(42.0, CallD(test->entry(), sign_extend(42)));
EXPECT_EQ(static_cast<double>(static_cast<uint32_t>(kMinInt32)),
CallD(test->entry(), sign_extend(kMinInt32)));
EXPECT_EQ(static_cast<double>(kMaxInt32),
CallD(test->entry(), sign_extend(kMaxInt32)));
EXPECT_EQ(static_cast<double>(kMaxUint32),
CallD(test->entry(), sign_extend(kMaxUint32)));
}
ASSEMBLER_TEST_GENERATE(DoubleMove, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fmvd(FA0, FA1);
__ ret();
}
ASSEMBLER_TEST_RUN(DoubleMove, test) {
EXPECT_DISASSEMBLY(
"22b58553 fmv.d fa0, fa1\n"
"00008067 ret\n");
EXPECT_EQ(36.0, CallD(test->entry(), 42.0, 36.0));
EXPECT_EQ(std::numeric_limits<double>::infinity(),
CallD(test->entry(), -std::numeric_limits<double>::infinity(),
std::numeric_limits<double>::infinity()));
}
ASSEMBLER_TEST_GENERATE(DoubleAbsoluteValue, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fabsd(FA0, FA0);
__ ret();
}
ASSEMBLER_TEST_RUN(DoubleAbsoluteValue, test) {
EXPECT_DISASSEMBLY(
"22a52553 fabs.d fa0, fa0\n"
"00008067 ret\n");
EXPECT_EQ(0.0, CallD(test->entry(), 0.0));
EXPECT_EQ(0.0, CallD(test->entry(), -0.0));
EXPECT_EQ(42.0, CallD(test->entry(), 42.0));
EXPECT_EQ(42.0, CallD(test->entry(), -42.0));
EXPECT_EQ(std::numeric_limits<double>::infinity(),
CallD(test->entry(), std::numeric_limits<double>::infinity()));
EXPECT_EQ(std::numeric_limits<double>::infinity(),
CallD(test->entry(), -std::numeric_limits<double>::infinity()));
}
ASSEMBLER_TEST_GENERATE(DoubleNegate, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fnegd(FA0, FA0);
__ ret();
}
ASSEMBLER_TEST_RUN(DoubleNegate, test) {
EXPECT_DISASSEMBLY(
"22a51553 fneg.d fa0, fa0\n"
"00008067 ret\n");
EXPECT_EQ(-0.0, CallD(test->entry(), 0.0));
EXPECT_EQ(0.0, CallD(test->entry(), -0.0));
EXPECT_EQ(-42.0, CallD(test->entry(), 42.0));
EXPECT_EQ(42.0, CallD(test->entry(), -42.0));
EXPECT_EQ(-std::numeric_limits<double>::infinity(),
CallD(test->entry(), std::numeric_limits<double>::infinity()));
EXPECT_EQ(std::numeric_limits<double>::infinity(),
CallD(test->entry(), -std::numeric_limits<double>::infinity()));
}
#if XLEN >= 64
ASSEMBLER_TEST_GENERATE(ConvertDoubleToDoubleWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fcvtld(A0, FA0);
__ ret();
}
ASSEMBLER_TEST_RUN(ConvertDoubleToDoubleWord, test) {
EXPECT_DISASSEMBLY(
"c2250553 fcvt.l.d a0, fa0\n"
"00008067 ret\n");
EXPECT_EQ(-42, CallI(test->entry(), static_cast<double>(-42)));
EXPECT_EQ(0, CallI(test->entry(), static_cast<double>(0)));
EXPECT_EQ(42, CallI(test->entry(), static_cast<double>(42)));
EXPECT_EQ(static_cast<int64_t>(kMinInt32),
CallI(test->entry(), static_cast<double>(kMinInt32)));
EXPECT_EQ(static_cast<int64_t>(kMaxInt32),
CallI(test->entry(), static_cast<double>(kMaxInt32)));
EXPECT_EQ(static_cast<int64_t>(kMaxUint32),
CallI(test->entry(), static_cast<double>(kMaxUint32)));
EXPECT_EQ(kMinInt64, CallI(test->entry(), static_cast<double>(kMinInt64)));
EXPECT_EQ(kMaxInt64, CallI(test->entry(), static_cast<double>(kMaxInt64)));
EXPECT_EQ(kMaxInt64, CallI(test->entry(), static_cast<double>(kMaxUint64)));
EXPECT_EQ(kMinInt64,
CallI(test->entry(), -std::numeric_limits<double>::infinity()));
EXPECT_EQ(kMaxInt64,
CallI(test->entry(), std::numeric_limits<double>::infinity()));
EXPECT_EQ(kMaxInt64,
CallI(test->entry(), std::numeric_limits<double>::signaling_NaN()));
}
ASSEMBLER_TEST_GENERATE(ConvertDoubleToDoubleWord_RNE, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fcvtld(A0, FA0, RNE);
__ ret();
}
ASSEMBLER_TEST_RUN(ConvertDoubleToDoubleWord_RNE, test) {
EXPECT_DISASSEMBLY(
"c2250553 fcvt.l.d a0, fa0\n"
"00008067 ret\n");
EXPECT_EQ(-44, CallI(test->entry(), -43.6));
EXPECT_EQ(-44, CallI(test->entry(), -43.5));
EXPECT_EQ(-43, CallI(test->entry(), -43.4));
EXPECT_EQ(-43, CallI(test->entry(), -43.0));
EXPECT_EQ(-43, CallI(test->entry(), -42.6));
EXPECT_EQ(-42, CallI(test->entry(), -42.5));
EXPECT_EQ(-42, CallI(test->entry(), -42.4));
EXPECT_EQ(-42, CallI(test->entry(), -42.0));
EXPECT_EQ(0, CallI(test->entry(), -0.0));
EXPECT_EQ(0, CallI(test->entry(), +0.0));
EXPECT_EQ(42, CallI(test->entry(), 42.0));
EXPECT_EQ(42, CallI(test->entry(), 42.4));
EXPECT_EQ(42, CallI(test->entry(), 42.5));
EXPECT_EQ(43, CallI(test->entry(), 42.6));
EXPECT_EQ(43, CallI(test->entry(), 43.0));
EXPECT_EQ(43, CallI(test->entry(), 43.4));
EXPECT_EQ(44, CallI(test->entry(), 43.5));
EXPECT_EQ(44, CallI(test->entry(), 43.6));
}
ASSEMBLER_TEST_GENERATE(ConvertDoubleToDoubleWord_RTZ, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fcvtld(A0, FA0, RTZ);
__ ret();
}
ASSEMBLER_TEST_RUN(ConvertDoubleToDoubleWord_RTZ, test) {
EXPECT_DISASSEMBLY(
"c2251553 fcvt.l.d a0, fa0, rtz\n"
"00008067 ret\n");
EXPECT_EQ(-43, CallI(test->entry(), -43.6));
EXPECT_EQ(-43, CallI(test->entry(), -43.5));
EXPECT_EQ(-43, CallI(test->entry(), -43.4));
EXPECT_EQ(-43, CallI(test->entry(), -43.0));
EXPECT_EQ(-42, CallI(test->entry(), -42.6));
EXPECT_EQ(-42, CallI(test->entry(), -42.5));
EXPECT_EQ(-42, CallI(test->entry(), -42.4));
EXPECT_EQ(-42, CallI(test->entry(), -42.0));
EXPECT_EQ(0, CallI(test->entry(), -0.0));
EXPECT_EQ(0, CallI(test->entry(), +0.0));
EXPECT_EQ(42, CallI(test->entry(), 42.0));
EXPECT_EQ(42, CallI(test->entry(), 42.4));
EXPECT_EQ(42, CallI(test->entry(), 42.5));
EXPECT_EQ(42, CallI(test->entry(), 42.6));
EXPECT_EQ(43, CallI(test->entry(), 43.0));
EXPECT_EQ(43, CallI(test->entry(), 43.4));
EXPECT_EQ(43, CallI(test->entry(), 43.5));
EXPECT_EQ(43, CallI(test->entry(), 43.6));
}
ASSEMBLER_TEST_GENERATE(ConvertDoubleToDoubleWord_RDN, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fcvtld(A0, FA0, RDN);
__ ret();
}
ASSEMBLER_TEST_RUN(ConvertDoubleToDoubleWord_RDN, test) {
EXPECT_DISASSEMBLY(
"c2252553 fcvt.l.d a0, fa0, rdn\n"
"00008067 ret\n");
EXPECT_EQ(-44, CallI(test->entry(), -43.6));
EXPECT_EQ(-44, CallI(test->entry(), -43.5));
EXPECT_EQ(-44, CallI(test->entry(), -43.4));
EXPECT_EQ(-43, CallI(test->entry(), -43.0));
EXPECT_EQ(-43, CallI(test->entry(), -42.6));
EXPECT_EQ(-43, CallI(test->entry(), -42.5));
EXPECT_EQ(-43, CallI(test->entry(), -42.4));
EXPECT_EQ(-42, CallI(test->entry(), -42.0));
EXPECT_EQ(0, CallI(test->entry(), -0.0));
EXPECT_EQ(0, CallI(test->entry(), +0.0));
EXPECT_EQ(42, CallI(test->entry(), 42.0));
EXPECT_EQ(42, CallI(test->entry(), 42.4));
EXPECT_EQ(42, CallI(test->entry(), 42.5));
EXPECT_EQ(42, CallI(test->entry(), 42.6));
EXPECT_EQ(43, CallI(test->entry(), 43.0));
EXPECT_EQ(43, CallI(test->entry(), 43.4));
EXPECT_EQ(43, CallI(test->entry(), 43.5));
EXPECT_EQ(43, CallI(test->entry(), 43.6));
}
ASSEMBLER_TEST_GENERATE(ConvertDoubleToDoubleWord_RUP, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fcvtld(A0, FA0, RUP);
__ ret();
}
ASSEMBLER_TEST_RUN(ConvertDoubleToDoubleWord_RUP, test) {
EXPECT_DISASSEMBLY(
"c2253553 fcvt.l.d a0, fa0, rup\n"
"00008067 ret\n");
EXPECT_EQ(-43, CallI(test->entry(), -43.6));
EXPECT_EQ(-43, CallI(test->entry(), -43.5));
EXPECT_EQ(-43, CallI(test->entry(), -43.4));
EXPECT_EQ(-43, CallI(test->entry(), -43.0));
EXPECT_EQ(-42, CallI(test->entry(), -42.6));
EXPECT_EQ(-42, CallI(test->entry(), -42.5));
EXPECT_EQ(-42, CallI(test->entry(), -42.4));
EXPECT_EQ(-42, CallI(test->entry(), -42.0));
EXPECT_EQ(0, CallI(test->entry(), -0.0));
EXPECT_EQ(0, CallI(test->entry(), +0.0));
EXPECT_EQ(42, CallI(test->entry(), 42.0));
EXPECT_EQ(43, CallI(test->entry(), 42.4));
EXPECT_EQ(43, CallI(test->entry(), 42.5));
EXPECT_EQ(43, CallI(test->entry(), 42.6));
EXPECT_EQ(43, CallI(test->entry(), 43.0));
EXPECT_EQ(44, CallI(test->entry(), 43.5));
EXPECT_EQ(44, CallI(test->entry(), 43.5));
EXPECT_EQ(44, CallI(test->entry(), 43.6));
}
ASSEMBLER_TEST_GENERATE(ConvertDoubleToDoubleWord_RMM, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fcvtld(A0, FA0, RMM);
__ ret();
}
ASSEMBLER_TEST_RUN(ConvertDoubleToDoubleWord_RMM, test) {
EXPECT_DISASSEMBLY(
"c2254553 fcvt.l.d a0, fa0, rmm\n"
"00008067 ret\n");
EXPECT_EQ(-44, CallI(test->entry(), -43.6));
EXPECT_EQ(-44, CallI(test->entry(), -43.5));
EXPECT_EQ(-43, CallI(test->entry(), -43.4));
EXPECT_EQ(-43, CallI(test->entry(), -43.0));
EXPECT_EQ(-43, CallI(test->entry(), -42.6));
EXPECT_EQ(-43, CallI(test->entry(), -42.5));
EXPECT_EQ(-42, CallI(test->entry(), -42.4));
EXPECT_EQ(-42, CallI(test->entry(), -42.0));
EXPECT_EQ(0, CallI(test->entry(), -0.0));
EXPECT_EQ(0, CallI(test->entry(), +0.0));
EXPECT_EQ(42, CallI(test->entry(), 42.0));
EXPECT_EQ(42, CallI(test->entry(), 42.4));
EXPECT_EQ(43, CallI(test->entry(), 42.5));
EXPECT_EQ(43, CallI(test->entry(), 42.6));
EXPECT_EQ(43, CallI(test->entry(), 43.0));
EXPECT_EQ(43, CallI(test->entry(), 43.4));
EXPECT_EQ(44, CallI(test->entry(), 43.5));
EXPECT_EQ(44, CallI(test->entry(), 43.6));
}
ASSEMBLER_TEST_GENERATE(ConvertDoubleToUnsignedDoubleWord, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fcvtlud(A0, FA0);
__ ret();
}
ASSEMBLER_TEST_RUN(ConvertDoubleToUnsignedDoubleWord, test) {
EXPECT_DISASSEMBLY(
"c2350553 fcvt.lu.d a0, fa0\n"
"00008067 ret\n");
EXPECT_EQ(0, CallI(test->entry(), static_cast<double>(-42)));
EXPECT_EQ(0, CallI(test->entry(), static_cast<double>(0)));
EXPECT_EQ(42, CallI(test->entry(), static_cast<double>(42)));
EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(0)),
CallI(test->entry(), static_cast<double>(kMinInt32)));
EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(kMaxInt32)),
CallI(test->entry(), static_cast<double>(kMaxInt32)));
EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(kMaxUint32)),
CallI(test->entry(), static_cast<double>(kMaxUint32)));
EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(0)),
CallI(test->entry(), static_cast<double>(kMinInt64)));
EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(kMaxInt64) + 1),
CallI(test->entry(), static_cast<double>(kMaxInt64)));
EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(kMaxUint64)),
CallI(test->entry(), static_cast<double>(kMaxUint64)));
EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(0)),
CallI(test->entry(), -std::numeric_limits<double>::infinity()));
EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(kMaxUint64)),
CallI(test->entry(), std::numeric_limits<double>::infinity()));
EXPECT_EQ(static_cast<int64_t>(static_cast<uint64_t>(kMaxUint64)),
CallI(test->entry(), std::numeric_limits<double>::signaling_NaN()));
}
ASSEMBLER_TEST_GENERATE(BitCastDoubleToInteger, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fmvxd(A0, FA0);
__ ret();
}
ASSEMBLER_TEST_RUN(BitCastDoubleToInteger, test) {
EXPECT_DISASSEMBLY(
"e2050553 fmv.x.d a0, fa0\n"
"00008067 ret\n");
EXPECT_EQ(bit_cast<int64_t>(0.0), CallI(test->entry(), 0.0));
EXPECT_EQ(bit_cast<int64_t>(-0.0), CallI(test->entry(), -0.0));
EXPECT_EQ(bit_cast<int64_t>(42.0), CallI(test->entry(), 42.0));
EXPECT_EQ(bit_cast<int64_t>(-42.0), CallI(test->entry(), -42.0));
EXPECT_EQ(bit_cast<int64_t>(std::numeric_limits<double>::quiet_NaN()),
CallI(test->entry(), std::numeric_limits<double>::quiet_NaN()));
EXPECT_EQ(bit_cast<int64_t>(std::numeric_limits<double>::signaling_NaN()),
CallI(test->entry(), std::numeric_limits<double>::signaling_NaN()));
EXPECT_EQ(bit_cast<int64_t>(std::numeric_limits<double>::infinity()),
CallI(test->entry(), std::numeric_limits<double>::infinity()));
EXPECT_EQ(bit_cast<int64_t>(-std::numeric_limits<double>::infinity()),
CallI(test->entry(), -std::numeric_limits<double>::infinity()));
}
ASSEMBLER_TEST_GENERATE(ConvertDoubleWordToDouble, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fcvtdl(FA0, A0);
__ ret();
}
ASSEMBLER_TEST_RUN(ConvertDoubleWordToDouble, test) {
EXPECT_DISASSEMBLY(
"d2250553 fcvt.d.l fa0, a0\n"
"00008067 ret\n");
EXPECT_EQ(0.0, CallD(test->entry(), sign_extend(0)));
EXPECT_EQ(42.0, CallD(test->entry(), sign_extend(42)));
EXPECT_EQ(-42.0, CallD(test->entry(), sign_extend(-42)));
EXPECT_EQ(static_cast<double>(kMinInt32),
CallD(test->entry(), sign_extend(kMinInt32)));
EXPECT_EQ(static_cast<double>(kMaxInt32),
CallD(test->entry(), sign_extend(kMaxInt32)));
EXPECT_EQ(static_cast<double>(sign_extend(kMaxUint32)),
CallD(test->entry(), sign_extend(kMaxUint32)));
EXPECT_EQ(static_cast<double>(kMinInt64),
CallD(test->entry(), sign_extend(kMinInt64)));
EXPECT_EQ(static_cast<double>(kMaxInt64),
CallD(test->entry(), sign_extend(kMaxInt64)));
EXPECT_EQ(static_cast<double>(sign_extend(kMaxUint64)),
CallD(test->entry(), sign_extend(kMaxUint64)));
}
ASSEMBLER_TEST_GENERATE(ConvertUnsignedDoubleWordToDouble, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fcvtdlu(FA0, A0);
__ ret();
}
ASSEMBLER_TEST_RUN(ConvertUnsignedDoubleWordToDouble, test) {
EXPECT_DISASSEMBLY(
"d2350553 fcvt.d.lu fa0, a0\n"
"00008067 ret\n");
EXPECT_EQ(0.0, CallD(test->entry(), sign_extend(0)));
EXPECT_EQ(42.0, CallD(test->entry(), sign_extend(42)));
EXPECT_EQ(static_cast<double>(static_cast<uint64_t>(sign_extend(-42))),
CallD(test->entry(), sign_extend(-42)));
EXPECT_EQ(static_cast<double>(static_cast<uint64_t>(sign_extend(kMinInt32))),
CallD(test->entry(), sign_extend(kMinInt32)));
EXPECT_EQ(static_cast<double>(static_cast<uint64_t>(sign_extend(kMaxInt32))),
CallD(test->entry(), sign_extend(kMaxInt32)));
EXPECT_EQ(static_cast<double>(static_cast<uint64_t>(sign_extend(kMaxUint32))),
CallD(test->entry(), sign_extend(kMaxUint32)));
EXPECT_EQ(static_cast<double>(static_cast<uint64_t>(sign_extend(kMinInt64))),
CallD(test->entry(), sign_extend(kMinInt64)));
EXPECT_EQ(static_cast<double>(static_cast<uint64_t>(sign_extend(kMaxInt64))),
CallD(test->entry(), sign_extend(kMaxInt64)));
EXPECT_EQ(static_cast<double>(kMaxUint64),
CallD(test->entry(), sign_extend(kMaxUint64)));
}
ASSEMBLER_TEST_GENERATE(BitCastIntegerToDouble, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
__ fmvdx(FA0, A0);
__ ret();
}
ASSEMBLER_TEST_RUN(BitCastIntegerToDouble, test) {
EXPECT_DISASSEMBLY(
"f2050553 fmv.d.x fa0, a0\n"
"00008067 ret\n");
EXPECT_EQ(0.0, CallD(test->entry(), bit_cast<int64_t>(0.0)));
EXPECT_EQ(-0.0, CallD(test->entry(), bit_cast<int64_t>(-0.0)));
EXPECT_EQ(42.0, CallD(test->entry(), bit_cast<int64_t>(42.0)));
EXPECT_EQ(-42.0, CallD(test->entry(), bit_cast<int64_t>(-42.0)));
EXPECT_EQ(true, isnan(CallD(test->entry(),
bit_cast<int64_t>(
std::numeric_limits<double>::quiet_NaN()))));
EXPECT_EQ(true,
isnan(CallD(test->entry(),
bit_cast<int64_t>(
std::numeric_limits<double>::signaling_NaN()))));
EXPECT_EQ(std::numeric_limits<double>::infinity(),
CallD(test->entry(),
bit_cast<int64_t>(std::numeric_limits<double>::infinity())));
EXPECT_EQ(-std::numeric_limits<double>::infinity(),
CallD(test->entry(),
bit_cast<int64_t>(-std::numeric_limits<double>::infinity())));
}
#endif
ASSEMBLER_TEST_GENERATE(Fibonacci, assembler) {
FLAG_use_compressed_instructions = false;
__ SetExtensions(RV_G);
Label fib, base, done;
__ Bind(&fib);
__ subi(SP, SP, sizeof(uintx_t) * 4);
__ sx(RA, Address(SP, 3 * sizeof(uintx_t)));
__ sx(A0, Address(SP, 2 * sizeof(uintx_t)));
__ subi(A0, A0, 1);
__ blez(A0, &base);
__ jal(&fib);
__ sx(A0, Address(SP, 1 * sizeof(uintx_t)));
__ lx(A0, Address(SP, 2 * sizeof(uintx_t)));
__ subi(A0, A0, 2);
__ jal(&fib);
__ lx(A1, Address(SP, 1 * sizeof(uintx_t)));
__ add(A0, A0, A1);
__ j(&done);
__ Bind(&base);
__ li(A0, 1);
__ Bind(&done);
__ lx(RA, Address(SP, 3 * sizeof(uintx_t)));
__ addi(SP, SP, sizeof(uintx_t) * 4);
__ ret();
__ trap();
}
ASSEMBLER_TEST_RUN(Fibonacci, test) {
#if XLEN == 32
EXPECT_DISASSEMBLY(
"ff010113 addi sp, sp, -16\n"
"00112623 sw ra, 12(sp)\n"
"00a12423 sw a0, 8(sp)\n"
"fff50513 addi a0, a0, -1\n"
"02a05263 blez a0, +36\n"
"fedff0ef jal -20\n"
"00a12223 sw a0, 4(sp)\n"
"00812503 lw a0, 8(sp)\n"
"ffe50513 addi a0, a0, -2\n"
"fddff0ef jal -36\n"
"00412583 lw a1, 4(sp)\n"
"00b50533 add a0, a0, a1\n"
"0080006f j +8\n"
"00100513 li a0, 1\n"
"00c12083 lw ra, 12(sp)\n"
"01010113 addi sp, sp, 16\n"
"00008067 ret\n"
"00000000 trap\n");
#elif XLEN == 64
EXPECT_DISASSEMBLY(
"fe010113 addi sp, sp, -32\n"
"00113c23 sd ra, 24(sp)\n"
"00a13823 sd a0, 16(sp)\n"
"fff50513 addi a0, a0, -1\n"
"02a05263 blez a0, +36\n"
"fedff0ef jal -20\n"
"00a13423 sd a0, 8(sp)\n"
"01013503 ld a0, 16(sp)\n"
"ffe50513 addi a0, a0, -2\n"
"fddff0ef jal -36\n"
"00813583 ld a1, 8(sp)\n"
"00b50533 add a0, a0, a1\n"
"0080006f j +8\n"
"00100513 li a0, 1\n"
"01813083 ld ra, 24(sp)\n"
"02010113 addi sp, sp, 32\n"
"00008067 ret\n"
"00000000 trap\n");
#else
#error Unimplemented
#endif
EXPECT_EQ(1, Call(test->entry(), 0));
EXPECT_EQ(1, Call(test->entry(), 1));
EXPECT_EQ(2, Call(test->entry(), 2));
EXPECT_EQ(3, Call(test->entry(), 3));
EXPECT_EQ(5, Call(test->entry(), 4));
EXPECT_EQ(8, Call(test->entry(), 5));
EXPECT_EQ(13, Call(test->entry(), 6));
}
ASSEMBLER_TEST_GENERATE(CompressedLoadStoreWordSP_0, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ subi(SP, SP, 256);
__ sw(A1, Address(SP, 0));
__ lw(A0, Address(SP, 0));
__ addi(SP, SP, 256);
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedLoadStoreWordSP_0, test) {
EXPECT_DISASSEMBLY(
" 7111 addi sp, sp, -256\n"
" c02e sw a1, 0(sp)\n"
" 4502 lw a0, 0(sp)\n"
" 6111 addi sp, sp, 256\n"
" 8082 ret\n");
EXPECT_EQ(sign_extend(0xAB010203), Call(test->entry(), 0, 0xAB010203));
EXPECT_EQ(sign_extend(0xCD020405), Call(test->entry(), 0, 0xCD020405));
EXPECT_EQ(sign_extend(0xEF030607), Call(test->entry(), 0, 0xEF030607));
}
ASSEMBLER_TEST_GENERATE(CompressedLoadStoreWordSP_Pos, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ subi(SP, SP, 256);
__ sw(A1, Address(SP, 4));
__ lw(A0, Address(SP, 4));
__ addi(SP, SP, 256);
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedLoadStoreWordSP_Pos, test) {
EXPECT_DISASSEMBLY(
" 7111 addi sp, sp, -256\n"
" c22e sw a1, 4(sp)\n"
" 4512 lw a0, 4(sp)\n"
" 6111 addi sp, sp, 256\n"
" 8082 ret\n");
EXPECT_EQ(sign_extend(0xAB010203), Call(test->entry(), 0, 0xAB010203));
EXPECT_EQ(sign_extend(0xCD020405), Call(test->entry(), 0, 0xCD020405));
EXPECT_EQ(sign_extend(0xEF030607), Call(test->entry(), 0, 0xEF030607));
}
#if XLEN == 32
ASSEMBLER_TEST_GENERATE(CompressedLoadStoreSingleFloatSP_0, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ subi(SP, SP, 256);
__ fsw(FA1, Address(SP, 0));
__ flw(FA0, Address(SP, 0));
__ addi(SP, SP, 256);
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedLoadStoreSingleFloatSP_0, test) {
EXPECT_DISASSEMBLY(
" 7111 addi sp, sp, -256\n"
" e02e fsw fa1, 0(sp)\n"
" 6502 flw fa0, 0(sp)\n"
" 6111 addi sp, sp, 256\n"
" 8082 ret\n");
EXPECT_EQ(1.7f, CallF(test->entry(), 0.0f, 1.7f));
EXPECT_EQ(2.8f, CallF(test->entry(), 0.0f, 2.8f));
EXPECT_EQ(3.9f, CallF(test->entry(), 0.0f, 3.9f));
}
ASSEMBLER_TEST_GENERATE(CompressedLoadStoreSingleFloatSP_Pos, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ subi(SP, SP, 256);
__ fsw(FA1, Address(SP, 4));
__ flw(FA0, Address(SP, 4));
__ addi(SP, SP, 256);
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedLoadStoreSingleFloatSP_Pos, test) {
EXPECT_DISASSEMBLY(
" 7111 addi sp, sp, -256\n"
" e22e fsw fa1, 4(sp)\n"
" 6512 flw fa0, 4(sp)\n"
" 6111 addi sp, sp, 256\n"
" 8082 ret\n");
EXPECT_EQ(1.7f, CallF(test->entry(), 0.0f, 1.7f));
EXPECT_EQ(2.8f, CallF(test->entry(), 0.0f, 2.8f));
EXPECT_EQ(3.9f, CallF(test->entry(), 0.0f, 3.9f));
}
#endif
ASSEMBLER_TEST_GENERATE(CompressedLoadStoreDoubleFloatSP_0, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ subi(SP, SP, 256);
__ fsd(FA1, Address(SP, 0));
__ fld(FA0, Address(SP, 0));
__ addi(SP, SP, 256);
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedLoadStoreDoubleFloatSP_0, test) {
EXPECT_DISASSEMBLY(
" 7111 addi sp, sp, -256\n"
" a02e fsd fa1, 0(sp)\n"
" 2502 fld fa0, 0(sp)\n"
" 6111 addi sp, sp, 256\n"
" 8082 ret\n");
EXPECT_EQ(1.7, CallD(test->entry(), 0.0, 1.7));
EXPECT_EQ(2.8, CallD(test->entry(), 0.0, 2.8));
EXPECT_EQ(3.9, CallD(test->entry(), 0.0, 3.9));
}
ASSEMBLER_TEST_GENERATE(CompressedLoadStoreDoubleFloatSP_Pos, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ subi(SP, SP, 256);
__ fsd(FA1, Address(SP, 8));
__ fld(FA0, Address(SP, 8));
__ addi(SP, SP, 256);
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedLoadStoreDoubleFloatSP_Pos, test) {
EXPECT_DISASSEMBLY(
" 7111 addi sp, sp, -256\n"
" a42e fsd fa1, 8(sp)\n"
" 2522 fld fa0, 8(sp)\n"
" 6111 addi sp, sp, 256\n"
" 8082 ret\n");
EXPECT_EQ(1.7, CallD(test->entry(), 0.0, 1.7));
EXPECT_EQ(2.8, CallD(test->entry(), 0.0, 2.8));
EXPECT_EQ(3.9, CallD(test->entry(), 0.0, 3.9));
}
#if XLEN >= 64
ASSEMBLER_TEST_GENERATE(CompressedLoadStoreDoubleWordSP_0, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ subi(SP, SP, 256);
__ sd(A1, Address(SP, 0));
__ ld(A0, Address(SP, 0));
__ addi(SP, SP, 256);
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedLoadStoreDoubleWordSP_0, test) {
EXPECT_DISASSEMBLY(
" 7111 addi sp, sp, -256\n"
" e02e sd a1, 0(sp)\n"
" 6502 ld a0, 0(sp)\n"
" 6111 addi sp, sp, 256\n"
" 8082 ret\n");
EXPECT_EQ((intx_t)0xAB01020304050607,
Call(test->entry(), 0, 0xAB01020304050607));
EXPECT_EQ((intx_t)0xCD02040505060708,
Call(test->entry(), 0, 0xCD02040505060708));
EXPECT_EQ((intx_t)0xEF03060708090A0B,
Call(test->entry(), 0, 0xEF03060708090A0B));
}
ASSEMBLER_TEST_GENERATE(CompressedLoadStoreDoubleWordSP_Pos, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ subi(SP, SP, 256);
__ sd(A1, Address(SP, 8));
__ ld(A0, Address(SP, 8));
__ addi(SP, SP, 256);
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedLoadStoreDoubleWordSP_Pos, test) {
EXPECT_DISASSEMBLY(
" 7111 addi sp, sp, -256\n"
" e42e sd a1, 8(sp)\n"
" 6522 ld a0, 8(sp)\n"
" 6111 addi sp, sp, 256\n"
" 8082 ret\n");
EXPECT_EQ((intx_t)0xAB01020304050607,
Call(test->entry(), 0, 0xAB01020304050607));
EXPECT_EQ((intx_t)0xCD02040505060708,
Call(test->entry(), 0, 0xCD02040505060708));
EXPECT_EQ((intx_t)0xEF03060708090A0B,
Call(test->entry(), 0, 0xEF03060708090A0B));
}
#endif
ASSEMBLER_TEST_GENERATE(CompressedLoadWord_0, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ lw(A0, Address(A0, 0));
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedLoadWord_0, test) {
EXPECT_DISASSEMBLY(
" 4108 lw a0, 0(a0)\n"
" 8082 ret\n");
uint32_t* values = reinterpret_cast<uint32_t*>(malloc(3 * sizeof(uint32_t)));
values[0] = 0xAB010203;
values[1] = 0xCD020405;
values[2] = 0xEF030607;
EXPECT_EQ(-855505915,
Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
}
ASSEMBLER_TEST_GENERATE(CompressedLoadWord_Pos, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ lw(A0, Address(A0, 4));
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedLoadWord_Pos, test) {
EXPECT_DISASSEMBLY(
" 4148 lw a0, 4(a0)\n"
" 8082 ret\n");
uint32_t* values = reinterpret_cast<uint32_t*>(malloc(3 * sizeof(uint32_t)));
values[0] = 0xAB010203;
values[1] = 0xCD020405;
values[2] = 0xEF030607;
EXPECT_EQ(-285014521,
Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
}
ASSEMBLER_TEST_GENERATE(CompressedStoreWord_0, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ sw(A1, Address(A0, 0));
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedStoreWord_0, test) {
EXPECT_DISASSEMBLY(
" c10c sw a1, 0(a0)\n"
" 8082 ret\n");
uint32_t* values = reinterpret_cast<uint32_t*>(malloc(3 * sizeof(uint32_t)));
values[0] = 0;
values[1] = 0;
values[2] = 0;
Call(test->entry(), reinterpret_cast<intx_t>(&values[1]), 0xCD020405);
EXPECT_EQ(0u, values[0]);
EXPECT_EQ(0xCD020405, values[1]);
EXPECT_EQ(0u, values[2]);
}
ASSEMBLER_TEST_GENERATE(CompressedStoreWord_Pos, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ sw(A1, Address(A0, 4));
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedStoreWord_Pos, test) {
EXPECT_DISASSEMBLY(
" c14c sw a1, 4(a0)\n"
" 8082 ret\n");
uint32_t* values = reinterpret_cast<uint32_t*>(malloc(3 * sizeof(uint32_t)));
values[0] = 0;
values[1] = 0;
values[2] = 0;
Call(test->entry(), reinterpret_cast<intx_t>(&values[1]), 0xEF030607);
EXPECT_EQ(0u, values[0]);
EXPECT_EQ(0u, values[1]);
EXPECT_EQ(0xEF030607, values[2]);
}
#if XLEN == 32
ASSEMBLER_TEST_GENERATE(CompressedLoadSingleFloat, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ flw(FA0, Address(A0, 1 * sizeof(float)));
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedLoadSingleFloat, test) {
EXPECT_DISASSEMBLY(
" 6148 flw fa0, 4(a0)\n"
" 8082 ret\n");
float* data = reinterpret_cast<float*>(malloc(3 * sizeof(float)));
data[0] = 1.7f;
data[1] = 2.8f;
data[2] = 3.9f;
EXPECT_EQ(data[1], CallF(test->entry(), reinterpret_cast<intx_t>(data)));
}
ASSEMBLER_TEST_GENERATE(CompressedStoreSingleFloat, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ fsw(FA0, Address(A0, 1 * sizeof(float)));
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedStoreSingleFloat, test) {
EXPECT_DISASSEMBLY(
" e148 fsw fa0, 4(a0)\n"
" 8082 ret\n");
float* data = reinterpret_cast<float*>(malloc(3 * sizeof(float)));
data[0] = 1.7f;
data[1] = 2.8f;
data[2] = 3.9f;
CallF(test->entry(), reinterpret_cast<intx_t>(data), 4.2f);
EXPECT_EQ(4.2f, data[1]);
}
#endif
#if XLEN >= 64
ASSEMBLER_TEST_GENERATE(CompressedLoadDoubleWord_0, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ ld(A0, Address(A0, 0));
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedLoadDoubleWord_0, test) {
EXPECT_DISASSEMBLY(
" 6108 ld a0, 0(a0)\n"
" 8082 ret\n");
uint64_t* values = reinterpret_cast<uint64_t*>(malloc(3 * sizeof(uint64_t)));
values[0] = 0xAB01020304050607;
values[1] = 0xCD02040505060708;
values[2] = 0xEF03060708090A0B;
EXPECT_EQ(-3674369926375274744,
Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
}
ASSEMBLER_TEST_GENERATE(CompressedLoadDoubleWord_Pos, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ ld(A0, Address(A0, 8));
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedLoadDoubleWord_Pos, test) {
EXPECT_DISASSEMBLY(
" 6508 ld a0, 8(a0)\n"
" 8082 ret\n");
uint64_t* values = reinterpret_cast<uint64_t*>(malloc(3 * sizeof(uint64_t)));
values[0] = 0xAB01020304050607;
values[1] = 0xCD02040505060708;
values[2] = 0xEF03060708090A0B;
EXPECT_EQ(-1224128046445295093,
Call(test->entry(), reinterpret_cast<intx_t>(&values[1])));
}
ASSEMBLER_TEST_GENERATE(CompressedStoreDoubleWord_0, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ sd(A1, Address(A0, 0));
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedStoreDoubleWord_0, test) {
EXPECT_DISASSEMBLY(
" e10c sd a1, 0(a0)\n"
" 8082 ret\n");
uint64_t* values = reinterpret_cast<uint64_t*>(malloc(3 * sizeof(uint64_t)));
values[0] = 0;
values[1] = 0;
values[2] = 0;
Call(test->entry(), reinterpret_cast<intx_t>(&values[1]), 0xCD02040505060708);
EXPECT_EQ(0u, values[0]);
EXPECT_EQ(0xCD02040505060708, values[1]);
EXPECT_EQ(0u, values[2]);
}
ASSEMBLER_TEST_GENERATE(CompressedStoreDoubleWord_Pos, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ sd(A1, Address(A0, 8));
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedStoreDoubleWord_Pos, test) {
EXPECT_DISASSEMBLY(
" e50c sd a1, 8(a0)\n"
" 8082 ret\n");
uint64_t* values = reinterpret_cast<uint64_t*>(malloc(3 * sizeof(uint64_t)));
values[0] = 0;
values[1] = 0;
values[2] = 0;
Call(test->entry(), reinterpret_cast<intx_t>(&values[1]), 0xEF03060708090A0B);
EXPECT_EQ(0u, values[0]);
EXPECT_EQ(0u, values[1]);
EXPECT_EQ(0xEF03060708090A0B, values[2]);
}
ASSEMBLER_TEST_GENERATE(CompressedLoadDoubleFloat, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ fld(FA0, Address(A0, 1 * sizeof(double)));
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedLoadDoubleFloat, test) {
EXPECT_DISASSEMBLY(
" 2508 fld fa0, 8(a0)\n"
" 8082 ret\n");
double* data = reinterpret_cast<double*>(malloc(3 * sizeof(double)));
data[0] = 1.7;
data[1] = 2.8;
data[2] = 3.9;
EXPECT_EQ(data[1], CallD(test->entry(), reinterpret_cast<intx_t>(data)));
free(data);
}
ASSEMBLER_TEST_GENERATE(CompressedStoreDoubleFloat, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ fsd(FA0, Address(A0, 1 * sizeof(double)));
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedStoreDoubleFloat, test) {
EXPECT_DISASSEMBLY(
" a508 fsd fa0, 8(a0)\n"
" 8082 ret\n");
double* data = reinterpret_cast<double*>(malloc(3 * sizeof(double)));
data[0] = 1.7;
data[1] = 2.8;
data[2] = 3.9;
CallD(test->entry(), reinterpret_cast<intx_t>(data), 4.2);
EXPECT_EQ(4.2, data[1]);
}
#endif
#if XLEN == 32
ASSEMBLER_TEST_GENERATE(CompressedJumpAndLink, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
Label label1, label2;
__ mv(T3, RA);
__ jal(&label1, Assembler::kNearJump); // Forward.
__ sub(A0, T0, T1);
__ mv(RA, T3);
__ ret();
__ trap();
__ Bind(&label2);
__ mv(T5, RA);
__ li(T1, 7);
__ jr(T5);
__ trap();
__ Bind(&label1);
__ mv(T4, RA);
__ li(T0, 4);
__ jal(&label2, Assembler::kNearJump); // Backward.
__ mv(RA, T4);
__ jr(T4);
__ trap();
}
ASSEMBLER_TEST_RUN(CompressedJumpAndLink, test) {
EXPECT_DISASSEMBLY(
" 8e06 mv t3, ra\n"
" 2811 jal +20\n"
"40628533 sub a0, t0, t1\n"
" 80f2 mv ra, t3\n"
" 8082 ret\n"
" 0000 trap\n"
" 8f06 mv t5, ra\n"
" 431d li t1, 7\n"
" 8f02 jr t5\n"
" 0000 trap\n"
" 8e86 mv t4, ra\n"
" 4291 li t0, 4\n"
" 3fd5 jal -12\n"
" 80f6 mv ra, t4\n"
" 8e82 jr t4\n"
" 0000 trap\n");
EXPECT_EQ(-3, Call(test->entry()));
}
#endif
ASSEMBLER_TEST_GENERATE(CompressedJump, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
Label label1, label2;
__ j(&label1, Assembler::kNearJump); // Forward.
__ trap();
__ Bind(&label2);
__ li(T1, 7);
__ sub(A0, T0, T1);
__ ret();
__ Bind(&label1);
__ li(T0, 4);
__ j(&label2, Assembler::kNearJump); // Backward.
__ trap();
}
ASSEMBLER_TEST_RUN(CompressedJump, test) {
EXPECT_DISASSEMBLY(
" a031 j +12\n"
" 0000 trap\n"
" 431d li t1, 7\n"
"40628533 sub a0, t0, t1\n"
" 8082 ret\n"
" 4291 li t0, 4\n"
" bfdd j -10\n"
" 0000 trap\n");
EXPECT_EQ(-3, Call(test->entry()));
}
static int CompressedJumpAndLinkRegister_label1 = 0;
static int CompressedJumpAndLinkRegister_label2 = 0;
ASSEMBLER_TEST_GENERATE(CompressedJumpAndLinkRegister, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
Label label1, label2;
__ mv(T3, RA);
__ jalr(A1); // Forward.
__ sub(A0, T0, T1);
__ jr(T3);
__ trap();
__ Bind(&label2);
__ mv(T5, RA);
__ li(T1, 7);
__ jr(T5);
__ trap();
__ Bind(&label1);
__ mv(T4, RA);
__ li(T0, 4);
__ jalr(A2); // Backward.
__ jr(T4);
__ trap();
CompressedJumpAndLinkRegister_label1 = label1.Position();
CompressedJumpAndLinkRegister_label2 = label2.Position();
}
ASSEMBLER_TEST_RUN(CompressedJumpAndLinkRegister, test) {
EXPECT_DISASSEMBLY(
" 8e06 mv t3, ra\n"
" 9582 jalr a1\n"
"40628533 sub a0, t0, t1\n"
" 8e02 jr t3\n"
" 0000 trap\n"
" 8f06 mv t5, ra\n"
" 431d li t1, 7\n"
" 8f02 jr t5\n"
" 0000 trap\n"
" 8e86 mv t4, ra\n"
" 4291 li t0, 4\n"
" 9602 jalr a2\n"
" 8e82 jr t4\n"
" 0000 trap\n");
EXPECT_EQ(-3,
Call(test->entry(), 0,
static_cast<intx_t>(test->entry() +
CompressedJumpAndLinkRegister_label1),
static_cast<intx_t>(test->entry() +
CompressedJumpAndLinkRegister_label2)));
}
static int CompressedJumpRegister_label = 0;
ASSEMBLER_TEST_GENERATE(CompressedJumpRegister, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
Label label;
__ jr(A1);
__ trap();
__ Bind(&label);
__ li(A0, 42);
__ ret();
CompressedJumpRegister_label = label.Position();
}
ASSEMBLER_TEST_RUN(CompressedJumpRegister, test) {
EXPECT_DISASSEMBLY(
" 8582 jr a1\n"
" 0000 trap\n"
"02a00513 li a0, 42\n"
" 8082 ret\n");
EXPECT_EQ(42, Call(test->entry(), 0,
static_cast<intx_t>(test->entry() +
CompressedJumpRegister_label)));
}
ASSEMBLER_TEST_GENERATE(CompressedBranchEqualZero, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
Label label;
__ beqz(A0, &label, Assembler::kNearJump);
__ li(A0, 3);
__ ret();
__ Bind(&label);
__ li(A0, 4);
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedBranchEqualZero, test) {
EXPECT_DISASSEMBLY(
" c119 beqz a0, +6\n"
" 450d li a0, 3\n"
" 8082 ret\n"
" 4511 li a0, 4\n"
" 8082 ret\n");
EXPECT_EQ(3, Call(test->entry(), -42));
EXPECT_EQ(4, Call(test->entry(), 0));
EXPECT_EQ(3, Call(test->entry(), 42));
}
ASSEMBLER_TEST_GENERATE(CompressedBranchNotEqualZero, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
Label label;
__ bnez(A0, &label, Assembler::kNearJump);
__ li(A0, 3);
__ ret();
__ Bind(&label);
__ li(A0, 4);
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedBranchNotEqualZero, test) {
EXPECT_DISASSEMBLY(
" e119 bnez a0, +6\n"
" 450d li a0, 3\n"
" 8082 ret\n"
" 4511 li a0, 4\n"
" 8082 ret\n");
EXPECT_EQ(4, Call(test->entry(), -42));
EXPECT_EQ(3, Call(test->entry(), 0));
EXPECT_EQ(4, Call(test->entry(), 42));
}
ASSEMBLER_TEST_GENERATE(CompressedLoadImmediate, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ li(A0, -7);
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedLoadImmediate, test) {
EXPECT_DISASSEMBLY(
" 5565 li a0, -7\n"
" 8082 ret\n");
EXPECT_EQ(-7, Call(test->entry()));
}
ASSEMBLER_TEST_GENERATE(CompressedLoadUpperImmediate, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ lui(A0, 7 << 12);
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedLoadUpperImmediate, test) {
EXPECT_DISASSEMBLY(
" 651d lui a0, 28672\n"
" 8082 ret\n");
EXPECT_EQ(7 << 12, Call(test->entry()));
}
ASSEMBLER_TEST_GENERATE(CompressedAddImmediate, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ addi(A0, A0, 19);
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedAddImmediate, test) {
EXPECT_DISASSEMBLY(
" 054d addi a0, a0, 19\n"
" 8082 ret\n");
EXPECT_EQ(42, Call(test->entry(), 23));
}
#if XLEN == 64
ASSEMBLER_TEST_GENERATE(CompressedAddImmediateWord, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ addiw(A0, A0, 19);
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedAddImmediateWord, test) {
EXPECT_DISASSEMBLY(
" 254d addiw a0, a0, 19\n"
" 8082 ret\n");
EXPECT_EQ(19, Call(test->entry(), 0xFFFFFFFF00000000));
EXPECT_EQ(-237, Call(test->entry(), 0x00000000FFFFFF00));
}
#endif
ASSEMBLER_TEST_GENERATE(CompressedAddImmediateSP16, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ addi(SP, SP, -128);
__ addi(SP, SP, +128);
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedAddImmediateSP16, test) {
EXPECT_DISASSEMBLY(
" 7119 addi sp, sp, -128\n"
" 6109 addi sp, sp, 128\n"
" 8082 ret\n");
EXPECT_EQ(0, Call(test->entry(), 0));
}
ASSEMBLER_TEST_GENERATE(CompressedAddImmediateSP4N, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ addi(A1, SP, 36);
__ sub(A0, A1, SP);
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedAddImmediateSP4N, test) {
EXPECT_DISASSEMBLY(
" 104c addi a1, sp, 36\n"
"40258533 sub a0, a1, sp\n"
" 8082 ret\n");
EXPECT_EQ(36, Call(test->entry()));
}
ASSEMBLER_TEST_GENERATE(CompressedShiftLeftLogicalImmediate, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ slli(A0, A0, 3);
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedShiftLeftLogicalImmediate, test) {
EXPECT_DISASSEMBLY(
" 050e slli a0, a0, 3\n"
" 8082 ret\n");
EXPECT_EQ(0, Call(test->entry(), 0));
EXPECT_EQ(336, Call(test->entry(), 42));
EXPECT_EQ(15872, Call(test->entry(), 1984));
EXPECT_EQ(-336, Call(test->entry(), -42));
EXPECT_EQ(-15872, Call(test->entry(), -1984));
}
ASSEMBLER_TEST_GENERATE(CompressedShiftRightLogicalImmediate, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ srli(A0, A0, 3);
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedShiftRightLogicalImmediate, test) {
EXPECT_DISASSEMBLY(
" 810d srli a0, a0, 3\n"
" 8082 ret\n");
EXPECT_EQ(0, Call(test->entry(), 0));
EXPECT_EQ(5, Call(test->entry(), 42));
EXPECT_EQ(248, Call(test->entry(), 1984));
EXPECT_EQ(static_cast<intx_t>(static_cast<uintx_t>(-42) >> 3),
Call(test->entry(), -42));
EXPECT_EQ(static_cast<intx_t>(static_cast<uintx_t>(-1984) >> 3),
Call(test->entry(), -1984));
}
ASSEMBLER_TEST_GENERATE(CompressedShiftRightArithmeticImmediate, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ srai(A0, A0, 3);
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedShiftRightArithmeticImmediate, test) {
EXPECT_DISASSEMBLY(
" 850d srai a0, a0, 3\n"
" 8082 ret\n");
EXPECT_EQ(0, Call(test->entry(), 0));
EXPECT_EQ(5, Call(test->entry(), 42));
EXPECT_EQ(248, Call(test->entry(), 1984));
EXPECT_EQ(-6, Call(test->entry(), -42));
EXPECT_EQ(-248, Call(test->entry(), -1984));
}
ASSEMBLER_TEST_GENERATE(CompressedAndImmediate, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ andi(A0, A0, 6);
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedAndImmediate, test) {
EXPECT_DISASSEMBLY(
" 8919 andi a0, a0, 6\n"
" 8082 ret\n");
EXPECT_EQ(0, Call(test->entry(), 0));
EXPECT_EQ(2, Call(test->entry(), 43));
EXPECT_EQ(0, Call(test->entry(), 1984));
EXPECT_EQ(6, Call(test->entry(), -42));
EXPECT_EQ(0, Call(test->entry(), -1984));
}
ASSEMBLER_TEST_GENERATE(CompressedAndImmediate2, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ andi(A0, A0, -6);
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedAndImmediate2, test) {
EXPECT_DISASSEMBLY(
" 9969 andi a0, a0, -6\n"
" 8082 ret\n");
EXPECT_EQ(0, Call(test->entry(), 0));
EXPECT_EQ(42, Call(test->entry(), 43));
EXPECT_EQ(1984, Call(test->entry(), 1984));
EXPECT_EQ(-46, Call(test->entry(), -42));
EXPECT_EQ(-1984, Call(test->entry(), -1984));
}
ASSEMBLER_TEST_GENERATE(CompressedMove, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ mv(A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedMove, test) {
EXPECT_DISASSEMBLY(
" 852e mv a0, a1\n"
" 8082 ret\n");
EXPECT_EQ(42, Call(test->entry(), 0, 42));
}
ASSEMBLER_TEST_GENERATE(CompressedAdd, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ add(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedAdd, test) {
EXPECT_DISASSEMBLY(
" 952e add a0, a0, a1\n"
" 8082 ret\n");
EXPECT_EQ(24, Call(test->entry(), 7, 17));
EXPECT_EQ(-10, Call(test->entry(), 7, -17));
EXPECT_EQ(10, Call(test->entry(), -7, 17));
EXPECT_EQ(-24, Call(test->entry(), -7, -17));
EXPECT_EQ(24, Call(test->entry(), 17, 7));
EXPECT_EQ(10, Call(test->entry(), 17, -7));
EXPECT_EQ(-10, Call(test->entry(), -17, 7));
EXPECT_EQ(-24, Call(test->entry(), -17, -7));
}
ASSEMBLER_TEST_GENERATE(CompressedAnd, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ and_(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedAnd, test) {
EXPECT_DISASSEMBLY(
" 8d6d and a0, a0, a1\n"
" 8082 ret\n");
EXPECT_EQ(1, Call(test->entry(), 7, 17));
EXPECT_EQ(7, Call(test->entry(), 7, -17));
EXPECT_EQ(17, Call(test->entry(), -7, 17));
EXPECT_EQ(-23, Call(test->entry(), -7, -17));
EXPECT_EQ(1, Call(test->entry(), 17, 7));
EXPECT_EQ(17, Call(test->entry(), 17, -7));
EXPECT_EQ(7, Call(test->entry(), -17, 7));
EXPECT_EQ(-23, Call(test->entry(), -17, -7));
}
ASSEMBLER_TEST_GENERATE(CompressedOr, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ or_(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedOr, test) {
EXPECT_DISASSEMBLY(
" 8d4d or a0, a0, a1\n"
" 8082 ret\n");
EXPECT_EQ(23, Call(test->entry(), 7, 17));
EXPECT_EQ(-17, Call(test->entry(), 7, -17));
EXPECT_EQ(-7, Call(test->entry(), -7, 17));
EXPECT_EQ(-1, Call(test->entry(), -7, -17));
EXPECT_EQ(23, Call(test->entry(), 17, 7));
EXPECT_EQ(-7, Call(test->entry(), 17, -7));
EXPECT_EQ(-17, Call(test->entry(), -17, 7));
EXPECT_EQ(-1, Call(test->entry(), -17, -7));
}
ASSEMBLER_TEST_GENERATE(CompressedXor, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ xor_(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedXor, test) {
EXPECT_DISASSEMBLY(
" 8d2d xor a0, a0, a1\n"
" 8082 ret\n");
EXPECT_EQ(22, Call(test->entry(), 7, 17));
EXPECT_EQ(-24, Call(test->entry(), 7, -17));
EXPECT_EQ(-24, Call(test->entry(), -7, 17));
EXPECT_EQ(22, Call(test->entry(), -7, -17));
EXPECT_EQ(22, Call(test->entry(), 17, 7));
EXPECT_EQ(-24, Call(test->entry(), 17, -7));
EXPECT_EQ(-24, Call(test->entry(), -17, 7));
EXPECT_EQ(22, Call(test->entry(), -17, -7));
}
ASSEMBLER_TEST_GENERATE(CompressedSubtract, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ sub(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedSubtract, test) {
EXPECT_DISASSEMBLY(
" 8d0d sub a0, a0, a1\n"
" 8082 ret\n");
EXPECT_EQ(-10, Call(test->entry(), 7, 17));
EXPECT_EQ(24, Call(test->entry(), 7, -17));
EXPECT_EQ(-24, Call(test->entry(), -7, 17));
EXPECT_EQ(10, Call(test->entry(), -7, -17));
EXPECT_EQ(10, Call(test->entry(), 17, 7));
EXPECT_EQ(24, Call(test->entry(), 17, -7));
EXPECT_EQ(-24, Call(test->entry(), -17, 7));
EXPECT_EQ(-10, Call(test->entry(), -17, -7));
}
#if XLEN >= 64
ASSEMBLER_TEST_GENERATE(CompressedAddWord, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ addw(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedAddWord, test) {
EXPECT_DISASSEMBLY(
" 9d2d addw a0, a0, a1\n"
" 8082 ret\n");
EXPECT_EQ(24, Call(test->entry(), 7, 17));
EXPECT_EQ(-10, Call(test->entry(), 7, -17));
EXPECT_EQ(10, Call(test->entry(), -7, 17));
EXPECT_EQ(-24, Call(test->entry(), -7, -17));
EXPECT_EQ(24, Call(test->entry(), 17, 7));
EXPECT_EQ(10, Call(test->entry(), 17, -7));
EXPECT_EQ(-10, Call(test->entry(), -17, 7));
EXPECT_EQ(-24, Call(test->entry(), -17, -7));
EXPECT_EQ(3, Call(test->entry(), 0x200000002, 0x100000001));
}
ASSEMBLER_TEST_GENERATE(CompressedSubtractWord, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ subw(A0, A0, A1);
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedSubtractWord, test) {
EXPECT_DISASSEMBLY(
" 9d0d subw a0, a0, a1\n"
" 8082 ret\n");
EXPECT_EQ(-10, Call(test->entry(), 7, 17));
EXPECT_EQ(24, Call(test->entry(), 7, -17));
EXPECT_EQ(-24, Call(test->entry(), -7, 17));
EXPECT_EQ(10, Call(test->entry(), -7, -17));
EXPECT_EQ(10, Call(test->entry(), 17, 7));
EXPECT_EQ(24, Call(test->entry(), 17, -7));
EXPECT_EQ(-24, Call(test->entry(), -17, 7));
EXPECT_EQ(-10, Call(test->entry(), -17, -7));
EXPECT_EQ(1, Call(test->entry(), 0x200000002, 0x100000001));
}
#endif
ASSEMBLER_TEST_GENERATE(CompressedNop, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ nop();
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedNop, test) {
EXPECT_DISASSEMBLY(
" 0001 nop\n"
" 8082 ret\n");
EXPECT_EQ(123, Call(test->entry(), 123));
}
ASSEMBLER_TEST_GENERATE(CompressedEnvironmentBreak, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ ebreak();
__ ret();
}
ASSEMBLER_TEST_RUN(CompressedEnvironmentBreak, test) {
EXPECT_DISASSEMBLY(
" 9002 ebreak\n"
" 8082 ret\n");
// Not running: would trap.
}
ASSEMBLER_TEST_GENERATE(LoadImmediate_MaxInt32, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ LoadImmediate(A0, kMaxInt32);
__ ret();
}
ASSEMBLER_TEST_RUN(LoadImmediate_MaxInt32, test) {
#if XLEN == 32
EXPECT_DISASSEMBLY(
"80000537 lui a0, -2147483648\n"
" 157d addi a0, a0, -1\n"
" 8082 ret\n");
#elif XLEN == 64
EXPECT_DISASSEMBLY(
"80000537 lui a0, -2147483648\n"
" 357d addiw a0, a0, -1\n"
" 8082 ret\n");
#endif
EXPECT_EQ(kMaxInt32, Call(test->entry()));
}
ASSEMBLER_TEST_GENERATE(LoadImmediate_MinInt32, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ LoadImmediate(A0, kMinInt32);
__ ret();
}
ASSEMBLER_TEST_RUN(LoadImmediate_MinInt32, test) {
EXPECT_DISASSEMBLY(
"80000537 lui a0, -2147483648\n"
" 8082 ret\n");
EXPECT_EQ(kMinInt32, Call(test->entry()));
}
#if XLEN >= 64
ASSEMBLER_TEST_GENERATE(LoadImmediate_MinInt64, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ LoadImmediate(A0, kMinInt64);
__ ret();
}
ASSEMBLER_TEST_RUN(LoadImmediate_MinInt64, test) {
EXPECT_DISASSEMBLY(
"f8000537 lui a0, -134217728\n"
" 0532 slli a0, a0, 12\n"
" 0532 slli a0, a0, 12\n"
" 0532 slli a0, a0, 12\n"
" 8082 ret\n");
EXPECT_EQ(kMinInt64, Call(test->entry()));
}
ASSEMBLER_TEST_GENERATE(LoadImmediate_Large, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
__ LoadImmediate(A0, 0xABCDABCDABCDABCD);
__ ret();
}
ASSEMBLER_TEST_RUN(LoadImmediate_Large, test) {
EXPECT_DISASSEMBLY(
"fabce537 lui a0, -88285184\n"
"abd5051b addiw a0, a0, -1347\n"
" 0532 slli a0, a0, 12\n"
"dac50513 addi a0, a0, -596\n"
" 0532 slli a0, a0, 12\n"
"cdb50513 addi a0, a0, -805\n"
" 0532 slli a0, a0, 12\n"
"bcd50513 addi a0, a0, -1075\n"
" 8082 ret\n");
EXPECT_EQ(static_cast<int64_t>(0xABCDABCDABCDABCD), Call(test->entry()));
}
#endif
ASSEMBLER_TEST_GENERATE(AddImmediateBranchOverflow, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
Label overflow;
__ AddImmediateBranchOverflow(A0, A0, 2, &overflow);
__ ret();
__ Bind(&overflow);
__ li(A0, 0);
__ ret();
}
ASSEMBLER_TEST_RUN(AddImmediateBranchOverflow, test) {
EXPECT_DISASSEMBLY(
" 872a mv tmp2, a0\n"
" 0509 addi a0, a0, 2\n"
"00e54363 blt a0, tmp2, +6\n"
" 8082 ret\n"
" 4501 li a0, 0\n"
" 8082 ret\n");
EXPECT_EQ(kMaxIntX - 1, Call(test->entry(), kMaxIntX - 3));
EXPECT_EQ(kMaxIntX, Call(test->entry(), kMaxIntX - 2));
EXPECT_EQ(0, Call(test->entry(), kMaxIntX - 1));
EXPECT_EQ(0, Call(test->entry(), kMaxIntX));
}
ASSEMBLER_TEST_GENERATE(AddBranchOverflow_NonDestructive, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
Label overflow;
__ AddBranchOverflow(A0, A1, A2, &overflow);
__ ret();
__ Bind(&overflow);
__ li(A0, 0);
__ ret();
}
ASSEMBLER_TEST_RUN(AddBranchOverflow_NonDestructive, test) {
EXPECT_DISASSEMBLY(
"00c58533 add a0, a1, a2\n"
"00062693 slti tmp, a2, 0\n"
"00b52733 slt tmp2, a0, a1\n"
"00e69363 bne tmp, tmp2, +6\n"
" 8082 ret\n"
" 4501 li a0, 0\n"
" 8082 ret\n");
EXPECT_EQ(kMaxIntX - 1, Call(test->entry(), 42, kMaxIntX, -1));
EXPECT_EQ(kMaxIntX, Call(test->entry(), 42, kMaxIntX, 0));
EXPECT_EQ(0, Call(test->entry(), 42, kMaxIntX, 1));
EXPECT_EQ(0, Call(test->entry(), 42, kMinIntX, -1));
EXPECT_EQ(kMinIntX + 1, Call(test->entry(), 42, kMinIntX, 1));
EXPECT_EQ(kMinIntX, Call(test->entry(), 42, kMinIntX, 0));
}
ASSEMBLER_TEST_GENERATE(AddBranchOverflow_Destructive, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
Label overflow;
__ AddBranchOverflow(A0, A1, A0, &overflow);
__ ret();
__ Bind(&overflow);
__ li(A0, 0);
__ ret();
}
ASSEMBLER_TEST_RUN(AddBranchOverflow_Destructive, test) {
EXPECT_DISASSEMBLY(
"00052693 slti tmp, a0, 0\n"
" 952e add a0, a0, a1\n"
"00b52733 slt tmp2, a0, a1\n"
"00e69363 bne tmp, tmp2, +6\n"
" 8082 ret\n"
" 4501 li a0, 0\n"
" 8082 ret\n");
EXPECT_EQ(kMaxIntX - 1, Call(test->entry(), kMaxIntX, -1));
EXPECT_EQ(kMaxIntX, Call(test->entry(), kMaxIntX, 0));
EXPECT_EQ(0, Call(test->entry(), kMaxIntX, 1));
EXPECT_EQ(0, Call(test->entry(), kMinIntX, -1));
EXPECT_EQ(kMinIntX + 1, Call(test->entry(), kMinIntX, 1));
EXPECT_EQ(kMinIntX, Call(test->entry(), kMinIntX, 0));
}
ASSEMBLER_TEST_GENERATE(SubtractImmediateBranchOverflow, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
Label overflow;
__ SubtractImmediateBranchOverflow(A0, A0, 2, &overflow);
__ ret();
__ Bind(&overflow);
__ li(A0, 0);
__ ret();
}
ASSEMBLER_TEST_RUN(SubtractImmediateBranchOverflow, test) {
EXPECT_DISASSEMBLY(
" 872a mv tmp2, a0\n"
" 1579 addi a0, a0, -2\n"
"00a74363 blt tmp2, a0, +6\n"
" 8082 ret\n"
" 4501 li a0, 0\n"
" 8082 ret\n");
EXPECT_EQ(kMinIntX + 1, Call(test->entry(), kMinIntX + 3));
EXPECT_EQ(kMinIntX, Call(test->entry(), kMinIntX + 2));
EXPECT_EQ(0, Call(test->entry(), kMinIntX + 1));
EXPECT_EQ(0, Call(test->entry(), kMinIntX));
}
ASSEMBLER_TEST_GENERATE(SubtractBranchOverflow_NonDestructive, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
Label overflow;
__ SubtractBranchOverflow(A0, A1, A2, &overflow);
__ ret();
__ Bind(&overflow);
__ li(A0, 0);
__ ret();
}
ASSEMBLER_TEST_RUN(SubtractBranchOverflow_NonDestructive, test) {
EXPECT_DISASSEMBLY(
"40c58533 sub a0, a1, a2\n"
"00062693 slti tmp, a2, 0\n"
"00a5a733 slt tmp2, a1, a0\n"
"00e69363 bne tmp, tmp2, +6\n"
" 8082 ret\n"
" 4501 li a0, 0\n"
" 8082 ret\n");
EXPECT_EQ(kMaxIntX - 1, Call(test->entry(), 42, kMaxIntX, 1));
EXPECT_EQ(kMaxIntX, Call(test->entry(), 42, kMaxIntX, 0));
EXPECT_EQ(0, Call(test->entry(), 42, kMaxIntX, -1));
EXPECT_EQ(0, Call(test->entry(), 42, kMinIntX, 1));
EXPECT_EQ(kMinIntX + 1, Call(test->entry(), 42, kMinIntX, -1));
EXPECT_EQ(kMinIntX, Call(test->entry(), 42, kMinIntX, 0));
}
ASSEMBLER_TEST_GENERATE(SubtractBranchOverflow_Destructive, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
Label overflow;
__ SubtractBranchOverflow(A0, A0, A1, &overflow);
__ ret();
__ Bind(&overflow);
__ li(A0, 0);
__ ret();
}
ASSEMBLER_TEST_RUN(SubtractBranchOverflow_Destructive, test) {
EXPECT_DISASSEMBLY(
"00052693 slti tmp, a0, 0\n"
" 8d0d sub a0, a0, a1\n"
"00b52733 slt tmp2, a0, a1\n"
"00e69363 bne tmp, tmp2, +6\n"
" 8082 ret\n"
" 4501 li a0, 0\n"
" 8082 ret\n");
EXPECT_EQ(kMaxIntX - 1, Call(test->entry(), kMaxIntX, 1));
EXPECT_EQ(kMaxIntX, Call(test->entry(), kMaxIntX, 0));
EXPECT_EQ(0, Call(test->entry(), kMaxIntX, -1));
EXPECT_EQ(0, Call(test->entry(), kMinIntX, 1));
EXPECT_EQ(kMinIntX + 1, Call(test->entry(), kMinIntX, -1));
EXPECT_EQ(kMinIntX, Call(test->entry(), kMinIntX, 0));
}
ASSEMBLER_TEST_GENERATE(MultiplyImmediateBranchOverflow, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
Label overflow;
__ MultiplyImmediateBranchOverflow(A0, A0, 2, &overflow);
__ ret();
__ Bind(&overflow);
__ li(A0, 0);
__ ret();
}
ASSEMBLER_TEST_RUN(MultiplyImmediateBranchOverflow, test) {
#if XLEN == 64
EXPECT_DISASSEMBLY(
" 4709 li tmp2, 2\n"
"02e516b3 mulh tmp, a0, tmp2\n"
"02e50533 mul a0, a0, tmp2\n"
"43f55713 srai tmp2, a0, 0x3f\n"
"00e69363 bne tmp, tmp2, +6\n"
" 8082 ret\n"
" 4501 li a0, 0\n"
" 8082 ret\n");
#elif XLEN == 32
EXPECT_DISASSEMBLY(
" 4709 li tmp2, 2\n"
"02e516b3 mulh tmp, a0, tmp2\n"
"02e50533 mul a0, a0, tmp2\n"
"41f55713 srai tmp2, a0, 0x1f\n"
"00e69363 bne tmp, tmp2, +6\n"
" 8082 ret\n"
" 4501 li a0, 0\n"
" 8082 ret\n");
#endif
EXPECT_EQ(0, Call(test->entry(), kMinIntX));
EXPECT_EQ(0, Call(test->entry(), kMaxIntX));
EXPECT_EQ(-2, Call(test->entry(), -1));
EXPECT_EQ(2, Call(test->entry(), 1));
EXPECT_EQ(kMinIntX, Call(test->entry(), kMinIntX / 2));
EXPECT_EQ(kMaxIntX - 1, Call(test->entry(), (kMaxIntX - 1) / 2));
}
ASSEMBLER_TEST_GENERATE(MultiplyBranchOverflow_NonDestructive, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
Label overflow;
__ MultiplyBranchOverflow(A0, A1, A2, &overflow);
__ ret();
__ Bind(&overflow);
__ li(A0, 42);
__ ret();
}
ASSEMBLER_TEST_RUN(MultiplyBranchOverflow_NonDestructive, test) {
#if XLEN == 64
EXPECT_DISASSEMBLY(
"02c596b3 mulh tmp, a1, a2\n"
"02c58533 mul a0, a1, a2\n"
"43f55713 srai tmp2, a0, 0x3f\n"
"00e69363 bne tmp, tmp2, +6\n"
" 8082 ret\n"
"02a00513 li a0, 42\n"
" 8082 ret\n");
#elif XLEN == 32
EXPECT_DISASSEMBLY(
"02c596b3 mulh tmp, a1, a2\n"
"02c58533 mul a0, a1, a2\n"
"41f55713 srai tmp2, a0, 0x1f\n"
"00e69363 bne tmp, tmp2, +6\n"
" 8082 ret\n"
"02a00513 li a0, 42\n"
" 8082 ret\n");
#endif
EXPECT_EQ(42, Call(test->entry(), 42, kMaxIntX, -2));
EXPECT_EQ(-kMaxIntX, Call(test->entry(), 42, kMaxIntX, -1));
EXPECT_EQ(0, Call(test->entry(), 42, kMaxIntX, 0));
EXPECT_EQ(kMaxIntX, Call(test->entry(), 42, kMaxIntX, 1));
EXPECT_EQ(42, Call(test->entry(), 42, kMaxIntX, 2));
EXPECT_EQ(42, Call(test->entry(), 42, kMinIntX, -2));
EXPECT_EQ(42, Call(test->entry(), 42, kMinIntX, -1));
EXPECT_EQ(0, Call(test->entry(), 42, kMinIntX, 0));
EXPECT_EQ(kMinIntX, Call(test->entry(), 42, kMinIntX, 1));
EXPECT_EQ(42, Call(test->entry(), 42, kMinIntX, 2));
}
ASSEMBLER_TEST_GENERATE(MultiplyBranchOverflow_Destructive, assembler) {
FLAG_use_compressed_instructions = true;
__ SetExtensions(RV_GC);
Label overflow;
__ MultiplyBranchOverflow(A0, A0, A1, &overflow);
__ ret();
__ Bind(&overflow);
__ li(A0, 42);
__ ret();
}
ASSEMBLER_TEST_RUN(MultiplyBranchOverflow_Destructive, test) {
#if XLEN == 64
EXPECT_DISASSEMBLY(
"02b516b3 mulh tmp, a0, a1\n"
"02b50533 mul a0, a0, a1\n"
"43f55713 srai tmp2, a0, 0x3f\n"
"00e69363 bne tmp, tmp2, +6\n"
" 8082 ret\n"
"02a00513 li a0, 42\n"
" 8082 ret\n");
#elif XLEN == 32
EXPECT_DISASSEMBLY(
"02b516b3 mulh tmp, a0, a1\n"
"02b50533 mul a0, a0, a1\n"
"41f55713 srai tmp2, a0, 0x1f\n"
"00e69363 bne tmp, tmp2, +6\n"
" 8082 ret\n"
"02a00513 li a0, 42\n"
" 8082 ret\n");
#endif
EXPECT_EQ(42, Call(test->entry(), kMaxIntX, -2));
EXPECT_EQ(-kMaxIntX, Call(test->entry(), kMaxIntX, -1));
EXPECT_EQ(0, Call(test->entry(), kMaxIntX, 0));
EXPECT_EQ(kMaxIntX, Call(test->entry(), kMaxIntX, 1));
EXPECT_EQ(42, Call(test->entry(), kMaxIntX, 2));
EXPECT_EQ(42, Call(test->entry(), kMinIntX, -2));
EXPECT_EQ(42, Call(test->entry(), kMinIntX, -1));
EXPECT_EQ(0, Call(test->entry(), kMinIntX, 0));
EXPECT_EQ(kMinIntX, Call(test->entry(), kMinIntX, 1));
EXPECT_EQ(42, Call(test->entry(), kMinIntX, 2));
}
#define TEST_ENCODING(type, name) \
VM_UNIT_TEST_CASE(Encoding##name) { \
for (intptr_t v = -(1 << 21); v <= (1 << 21); v++) { \
type value = static_cast<type>(v); \
if (!Is##name(value)) continue; \
int32_t encoded = Encode##name(value); \
type decoded = Decode##name(encoded); \
EXPECT_EQ(value, decoded); \
} \
}
TEST_ENCODING(Register, Rd)
TEST_ENCODING(Register, Rs1)
TEST_ENCODING(Register, Rs2)
TEST_ENCODING(FRegister, FRd)
TEST_ENCODING(FRegister, FRs1)
TEST_ENCODING(FRegister, FRs2)
TEST_ENCODING(FRegister, FRs3)
TEST_ENCODING(Funct2, Funct2)
TEST_ENCODING(Funct3, Funct3)
TEST_ENCODING(Funct5, Funct5)
TEST_ENCODING(Funct7, Funct7)
TEST_ENCODING(Funct12, Funct12)
TEST_ENCODING(RoundingMode, RoundingMode)
TEST_ENCODING(intptr_t, BTypeImm)
TEST_ENCODING(intptr_t, JTypeImm)
TEST_ENCODING(intptr_t, ITypeImm)
TEST_ENCODING(intptr_t, STypeImm)
TEST_ENCODING(intptr_t, UTypeImm)
TEST_ENCODING(Register, CRd)
TEST_ENCODING(Register, CRs1)
TEST_ENCODING(Register, CRs2)
TEST_ENCODING(Register, CRdp)
TEST_ENCODING(Register, CRs1p)
TEST_ENCODING(Register, CRs2p)
TEST_ENCODING(FRegister, CFRd)
TEST_ENCODING(FRegister, CFRs1)
TEST_ENCODING(FRegister, CFRs2)
TEST_ENCODING(FRegister, CFRdp)
TEST_ENCODING(FRegister, CFRs1p)
TEST_ENCODING(FRegister, CFRs2p)
TEST_ENCODING(intptr_t, CSPLoad4Imm)
TEST_ENCODING(intptr_t, CSPLoad8Imm)
TEST_ENCODING(intptr_t, CSPStore4Imm)
TEST_ENCODING(intptr_t, CSPStore8Imm)
TEST_ENCODING(intptr_t, CMem4Imm)
TEST_ENCODING(intptr_t, CMem8Imm)
TEST_ENCODING(intptr_t, CJImm)
TEST_ENCODING(intptr_t, CBImm)
TEST_ENCODING(intptr_t, CIImm)
TEST_ENCODING(intptr_t, CUImm)
TEST_ENCODING(intptr_t, CI16Imm)
TEST_ENCODING(intptr_t, CI4SPNImm)
#undef TEST_ENCODING
} // namespace compiler
} // namespace dart
#endif // defined(TARGET_ARCH_RISCV)