mirror of
git://repo.or.cz/tinycc.git
synced 2026-06-17 15:44:18 +08:00
tcctest: restore & combine
Revert 199369bb17
- generating test.ref with tcc makes little sense.
- combine riscv_asm & conversion tests into only two files.
(too many files are bad ...)
This commit is contained in:
parent
6daf1617ef
commit
44977b0de8
2
Makefile
2
Makefile
@ -336,7 +336,7 @@ FORCE:
|
|||||||
# some versions of gnu-make do not recognize 'command' as a shell builtin
|
# some versions of gnu-make do not recognize 'command' as a shell builtin
|
||||||
WHICH = sh -c 'command -v $1'
|
WHICH = sh -c 'command -v $1'
|
||||||
|
|
||||||
run-if = $(if $(shell $(call WHICH,$1)),$S $1 $2,@echo "(skipping $@ - no $1)")
|
run-if = $(if $(shell $(call WHICH,$1x)),$S $1 $2,@true||echo "(skipping $@ - no $1)")
|
||||||
S = $(if $(findstring yes,$(SILENT)),@$(info * $@))
|
S = $(if $(findstring yes,$(SILENT)),@$(info * $@))
|
||||||
|
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
|
|||||||
2
tccelf.c
2
tccelf.c
@ -114,7 +114,7 @@ ST_FUNC void tccelf_new(TCCState *s)
|
|||||||
#ifndef ELF_OBJ_ONLY
|
#ifndef ELF_OBJ_ONLY
|
||||||
if (NULL == s->elfint && s1->output_type != TCC_OUTPUT_OBJ) {
|
if (NULL == s->elfint && s1->output_type != TCC_OUTPUT_OBJ) {
|
||||||
const char *p = CONFIG_TCC_ELFINTERP;
|
const char *p = CONFIG_TCC_ELFINTERP;
|
||||||
#ifdef TCC_TARGET_ARM
|
#if defined TCC_TARGET_ARM && defined CONFIG_TCC_ELFINTERP_ARMHF
|
||||||
if (s->float_abi == ARM_HARD_FLOAT)
|
if (s->float_abi == ARM_HARD_FLOAT)
|
||||||
p = CONFIG_TCC_ELFINTERP_ARMHF;
|
p = CONFIG_TCC_ELFINTERP_ARMHF;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -110,8 +110,8 @@ libtcc_test_mt$(EXESUF): libtcc_test_mt.c
|
|||||||
|
|
||||||
# test.ref - generate using cc
|
# test.ref - generate using cc
|
||||||
test.ref: tcctest.c
|
test.ref: tcctest.c
|
||||||
$(TCC) $(TCCFLAGS) -w -o tcctest.tcc$(EXESUF) $<
|
$(CC) -o tcctest.gcc$(EXESUF) $< $(CFLAGS) -w -O0 -std=gnu99 -fno-omit-frame-pointer
|
||||||
./tcctest.tcc$(EXESUF) > $@
|
./tcctest.gcc$(EXESUF) > $@
|
||||||
|
|
||||||
# auto test
|
# auto test
|
||||||
test1 test1b: tcctest.c test.ref
|
test1 test1b: tcctest.c test.ref
|
||||||
|
|||||||
@ -1175,7 +1175,7 @@ void char_short_test()
|
|||||||
var4 = 0x11223344aa998877ULL;
|
var4 = 0x11223344aa998877ULL;
|
||||||
printf("promote char/short assign VA %d %d\n", var3 = var1 + 1, var3 = var4 + 1);
|
printf("promote char/short assign VA %d %d\n", var3 = var1 + 1, var3 = var4 + 1);
|
||||||
printf("promote char/short cast VA %d %d\n", (signed char)(var1 + 1), (signed char)(var4 + 1));
|
printf("promote char/short cast VA %d %d\n", (signed char)(var1 + 1), (signed char)(var4 + 1));
|
||||||
#if !defined(__arm__)
|
#if !defined __arm__ && !defined __riscv
|
||||||
/* We can't really express GCC behaviour of return type promotion in
|
/* We can't really express GCC behaviour of return type promotion in
|
||||||
the presence of undefined behaviour (like __csf is). */
|
the presence of undefined behaviour (like __csf is). */
|
||||||
var1 = csf(unsigned char,0x89898989);
|
var1 = csf(unsigned char,0x89898989);
|
||||||
|
|||||||
@ -1,52 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
/* PROMOTE_RET test: verify char/short return values are properly
|
|
||||||
zero/sign-extended to 64-bit per the RISC-V integer calling convention.
|
|
||||||
Without PROMOTE_RET, upper bits of the return register may contain
|
|
||||||
garbage, causing incorrect results when assigned to a wider type. */
|
|
||||||
|
|
||||||
unsigned char get_uc(void) { return 0x80; }
|
|
||||||
signed char get_sc(void) { return 0x80; }
|
|
||||||
unsigned short get_us(void) { return 0x8000; }
|
|
||||||
signed short get_ss(void) { return 0x8000; }
|
|
||||||
|
|
||||||
/* Prevent inlining to force ABI-compliant calling. */
|
|
||||||
unsigned char (* volatile fp_uc)(void) = get_uc;
|
|
||||||
signed char (* volatile fp_sc)(void) = get_sc;
|
|
||||||
unsigned short (* volatile fp_us)(void) = get_us;
|
|
||||||
signed short (* volatile fp_ss)(void) = get_ss;
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
int ok = 1;
|
|
||||||
unsigned long long uc = fp_uc();
|
|
||||||
signed long long sc = fp_sc();
|
|
||||||
unsigned long long us = fp_us();
|
|
||||||
signed long long ss = fp_ss();
|
|
||||||
|
|
||||||
printf("uc=%llx sc=%llx us=%llx ss=%llx\n",
|
|
||||||
(unsigned long long)uc,
|
|
||||||
(unsigned long long)sc,
|
|
||||||
(unsigned long long)us,
|
|
||||||
(unsigned long long)ss);
|
|
||||||
|
|
||||||
if (uc != 0x80) {
|
|
||||||
printf("FAIL: uc not zero-extended\n");
|
|
||||||
ok = 0;
|
|
||||||
}
|
|
||||||
if (sc != 0xffffffffffffff80LL) {
|
|
||||||
printf("FAIL: sc not sign-extended\n");
|
|
||||||
ok = 0;
|
|
||||||
}
|
|
||||||
if (us != 0x8000) {
|
|
||||||
printf("FAIL: us not zero-extended\n");
|
|
||||||
ok = 0;
|
|
||||||
}
|
|
||||||
if (ss != 0xffffffffffff8000LL) {
|
|
||||||
printf("FAIL: ss not sign-extended\n");
|
|
||||||
ok = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("%s\n", ok ? "PASS" : "FAIL");
|
|
||||||
return ok ? 0 : 1;
|
|
||||||
}
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
uc=80 sc=ffffffffffffff80 us=8000 ss=ffffffffffff8000
|
|
||||||
PASS
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
/* gen_cvt_csti test: verify narrow-type conversions in expressions.
|
|
||||||
Without the fix, TCC's riscv64 backend could miss the conversion
|
|
||||||
step when promoting a narrow result back to int, producing wrong
|
|
||||||
values (e.g., treating a char as still 32-bit). */
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
int ok = 1;
|
|
||||||
int x = 0x12345678;
|
|
||||||
|
|
||||||
/* Cast to char then add 1 — result must be 8-bit. */
|
|
||||||
char c = (char)x + 1;
|
|
||||||
unsigned char uc = (unsigned char)x + 1;
|
|
||||||
short s = (short)x + 1;
|
|
||||||
unsigned short us = (unsigned short)x + 1;
|
|
||||||
|
|
||||||
printf("c=%x uc=%x s=%x us=%x\n",
|
|
||||||
(unsigned char)c, (unsigned)uc,
|
|
||||||
(unsigned short)s, (unsigned)us);
|
|
||||||
|
|
||||||
if (c != (char)0x78 + 1) {
|
|
||||||
printf("FAIL: char conversion\n");
|
|
||||||
ok = 0;
|
|
||||||
}
|
|
||||||
if (uc != (unsigned char)0x78 + 1) {
|
|
||||||
printf("FAIL: unsigned char conversion\n");
|
|
||||||
ok = 0;
|
|
||||||
}
|
|
||||||
if (s != (short)0x5678 + 1) {
|
|
||||||
printf("FAIL: short conversion\n");
|
|
||||||
ok = 0;
|
|
||||||
}
|
|
||||||
if (us != (unsigned short)0x5678 + 1) {
|
|
||||||
printf("FAIL: unsigned short conversion\n");
|
|
||||||
ok = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("%s\n", ok ? "PASS" : "FAIL");
|
|
||||||
return ok ? 0 : 1;
|
|
||||||
}
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
c=79 uc=79 s=5679 us=5679
|
|
||||||
PASS
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
/* gen_cvt_sxtw test: verify sign-extension from 32-bit int to 64-bit long long.
|
|
||||||
Without the fix, the riscv64 backend had an empty stub for gen_cvt_sxtw,
|
|
||||||
leaving upper 32 bits unmodified (containing whatever was in the register
|
|
||||||
before), so (long long)(int)x produced wrong results for negative values. */
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
int ok = 1;
|
|
||||||
int x = 0x80000000;
|
|
||||||
long long y = (long long)x;
|
|
||||||
|
|
||||||
printf("y=%llx\n", (unsigned long long)y);
|
|
||||||
|
|
||||||
if (y != 0xffffffff80000000LL) {
|
|
||||||
printf("FAIL: int→long long sign-extension\n");
|
|
||||||
ok = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Also test positive value. */
|
|
||||||
x = 0x40000000;
|
|
||||||
y = (long long)x;
|
|
||||||
printf("y=%llx\n", (unsigned long long)y);
|
|
||||||
|
|
||||||
if (y != 0x40000000LL) {
|
|
||||||
printf("FAIL: int→long long positive value\n");
|
|
||||||
ok = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Test via unsigned int to catch zero-extension vs sign-extension. */
|
|
||||||
unsigned int ux = 0x80000000;
|
|
||||||
long long uy = (long long)(int)ux;
|
|
||||||
printf("uy=%llx\n", (unsigned long long)uy);
|
|
||||||
|
|
||||||
if (uy != 0xffffffff80000000LL) {
|
|
||||||
printf("FAIL: unsigned→int→long long sign-extension\n");
|
|
||||||
ok = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("%s\n", ok ? "PASS" : "FAIL");
|
|
||||||
return ok ? 0 : 1;
|
|
||||||
}
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
y=ffffffff80000000
|
|
||||||
y=40000000
|
|
||||||
uy=ffffffff80000000
|
|
||||||
PASS
|
|
||||||
350
tests/tests2/141_riscv_asm.c
Normal file
350
tests/tests2/141_riscv_asm.c
Normal file
@ -0,0 +1,350 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifdef __riscv
|
||||||
|
|
||||||
|
/* P0.4 + P1.4: riscv64 asm pseudo-instructions test.
|
||||||
|
Exercises neg/negw, sext.w, fmv.s/d, fneg.s/d. */
|
||||||
|
|
||||||
|
int test_neg(int x)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
asm("neg %0, %1" : "=r"(r) : "r"(x));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
long long test_negw(long long x)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
asm("negw %0, %1" : "=r"(r) : "r"((int)x));
|
||||||
|
return (long long)r;
|
||||||
|
}
|
||||||
|
|
||||||
|
long long test_sextw(int x)
|
||||||
|
{
|
||||||
|
long long r;
|
||||||
|
asm("sext.w %0, %1" : "=r"(r) : "r"(x));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
float test_fmv_s(float a)
|
||||||
|
{
|
||||||
|
float r;
|
||||||
|
asm("fmv.s %0, %1" : "=f"(r) : "f"(a));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
float test_fneg_s(float a)
|
||||||
|
{
|
||||||
|
float r;
|
||||||
|
asm("fneg.s %0, %1" : "=f"(r) : "f"(a));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
double test_fmv_d(double a)
|
||||||
|
{
|
||||||
|
double r;
|
||||||
|
asm("fmv.d %0, %1" : "=f"(r) : "f"(a));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
double test_fneg_d(double a)
|
||||||
|
{
|
||||||
|
double r;
|
||||||
|
asm("fneg.d %0, %1" : "=f"(r) : "f"(a));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_pseudo(void)
|
||||||
|
{
|
||||||
|
int ok = 1;
|
||||||
|
|
||||||
|
if (test_neg(42) != -42) {
|
||||||
|
printf("FAIL: neg\n");
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
if (test_negw(100) != -100) {
|
||||||
|
printf("FAIL: negw\n");
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
if (test_sextw(0x80000000) != 0xffffffff80000000LL) {
|
||||||
|
printf("FAIL: sext.w\n");
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
if (test_fmv_s(3.14f) != 3.14f) {
|
||||||
|
printf("FAIL: fmv.s\n");
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
if (test_fneg_s(3.14f) != -3.14f) {
|
||||||
|
printf("FAIL: fneg.s\n");
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
if (test_fmv_d(2.718281828) != 2.718281828) {
|
||||||
|
printf("FAIL: fmv.d\n");
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
if (test_fneg_d(2.718281828) != -2.718281828) {
|
||||||
|
printf("FAIL: fneg.d\n");
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* P1.1: riscv64 inline asm with 64-bit immediate (li).
|
||||||
|
Tests that long long immediates assemble correctly,
|
||||||
|
including the lui+addi sequence for large constants. */
|
||||||
|
|
||||||
|
long long test_li_small(void)
|
||||||
|
{
|
||||||
|
long long r;
|
||||||
|
asm("li %0, 42" : "=r"(r));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
long long test_li_large(void)
|
||||||
|
{
|
||||||
|
long long r;
|
||||||
|
asm("li %0, 0x123456789ABCDEF0" : "=r"(r));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
long long test_li_negative(void)
|
||||||
|
{
|
||||||
|
long long r;
|
||||||
|
asm("li %0, -1" : "=r"(r));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_ll(void)
|
||||||
|
{
|
||||||
|
int ok = 1;
|
||||||
|
|
||||||
|
if (test_li_small() != 42) {
|
||||||
|
printf("FAIL: li small\n");
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
if (test_li_large() != 0x123456789ABCDEF0LL) {
|
||||||
|
printf("FAIL: li large\n");
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
if (test_li_negative() != -1) {
|
||||||
|
printf("FAIL: li negative\n");
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* P1.3: riscv64 F/D extension arithmetic instructions.
|
||||||
|
Tests fadd/fsub/fmul/fdiv for both single and double precision. */
|
||||||
|
|
||||||
|
float test_fadd_s(float a, float b)
|
||||||
|
{
|
||||||
|
float r;
|
||||||
|
asm("fadd.s %0, %1, %2" : "=f"(r) : "f"(a), "f"(b));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
float test_fsub_s(float a, float b)
|
||||||
|
{
|
||||||
|
float r;
|
||||||
|
asm("fsub.s %0, %1, %2" : "=f"(r) : "f"(a), "f"(b));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
float test_fmul_s(float a, float b)
|
||||||
|
{
|
||||||
|
float r;
|
||||||
|
asm("fmul.s %0, %1, %2" : "=f"(r) : "f"(a), "f"(b));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
float test_fdiv_s(float a, float b)
|
||||||
|
{
|
||||||
|
float r;
|
||||||
|
asm("fdiv.s %0, %1, %2" : "=f"(r) : "f"(a), "f"(b));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
double test_fadd_d(double a, double b)
|
||||||
|
{
|
||||||
|
double r;
|
||||||
|
asm("fadd.d %0, %1, %2" : "=f"(r) : "f"(a), "f"(b));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
double test_fsub_d(double a, double b)
|
||||||
|
{
|
||||||
|
double r;
|
||||||
|
asm("fsub.d %0, %1, %2" : "=f"(r) : "f"(a), "f"(b));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
double test_fmul_d(double a, double b)
|
||||||
|
{
|
||||||
|
double r;
|
||||||
|
asm("fmul.d %0, %1, %2" : "=f"(r) : "f"(a), "f"(b));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
double test_fdiv_d(double a, double b)
|
||||||
|
{
|
||||||
|
double r;
|
||||||
|
asm("fdiv.d %0, %1, %2" : "=f"(r) : "f"(a), "f"(b));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_farith(void)
|
||||||
|
{
|
||||||
|
int ok = 1;
|
||||||
|
|
||||||
|
if (test_fadd_s(1.5f, 2.5f) != 4.0f) {
|
||||||
|
printf("FAIL: fadd.s\n");
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
if (test_fsub_s(5.0f, 2.0f) != 3.0f) {
|
||||||
|
printf("FAIL: fsub.s\n");
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
if (test_fmul_s(3.0f, 4.0f) != 12.0f) {
|
||||||
|
printf("FAIL: fmul.s\n");
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
if (test_fdiv_s(12.0f, 4.0f) != 3.0f) {
|
||||||
|
printf("FAIL: fdiv.s\n");
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (test_fadd_d(1.5, 2.5) != 4.0) {
|
||||||
|
printf("FAIL: fadd.d\n");
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
if (test_fsub_d(5.0, 2.0) != 3.0) {
|
||||||
|
printf("FAIL: fsub.d\n");
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
if (test_fmul_d(3.0, 4.0) != 12.0) {
|
||||||
|
printf("FAIL: fmul.d\n");
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
if (test_fdiv_d(12.0, 4.0) != 3.0) {
|
||||||
|
printf("FAIL: fdiv.d\n");
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
int csr_pseudo_main(void)
|
||||||
|
{
|
||||||
|
int ok = 1;
|
||||||
|
int old, tmp;
|
||||||
|
|
||||||
|
asm volatile("csrr %0, 0x003" : "=r"(old));
|
||||||
|
|
||||||
|
asm volatile("csrr %0, 0x003" : "=r"(tmp));
|
||||||
|
//printf("csrr fcsr=%x\n", (unsigned)tmp);
|
||||||
|
|
||||||
|
asm volatile("csrw 0x003, %0" : : "r"(0xE0));
|
||||||
|
asm volatile("csrr %0, 0x003" : "=r"(tmp));
|
||||||
|
//printf("csrw: wrote e0 got %x\n", (unsigned)tmp);
|
||||||
|
if (tmp != 0xE0) { printf("FAIL: csrw\n"); ok = 0; }
|
||||||
|
asm volatile("csrw 0x003, %0" : : "r"(old));
|
||||||
|
|
||||||
|
asm volatile("csrwi 0x003, 0x10");
|
||||||
|
asm volatile("csrr %0, 0x003" : "=r"(tmp));
|
||||||
|
//printf("csrwi: wrote 0x10 got %x\n", (unsigned)tmp);
|
||||||
|
if (tmp != 0x10) { printf("FAIL: csrwi\n"); ok = 0; }
|
||||||
|
asm volatile("csrw 0x003, %0" : : "r"(old));
|
||||||
|
|
||||||
|
asm volatile("csrsi 0x003, 0x03");
|
||||||
|
asm volatile("csrr %0, 0x003" : "=r"(tmp));
|
||||||
|
//printf("csrsi: old|3=%x\n", (unsigned)tmp);
|
||||||
|
if ((old | 0x03) != tmp) { printf("FAIL: csrsi\n"); ok = 0; }
|
||||||
|
asm volatile("csrw 0x003, %0" : : "r"(old));
|
||||||
|
|
||||||
|
asm volatile("csrci 0x003, 0x03");
|
||||||
|
asm volatile("csrr %0, 0x003" : "=r"(tmp));
|
||||||
|
//printf("csrci: old&~3=%x\n", (unsigned)tmp);
|
||||||
|
if ((old & ~0x03) != tmp) { printf("FAIL: csrci\n"); ok = 0; }
|
||||||
|
asm volatile("csrw 0x003, %0" : : "r"(old));
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fp_cmp_cvt_main(void)
|
||||||
|
{
|
||||||
|
/* F/D comparison (use raw regs to avoid inline asm float→int bug) */
|
||||||
|
asm volatile("feq.s a0, fa0, fa1");
|
||||||
|
asm volatile("feq.d a0, fa0, fa1");
|
||||||
|
asm volatile("flt.s a0, fa0, fa1");
|
||||||
|
asm volatile("flt.d a0, fa0, fa1");
|
||||||
|
asm volatile("fle.s a0, fa0, fa1");
|
||||||
|
asm volatile("fle.d a0, fa0, fa1");
|
||||||
|
|
||||||
|
/* fcvt conversions */
|
||||||
|
asm volatile("fcvt.w.s a0, fa0");
|
||||||
|
asm volatile("fcvt.wu.s a0, fa0");
|
||||||
|
asm volatile("fcvt.s.w fa0, a0");
|
||||||
|
asm volatile("fcvt.w.d a0, fa0");
|
||||||
|
asm volatile("fcvt.d.w fa0, a0");
|
||||||
|
asm volatile("fcvt.d.s fa0, fa0");
|
||||||
|
asm volatile("fcvt.s.d fa0, fa0");
|
||||||
|
|
||||||
|
/* fclass */
|
||||||
|
asm volatile("fclass.s a0, fa0");
|
||||||
|
asm volatile("fclass.d a0, fa0");
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int amo_main(void)
|
||||||
|
{
|
||||||
|
/* AMO base (all funct5 now match GNU as) */
|
||||||
|
asm volatile("amoadd.w a0, a1, (sp)");
|
||||||
|
asm volatile("amoswap.w a0, a1, (sp)");
|
||||||
|
asm volatile("amoand.w a0, a1, (sp)");
|
||||||
|
asm volatile("amoor.d a0, a1, (sp)");
|
||||||
|
asm volatile("amoxor.w a0, a1, (sp)");
|
||||||
|
asm volatile("amomax.w a0, a1, (sp)");
|
||||||
|
asm volatile("amomaxu.d a0, a1, (sp)");
|
||||||
|
asm volatile("amomin.w a0, a1, (sp)");
|
||||||
|
asm volatile("amominu.d a0, a1, (sp)");
|
||||||
|
|
||||||
|
/* AMO aq/rl ordering suffixes */
|
||||||
|
asm volatile("amoadd.w.aq a0, a1, (sp)");
|
||||||
|
asm volatile("amoadd.w.rl a0, a1, (sp)");
|
||||||
|
asm volatile("amoadd.d.aqrl a0, a1, (sp)");
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fcvt_round_main(void)
|
||||||
|
{
|
||||||
|
/* fcvt with optional rounding mode operand (GNU as syntax) */
|
||||||
|
asm volatile("fcvt.w.s a0, fa0, rne");
|
||||||
|
asm volatile("fcvt.w.s a0, fa0, rtz");
|
||||||
|
asm volatile("fcvt.w.s a0, fa0, rup");
|
||||||
|
asm volatile("fcvt.w.d a0, fa0, rne");
|
||||||
|
asm volatile("fcvt.w.d a0, fa0, rtz");
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int ok = 1;
|
||||||
|
ok &= test_pseudo();
|
||||||
|
ok &= test_ll();
|
||||||
|
ok &= test_farith();
|
||||||
|
ok &= csr_pseudo_main();
|
||||||
|
ok &= fp_cmp_cvt_main();
|
||||||
|
//ok &= amo_main(); //crash on qemu
|
||||||
|
ok &= fcvt_round_main();
|
||||||
|
printf("%s\n", ok ? "PASS" : "FAIL");
|
||||||
|
return !ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
printf("SKIP\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@ -1,100 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
/* P0.4 + P1.4: riscv64 asm pseudo-instructions test.
|
|
||||||
Exercises neg/negw, sext.w, fmv.s/d, fneg.s/d. */
|
|
||||||
|
|
||||||
#ifdef __riscv
|
|
||||||
|
|
||||||
int test_neg(int x)
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
asm("neg %0, %1" : "=r"(r) : "r"(x));
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
long long test_negw(long long x)
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
asm("negw %0, %1" : "=r"(r) : "r"((int)x));
|
|
||||||
return (long long)r;
|
|
||||||
}
|
|
||||||
|
|
||||||
long long test_sextw(int x)
|
|
||||||
{
|
|
||||||
long long r;
|
|
||||||
asm("sext.w %0, %1" : "=r"(r) : "r"(x));
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
float test_fmv_s(float a)
|
|
||||||
{
|
|
||||||
float r;
|
|
||||||
asm("fmv.s %0, %1" : "=f"(r) : "f"(a));
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
float test_fneg_s(float a)
|
|
||||||
{
|
|
||||||
float r;
|
|
||||||
asm("fneg.s %0, %1" : "=f"(r) : "f"(a));
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
double test_fmv_d(double a)
|
|
||||||
{
|
|
||||||
double r;
|
|
||||||
asm("fmv.d %0, %1" : "=f"(r) : "f"(a));
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
double test_fneg_d(double a)
|
|
||||||
{
|
|
||||||
double r;
|
|
||||||
asm("fneg.d %0, %1" : "=f"(r) : "f"(a));
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
int ok = 1;
|
|
||||||
|
|
||||||
if (test_neg(42) != -42) {
|
|
||||||
printf("FAIL: neg\n");
|
|
||||||
ok = 0;
|
|
||||||
}
|
|
||||||
if (test_negw(100) != -100) {
|
|
||||||
printf("FAIL: negw\n");
|
|
||||||
ok = 0;
|
|
||||||
}
|
|
||||||
if (test_sextw(0x80000000) != 0xffffffff80000000LL) {
|
|
||||||
printf("FAIL: sext.w\n");
|
|
||||||
ok = 0;
|
|
||||||
}
|
|
||||||
if (test_fmv_s(3.14f) != 3.14f) {
|
|
||||||
printf("FAIL: fmv.s\n");
|
|
||||||
ok = 0;
|
|
||||||
}
|
|
||||||
if (test_fneg_s(3.14f) != -3.14f) {
|
|
||||||
printf("FAIL: fneg.s\n");
|
|
||||||
ok = 0;
|
|
||||||
}
|
|
||||||
if (test_fmv_d(2.718281828) != 2.718281828) {
|
|
||||||
printf("FAIL: fmv.d\n");
|
|
||||||
ok = 0;
|
|
||||||
}
|
|
||||||
if (test_fneg_d(2.718281828) != -2.718281828) {
|
|
||||||
printf("FAIL: fneg.d\n");
|
|
||||||
ok = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("%s\n", ok ? "PASS" : "FAIL");
|
|
||||||
return ok ? 0 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
printf("SKIP\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
143
tests/tests2/142_int_conversion.c
Normal file
143
tests/tests2/142_int_conversion.c
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/* PROMOTE_RET test: verify char/short return values are properly
|
||||||
|
zero/sign-extended to 64-bit per the RISC-V integer calling convention.
|
||||||
|
Without PROMOTE_RET, upper bits of the return register may contain
|
||||||
|
garbage, causing incorrect results when assigned to a wider type. */
|
||||||
|
|
||||||
|
unsigned char get_uc(void) { return 0x80; }
|
||||||
|
signed char get_sc(void) { return 0x80; }
|
||||||
|
unsigned short get_us(void) { return 0x8000; }
|
||||||
|
signed short get_ss(void) { return 0x8000; }
|
||||||
|
|
||||||
|
/* Prevent inlining to force ABI-compliant calling. */
|
||||||
|
unsigned char (* volatile fp_uc)(void) = get_uc;
|
||||||
|
signed char (* volatile fp_sc)(void) = get_sc;
|
||||||
|
unsigned short (* volatile fp_us)(void) = get_us;
|
||||||
|
signed short (* volatile fp_ss)(void) = get_ss;
|
||||||
|
|
||||||
|
int promote_main(void)
|
||||||
|
{
|
||||||
|
int ok = 1;
|
||||||
|
unsigned long long uc = fp_uc();
|
||||||
|
signed long long sc = fp_sc();
|
||||||
|
unsigned long long us = fp_us();
|
||||||
|
signed long long ss = fp_ss();
|
||||||
|
|
||||||
|
printf("uc=%llx sc=%llx us=%llx ss=%llx\n",
|
||||||
|
(unsigned long long)uc,
|
||||||
|
(unsigned long long)sc,
|
||||||
|
(unsigned long long)us,
|
||||||
|
(unsigned long long)ss);
|
||||||
|
|
||||||
|
if (uc != 0x80) {
|
||||||
|
printf("FAIL: uc not zero-extended\n");
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
if (sc != 0xffffffffffffff80LL) {
|
||||||
|
printf("FAIL: sc not sign-extended\n");
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
if (us != 0x8000) {
|
||||||
|
printf("FAIL: us not zero-extended\n");
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
if (ss != 0xffffffffffff8000LL) {
|
||||||
|
printf("FAIL: ss not sign-extended\n");
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s\n", ok ? "PASS" : "FAIL");
|
||||||
|
return ok ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* gen_cvt_csti test: verify narrow-type conversions in expressions.
|
||||||
|
Without the fix, TCC's riscv64 backend could miss the conversion
|
||||||
|
step when promoting a narrow result back to int, producing wrong
|
||||||
|
values (e.g., treating a char as still 32-bit). */
|
||||||
|
|
||||||
|
int cast_main(void)
|
||||||
|
{
|
||||||
|
int ok = 1;
|
||||||
|
int x = 0x12345678;
|
||||||
|
|
||||||
|
/* Cast to char then add 1 — result must be 8-bit. */
|
||||||
|
char c = (char)x + 1;
|
||||||
|
unsigned char uc = (unsigned char)x + 1;
|
||||||
|
short s = (short)x + 1;
|
||||||
|
unsigned short us = (unsigned short)x + 1;
|
||||||
|
|
||||||
|
printf("c=%x uc=%x s=%x us=%x\n",
|
||||||
|
(unsigned char)c, (unsigned)uc,
|
||||||
|
(unsigned short)s, (unsigned)us);
|
||||||
|
|
||||||
|
if (c != (char)0x78 + 1) {
|
||||||
|
printf("FAIL: char conversion\n");
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
if (uc != (unsigned char)0x78 + 1) {
|
||||||
|
printf("FAIL: unsigned char conversion\n");
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
if (s != (short)0x5678 + 1) {
|
||||||
|
printf("FAIL: short conversion\n");
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
if (us != (unsigned short)0x5678 + 1) {
|
||||||
|
printf("FAIL: unsigned short conversion\n");
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s\n", ok ? "PASS" : "FAIL");
|
||||||
|
return ok ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* gen_cvt_sxtw test: verify sign-extension from 32-bit int to 64-bit long long.
|
||||||
|
Without the fix, the riscv64 backend had an empty stub for gen_cvt_sxtw,
|
||||||
|
leaving upper 32 bits unmodified (containing whatever was in the register
|
||||||
|
before), so (long long)(int)x produced wrong results for negative values. */
|
||||||
|
|
||||||
|
int sign_main(void)
|
||||||
|
{
|
||||||
|
int ok = 1;
|
||||||
|
int x = 0x80000000;
|
||||||
|
long long y = (long long)x;
|
||||||
|
|
||||||
|
printf("y=%llx\n", (unsigned long long)y);
|
||||||
|
|
||||||
|
if (y != 0xffffffff80000000LL) {
|
||||||
|
printf("FAIL: int→long long sign-extension\n");
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Also test positive value. */
|
||||||
|
x = 0x40000000;
|
||||||
|
y = (long long)x;
|
||||||
|
printf("y=%llx\n", (unsigned long long)y);
|
||||||
|
|
||||||
|
if (y != 0x40000000LL) {
|
||||||
|
printf("FAIL: int→long long positive value\n");
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test via unsigned int to catch zero-extension vs sign-extension. */
|
||||||
|
unsigned int ux = 0x80000000;
|
||||||
|
long long uy = (long long)(int)ux;
|
||||||
|
printf("uy=%llx\n", (unsigned long long)uy);
|
||||||
|
|
||||||
|
if (uy != 0xffffffff80000000LL) {
|
||||||
|
printf("FAIL: unsigned→int→long long sign-extension\n");
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s\n", ok ? "PASS" : "FAIL");
|
||||||
|
return ok ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
return
|
||||||
|
promote_main()
|
||||||
|
| cast_main()
|
||||||
|
| sign_main();
|
||||||
|
}
|
||||||
8
tests/tests2/142_int_conversion.expect
Normal file
8
tests/tests2/142_int_conversion.expect
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
uc=80 sc=ffffffffffffff80 us=8000 ss=ffffffffffff8000
|
||||||
|
PASS
|
||||||
|
c=79 uc=79 s=5679 us=5679
|
||||||
|
PASS
|
||||||
|
y=ffffffff80000000
|
||||||
|
y=40000000
|
||||||
|
uy=ffffffff80000000
|
||||||
|
PASS
|
||||||
@ -1,57 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
/* P1.1: riscv64 inline asm with 64-bit immediate (li).
|
|
||||||
Tests that long long immediates assemble correctly,
|
|
||||||
including the lui+addi sequence for large constants. */
|
|
||||||
|
|
||||||
#ifdef __riscv
|
|
||||||
|
|
||||||
long long test_li_small(void)
|
|
||||||
{
|
|
||||||
long long r;
|
|
||||||
asm("li %0, 42" : "=r"(r));
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
long long test_li_large(void)
|
|
||||||
{
|
|
||||||
long long r;
|
|
||||||
asm("li %0, 0x123456789ABCDEF0" : "=r"(r));
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
long long test_li_negative(void)
|
|
||||||
{
|
|
||||||
long long r;
|
|
||||||
asm("li %0, -1" : "=r"(r));
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
int ok = 1;
|
|
||||||
|
|
||||||
if (test_li_small() != 42) {
|
|
||||||
printf("FAIL: li small\n");
|
|
||||||
ok = 0;
|
|
||||||
}
|
|
||||||
if (test_li_large() != 0x123456789ABCDEF0LL) {
|
|
||||||
printf("FAIL: li large\n");
|
|
||||||
ok = 0;
|
|
||||||
}
|
|
||||||
if (test_li_negative() != -1) {
|
|
||||||
printf("FAIL: li negative\n");
|
|
||||||
ok = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("%s\n", ok ? "PASS" : "FAIL");
|
|
||||||
return ok ? 0 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
printf("SKIP\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@ -1 +0,0 @@
|
|||||||
PASS
|
|
||||||
@ -1,112 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
/* P1.3: riscv64 F/D extension arithmetic instructions.
|
|
||||||
Tests fadd/fsub/fmul/fdiv for both single and double precision. */
|
|
||||||
|
|
||||||
#ifdef __riscv
|
|
||||||
|
|
||||||
float test_fadd_s(float a, float b)
|
|
||||||
{
|
|
||||||
float r;
|
|
||||||
asm("fadd.s %0, %1, %2" : "=f"(r) : "f"(a), "f"(b));
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
float test_fsub_s(float a, float b)
|
|
||||||
{
|
|
||||||
float r;
|
|
||||||
asm("fsub.s %0, %1, %2" : "=f"(r) : "f"(a), "f"(b));
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
float test_fmul_s(float a, float b)
|
|
||||||
{
|
|
||||||
float r;
|
|
||||||
asm("fmul.s %0, %1, %2" : "=f"(r) : "f"(a), "f"(b));
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
float test_fdiv_s(float a, float b)
|
|
||||||
{
|
|
||||||
float r;
|
|
||||||
asm("fdiv.s %0, %1, %2" : "=f"(r) : "f"(a), "f"(b));
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
double test_fadd_d(double a, double b)
|
|
||||||
{
|
|
||||||
double r;
|
|
||||||
asm("fadd.d %0, %1, %2" : "=f"(r) : "f"(a), "f"(b));
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
double test_fsub_d(double a, double b)
|
|
||||||
{
|
|
||||||
double r;
|
|
||||||
asm("fsub.d %0, %1, %2" : "=f"(r) : "f"(a), "f"(b));
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
double test_fmul_d(double a, double b)
|
|
||||||
{
|
|
||||||
double r;
|
|
||||||
asm("fmul.d %0, %1, %2" : "=f"(r) : "f"(a), "f"(b));
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
double test_fdiv_d(double a, double b)
|
|
||||||
{
|
|
||||||
double r;
|
|
||||||
asm("fdiv.d %0, %1, %2" : "=f"(r) : "f"(a), "f"(b));
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
int ok = 1;
|
|
||||||
|
|
||||||
if (test_fadd_s(1.5f, 2.5f) != 4.0f) {
|
|
||||||
printf("FAIL: fadd.s\n");
|
|
||||||
ok = 0;
|
|
||||||
}
|
|
||||||
if (test_fsub_s(5.0f, 2.0f) != 3.0f) {
|
|
||||||
printf("FAIL: fsub.s\n");
|
|
||||||
ok = 0;
|
|
||||||
}
|
|
||||||
if (test_fmul_s(3.0f, 4.0f) != 12.0f) {
|
|
||||||
printf("FAIL: fmul.s\n");
|
|
||||||
ok = 0;
|
|
||||||
}
|
|
||||||
if (test_fdiv_s(12.0f, 4.0f) != 3.0f) {
|
|
||||||
printf("FAIL: fdiv.s\n");
|
|
||||||
ok = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (test_fadd_d(1.5, 2.5) != 4.0) {
|
|
||||||
printf("FAIL: fadd.d\n");
|
|
||||||
ok = 0;
|
|
||||||
}
|
|
||||||
if (test_fsub_d(5.0, 2.0) != 3.0) {
|
|
||||||
printf("FAIL: fsub.d\n");
|
|
||||||
ok = 0;
|
|
||||||
}
|
|
||||||
if (test_fmul_d(3.0, 4.0) != 12.0) {
|
|
||||||
printf("FAIL: fmul.d\n");
|
|
||||||
ok = 0;
|
|
||||||
}
|
|
||||||
if (test_fdiv_d(12.0, 4.0) != 3.0) {
|
|
||||||
printf("FAIL: fdiv.d\n");
|
|
||||||
ok = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("%s\n", ok ? "PASS" : "FAIL");
|
|
||||||
return ok ? 0 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
printf("SKIP\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@ -1 +0,0 @@
|
|||||||
PASS
|
|
||||||
@ -1,49 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#ifdef __riscv
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
int ok = 1;
|
|
||||||
int old, tmp;
|
|
||||||
|
|
||||||
asm volatile("csrr %0, 0x003" : "=r"(old));
|
|
||||||
|
|
||||||
asm volatile("csrr %0, 0x003" : "=r"(tmp));
|
|
||||||
printf("csrr fcsr=%x\n", (unsigned)tmp);
|
|
||||||
|
|
||||||
asm volatile("csrw 0x003, %0" : : "r"(0xE0));
|
|
||||||
asm volatile("csrr %0, 0x003" : "=r"(tmp));
|
|
||||||
printf("csrw: wrote e0 got %x\n", (unsigned)tmp);
|
|
||||||
if (tmp != 0xE0) { printf("FAIL: csrw\n"); ok = 0; }
|
|
||||||
asm volatile("csrw 0x003, %0" : : "r"(old));
|
|
||||||
|
|
||||||
asm volatile("csrwi 0x003, 0x10");
|
|
||||||
asm volatile("csrr %0, 0x003" : "=r"(tmp));
|
|
||||||
printf("csrwi: wrote 0x10 got %x\n", (unsigned)tmp);
|
|
||||||
if (tmp != 0x10) { printf("FAIL: csrwi\n"); ok = 0; }
|
|
||||||
asm volatile("csrw 0x003, %0" : : "r"(old));
|
|
||||||
|
|
||||||
asm volatile("csrsi 0x003, 0x03");
|
|
||||||
asm volatile("csrr %0, 0x003" : "=r"(tmp));
|
|
||||||
printf("csrsi: old|3=%x\n", (unsigned)tmp);
|
|
||||||
if ((old | 0x03) != tmp) { printf("FAIL: csrsi\n"); ok = 0; }
|
|
||||||
asm volatile("csrw 0x003, %0" : : "r"(old));
|
|
||||||
|
|
||||||
asm volatile("csrci 0x003, 0x03");
|
|
||||||
asm volatile("csrr %0, 0x003" : "=r"(tmp));
|
|
||||||
printf("csrci: old&~3=%x\n", (unsigned)tmp);
|
|
||||||
if ((old & ~0x03) != tmp) { printf("FAIL: csrci\n"); ok = 0; }
|
|
||||||
asm volatile("csrw 0x003, %0" : : "r"(old));
|
|
||||||
|
|
||||||
printf("%s\n", ok ? "PASS" : "FAIL");
|
|
||||||
return ok ? 0 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
printf("SKIP\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@ -1 +0,0 @@
|
|||||||
SKIP
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#ifdef __riscv
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
/* F/D comparison (use raw regs to avoid inline asm float→int bug) */
|
|
||||||
asm volatile("feq.s a0, fa0, fa1");
|
|
||||||
asm volatile("feq.d a0, fa0, fa1");
|
|
||||||
asm volatile("flt.s a0, fa0, fa1");
|
|
||||||
asm volatile("flt.d a0, fa0, fa1");
|
|
||||||
asm volatile("fle.s a0, fa0, fa1");
|
|
||||||
asm volatile("fle.d a0, fa0, fa1");
|
|
||||||
|
|
||||||
/* fcvt conversions */
|
|
||||||
asm volatile("fcvt.w.s a0, fa0");
|
|
||||||
asm volatile("fcvt.wu.s a0, fa0");
|
|
||||||
asm volatile("fcvt.s.w fa0, a0");
|
|
||||||
asm volatile("fcvt.w.d a0, fa0");
|
|
||||||
asm volatile("fcvt.d.w fa0, a0");
|
|
||||||
asm volatile("fcvt.d.s fa0, fa0");
|
|
||||||
asm volatile("fcvt.s.d fa0, fa0");
|
|
||||||
|
|
||||||
/* fclass */
|
|
||||||
asm volatile("fclass.s a0, fa0");
|
|
||||||
asm volatile("fclass.d a0, fa0");
|
|
||||||
|
|
||||||
printf("PASS\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
int main(void) { printf("SKIP\n"); return 0; }
|
|
||||||
#endif
|
|
||||||
@ -1 +0,0 @@
|
|||||||
PASS
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#ifdef __riscv
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
/* AMO base (all funct5 now match GNU as) */
|
|
||||||
asm volatile("amoadd.w a0, a1, (sp)");
|
|
||||||
asm volatile("amoswap.w a0, a1, (sp)");
|
|
||||||
asm volatile("amoand.w a0, a1, (sp)");
|
|
||||||
asm volatile("amoor.d a0, a1, (sp)");
|
|
||||||
asm volatile("amoxor.w a0, a1, (sp)");
|
|
||||||
asm volatile("amomax.w a0, a1, (sp)");
|
|
||||||
asm volatile("amomaxu.d a0, a1, (sp)");
|
|
||||||
asm volatile("amomin.w a0, a1, (sp)");
|
|
||||||
asm volatile("amominu.d a0, a1, (sp)");
|
|
||||||
|
|
||||||
/* AMO aq/rl ordering suffixes */
|
|
||||||
asm volatile("amoadd.w.aq a0, a1, (sp)");
|
|
||||||
asm volatile("amoadd.w.rl a0, a1, (sp)");
|
|
||||||
asm volatile("amoadd.d.aqrl a0, a1, (sp)");
|
|
||||||
|
|
||||||
printf("PASS\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
int main(void) { printf("SKIP\n"); return 0; }
|
|
||||||
#endif
|
|
||||||
@ -1 +0,0 @@
|
|||||||
SKIP
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#ifdef __riscv
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
/* fcvt with optional rounding mode operand (GNU as syntax) */
|
|
||||||
asm volatile("fcvt.w.s a0, fa0, rne");
|
|
||||||
asm volatile("fcvt.w.s a0, fa0, rtz");
|
|
||||||
asm volatile("fcvt.w.s a0, fa0, rup");
|
|
||||||
asm volatile("fcvt.w.d a0, fa0, rne");
|
|
||||||
asm volatile("fcvt.w.d a0, fa0, rtz");
|
|
||||||
|
|
||||||
printf("PASS\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
int main(void) { printf("SKIP\n"); return 0; }
|
|
||||||
#endif
|
|
||||||
@ -1 +0,0 @@
|
|||||||
SKIP
|
|
||||||
@ -19,15 +19,6 @@ ifeq (,$(filter i386 x86_64,$(ARCH)))
|
|||||||
SKIP += 85_asm-outside-function.test # x86 asm
|
SKIP += 85_asm-outside-function.test # x86 asm
|
||||||
SKIP += 127_asm_goto.test # hardcodes x86 asm
|
SKIP += 127_asm_goto.test # hardcodes x86 asm
|
||||||
endif
|
endif
|
||||||
ifeq (,$(filter riscv64,$(ARCH)))
|
|
||||||
SKIP += 141_riscv_asm_pseudo.test # riscv64 asm
|
|
||||||
SKIP += 142_riscv_asm_longlong.test # riscv64 asm
|
|
||||||
SKIP += 143_riscv_asm_farith.test # riscv64 asm
|
|
||||||
SKIP += 144_riscv_csr_pseudo.test # riscv64 asm
|
|
||||||
SKIP += 145_riscv_fp_cmp_cvt.test # riscv64 asm
|
|
||||||
SKIP += 146_riscv_amo.test # riscv64 asm
|
|
||||||
SKIP += 147_riscv_fcvt_round.test # riscv64 asm
|
|
||||||
endif
|
|
||||||
ifeq ($(CONFIG_backtrace),no)
|
ifeq ($(CONFIG_backtrace),no)
|
||||||
SKIP += 113_btdll.test
|
SKIP += 113_btdll.test
|
||||||
CONFIG_bcheck = no
|
CONFIG_bcheck = no
|
||||||
@ -67,6 +58,9 @@ ifeq (,$(filter arm64 aarch64,$(ARCH)))
|
|||||||
SKIP += 139_arm64_errors.test
|
SKIP += 139_arm64_errors.test
|
||||||
SKIP += 140_arm64_extasm.test
|
SKIP += 140_arm64_extasm.test
|
||||||
endif
|
endif
|
||||||
|
ifeq (,$(filter riscv64,$(ARCH)))
|
||||||
|
SKIP += 141_riscv_asm.test # riscv64 asm
|
||||||
|
endif
|
||||||
|
|
||||||
# Some tests might need arguments
|
# Some tests might need arguments
|
||||||
ARGS =
|
ARGS =
|
||||||
@ -94,10 +88,6 @@ endif
|
|||||||
GEN-ALWAYS =
|
GEN-ALWAYS =
|
||||||
# GEN-ALWAYS += 95_bitfields.expect # does not work
|
# GEN-ALWAYS += 95_bitfields.expect # does not work
|
||||||
|
|
||||||
# fcvt rounding 3-dot names not supported by host binutils, use TCC
|
|
||||||
GEN-ALWAYS =
|
|
||||||
# GEN-ALWAYS += 95_bitfields.expect # does not work
|
|
||||||
|
|
||||||
# using the ms compiler for the really ms-compatible bitfields
|
# using the ms compiler for the really ms-compatible bitfields
|
||||||
95_bitfields_ms.test : GEN = $(GEN-MSC)
|
95_bitfields_ms.test : GEN = $(GEN-MSC)
|
||||||
|
|
||||||
@ -145,6 +135,7 @@ endif
|
|||||||
128_run_atexit.test: FLAGS += -dt
|
128_run_atexit.test: FLAGS += -dt
|
||||||
132_bound_test.test: FLAGS += -b
|
132_bound_test.test: FLAGS += -b
|
||||||
140_arm64_extasm.test: GEN = $(GEN-TCC)
|
140_arm64_extasm.test: GEN = $(GEN-TCC)
|
||||||
|
141_riscv_asm.test: FLAGS += -bt
|
||||||
|
|
||||||
# Filter source directory in warnings/errors (out-of-tree builds)
|
# Filter source directory in warnings/errors (out-of-tree builds)
|
||||||
FILTER = 2>&1 | sed -e 's,$(SRC)/,,g'
|
FILTER = 2>&1 | sed -e 's,$(SRC)/,,g'
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user