sellicott/tcc-riscv32

LI behaving strangely

fwsGonzo opened this issue · 4 comments

static long fib(long n, long acc, long prev)
{
	if (n == 0)
		return acc;
	else
		return fib(n - 1, prev + acc, acc);
}

inline long syscall(long n, long arg0) {
	register long a0 asm("a0") = arg0;
	register long syscall_id asm("a7") = n;

	__asm__ volatile ("scall" : "+r"(a0) : "r"(syscall_id));

	return a0;
}

asm(
".global exit\n"
"exit:\n"
//"  li a7, 93\n"
"  addi a7, zero, 93\n"
"  ecall\n"
);

/**
"  addi a7, zero, 93\n"

   111f8:	000018b7          	lui	a7,0x1
   111fc:	05d88893          	addi	a7,a7,93 # 0x105d
   11200:	00000073          	ecall

"  addi a7, zero, 93\n"

   111f8:	05d00893          	li	a7,93
   111fc:	00000073          	ecall
*/

extern void exit(long);
void _start()
{
	const volatile long n = 30;
	exit(fib(n, 0, 1));
	//syscall(93, fib(n, 0, 1));
}

I wrote this program in order to test fib(), and I see that "li a7, 93" produces the wrong register value, while "addi a7, zero, 94" works as expected.

Maybe this helps narrow down an issue?

The inline system call also produces a strange function, but I guess it is not supported right now, not to mention global assembly is completely OK 👍

[00011264] FEA42423 ST.W A0, [SR0-24] (0x1113DC8)
[00011268] FEB42023 ST.W A1, [SR0-32] (0x1113DC0)
[0001126C] FE042503 LD.W A0, [SR0-32 = 0x1113DC0]
[00011270] FCA42E23 ST.W A0, [SR0-36] (0x1113DBC)
[00011274] FE842503 LD.W A0, [SR0-24 = 0x1113DC8]
[00011278] FCA42C23 ST.W A0, [SR0-40] (0x1113DB8)
[0001127C] 00000073 SYS ECALL

Thanks for the bug report!
I pushed a change (9f0715b) that I think will fix the li issue (I did some code refactoring late last night that apparently broke it). I haven't checked it yet but will look into it further later tonight.
Yeah, I haven't done any testing of inline assembly. It's completely disabled in the riscv64 version I turned it on to play with later, but have not debugged the output yet.

Awesome! It works now:

   111f8:	000008b7          	lui	a7,0x0
   111fc:	05d88893          	addi	a7,a7,93 # 0x5d
   11200:	00000073          	ecall

It's not optimal but it's definitely correct now!

Great! Let me know if you see anything else (I am sure there are many more bugs that I haven't found).
Optimal would be just adda correct (since the upper 24-bits are all zero)? I can patch to that behavior soon.

Yes, just a simple addi DST, x0, imm will load an integer between -4096 and 4095