@@ -383,21 +383,21 @@ impl RiscvArch {
383383 }
384384 }
385385
386- fn width ( & self ) -> usize {
386+ const fn width ( & self ) -> usize {
387387 match self {
388388 Self :: Rv32I | Self :: Rv32E => 4 ,
389389 Self :: Rv64I | Self :: Rv64E => 8 ,
390390 }
391391 }
392392
393- fn store ( & self ) -> & str {
393+ const fn store ( & self ) -> & str {
394394 match self {
395395 Self :: Rv32I | Self :: Rv32E => "sw" ,
396396 Self :: Rv64I | Self :: Rv64E => "sd" ,
397397 }
398398 }
399399
400- fn load ( & self ) -> & str {
400+ const fn load ( & self ) -> & str {
401401 match self {
402402 Self :: Rv32I | Self :: Rv32E => "lw" ,
403403 Self :: Rv64I | Self :: Rv64E => "ld" ,
@@ -410,10 +410,21 @@ impl RiscvArch {
410410 "ra" , "t0" , "t1" , "t2" , "t3" , "t4" , "t5" , "t6" , "a0" , "a1" , "a2" , "a3" , "a4" , "a5" ,
411411 "a6" , "a7" ,
412412 ] ,
413- Self :: Rv32E => vec ! [
414- "ra" , "t0" , "t1" , "t2" , "a0" , "a1" , "a2" , "a3" , "a4" , "a5" , "_r0" , "_r1" ,
415- ] ,
416- Self :: Rv64E => vec ! [ "ra" , "t0" , "t1" , "t2" , "a0" , "a1" , "a2" , "a3" , "a4" , "a5" ] ,
413+ Self :: Rv32E | Self :: Rv64E => {
414+ vec ! [ "ra" , "t0" , "t1" , "t2" , "a0" , "a1" , "a2" , "a3" , "a4" , "a5" ]
415+ }
416+ }
417+ }
418+
419+ /// Standard RISC-V ABI requires the stack to be 16-byte aligned.
420+ /// However, in LLVM, for RV32E and RV64E, the stack must be 4-byte aligned
421+ /// to be compatible with the implementation of ilp32e in GCC
422+ ///
423+ /// Related: https://llvm.org/docs/RISCVUsage.html
424+ const fn byte_alignment ( & self ) -> usize {
425+ match self {
426+ Self :: Rv32E | Self :: Rv64E => 4 ,
427+ _ => 16 ,
417428 }
418429 }
419430}
@@ -474,8 +485,9 @@ pub fn weak_start_trap(_input: TokenStream) -> TokenStream {
474485
475486 let width = arch. width ( ) ;
476487 let trap_size = arch. trap_frame ( ) . len ( ) ;
488+ let byte_alignment = arch. byte_alignment ( ) ;
477489 // ensure we do not break that sp is 16-byte aligned
478- if ( trap_size * width) % 16 != 0 {
490+ if ( trap_size * width) % byte_alignment != 0 {
479491 return parse:: Error :: new ( Span :: call_site ( ) , "Trap frame size must be 16-byte aligned" )
480492 . to_compile_error ( )
481493 . into ( ) ;
0 commit comments