@@ -383,21 +383,21 @@ impl RiscvArch {
383
383
}
384
384
}
385
385
386
- fn width ( & self ) -> usize {
386
+ const fn width ( & self ) -> usize {
387
387
match self {
388
388
Self :: Rv32I | Self :: Rv32E => 4 ,
389
389
Self :: Rv64I | Self :: Rv64E => 8 ,
390
390
}
391
391
}
392
392
393
- fn store ( & self ) -> & str {
393
+ const fn store ( & self ) -> & str {
394
394
match self {
395
395
Self :: Rv32I | Self :: Rv32E => "sw" ,
396
396
Self :: Rv64I | Self :: Rv64E => "sd" ,
397
397
}
398
398
}
399
399
400
- fn load ( & self ) -> & str {
400
+ const fn load ( & self ) -> & str {
401
401
match self {
402
402
Self :: Rv32I | Self :: Rv32E => "lw" ,
403
403
Self :: Rv64I | Self :: Rv64E => "ld" ,
@@ -410,10 +410,21 @@ impl RiscvArch {
410
410
"ra" , "t0" , "t1" , "t2" , "t3" , "t4" , "t5" , "t6" , "a0" , "a1" , "a2" , "a3" , "a4" , "a5" ,
411
411
"a6" , "a7" ,
412
412
] ,
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 ,
417
428
}
418
429
}
419
430
}
@@ -474,8 +485,9 @@ pub fn weak_start_trap(_input: TokenStream) -> TokenStream {
474
485
475
486
let width = arch. width ( ) ;
476
487
let trap_size = arch. trap_frame ( ) . len ( ) ;
488
+ let byte_alignment = arch. byte_alignment ( ) ;
477
489
// 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 {
479
491
return parse:: Error :: new ( Span :: call_site ( ) , "Trap frame size must be 16-byte aligned" )
480
492
. to_compile_error ( )
481
493
. into ( ) ;
0 commit comments