tinycc/tests/tests2/140_int_sign_extension.c
Meng Zhuo ff917c09aa riscv64: implement gen_cvt_sxtw with addiw instruction
Replaces the empty stub that relied on 'RV64 registers are always
sign-extended' assumption.  Now emits addiw rd, rs, 0 for proper
32-to-64 bit sign extension, matching arm64's sxtw behavior.

Verified on Spacemit X100: tests2 pass (125_atomic_misc has a
pre-existing intermittent segfault, not caused by this change).
2026-05-06 12:30:34 +08:00

44 lines
1.2 KiB
C

#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;
}