RISC-V port

Luís Marques luis at luismarques.eu
Thu May 24 18:31:01 UTC 2018

On Thursday, 24 May 2018 at 14:45:26 UTC, Luís Marques wrote:
> Clue: when I call __cxa_throw in D code instead of throwing 
> normally (i.e., calling _d_throw_exception), the D personality 
> handler *is* called. Which indicates that, indeed, the problem 
> is *not* in the generated assembly file. So I guess it's 
> something that _d_throw_exception does which isn't quite right, 
> although I can't see what.

There is this fragment of code in libgcc's _Unwind_RaiseException
(printfs inserted by me):

       code = uw_frame_state_for (&cur_context, &fs);
       printf("_Unwind_RaiseException uw_frame_state_for %d\n", 

       if (code == _URC_END_OF_STACK)
	/* Hit end of stack with no handler found.  */
         printf("_Unwind_RaiseException code == 
	return _URC_END_OF_STACK;

The code prints:

_Unwind_RaiseException uw_frame_state_for 5
_Unwind_RaiseException code == _URC_END_OF_STACK

But then the function actually returns a nonsense number instead 
of the expected 5/_URC_END_OF_STACK. Looking at the disassembly 
of _Unwind_RaiseException what seems to happen is that the 
function starts with:

00001db0 <_Unwind_RaiseException>:
     1db0:	a7010113          	addi	sp,sp,-1424
     1db4:	58912223          	sw	s1,1412(sp)
     1db8:	58a12023          	sw	a0,1408(sp) // store a0

And then before it returns it does this:

     2034:	58012503          	lw	a0,1408(sp) // load original a0
     2038:	59010113          	addi	sp,sp,1424
     203c:	00e10133          	add	sp,sp,a4
     2040:	00008067          	ret

No other part of that function stores to 1408(sp), so of course 
a0 (the main return register) returns garbage instead of the more 
meaningful 5/_URC_END_OF_STACK.

GCC is supposed to be reliable, so I would lean towards believing 
this isn't a miscompilation. The function prototype is:

_Unwind_RaiseException(struct _Unwind_Exception *exc)

So I though maybe LIBGCC2_UNWIND_ATTRIBUTE was modifying the ABI 
somehow, and the return value wouldn't be in a0 as usual. But 
grepping my RISC-V GCC source code for that didn't find anything 
meaningful (only mips seems to define it). And looking at the 
complete disassembly it doesn't explain how the return value 
would be returned anyway. So maybe that's a miscompilation? I'll 
ask in the RISC-V forums.

More information about the digitalmars-d-ldc mailing list