Skip to content

Commit

Permalink
core: riscv: Use sp as base register of load instructions
Browse files Browse the repository at this point in the history
Use sp as base register of load instructions can reduce code size if RVC
extension is enabled to generate 16-bit instructions. The following code
shows the difference after applying this commit.

Before:
    f10009da:	0d053d83          	ld	s11,208(a0)
    f10009de:	0c853d03          	ld	s10,200(a0)
    f10009e2:	0c053c83          	ld	s9,192(a0)
    f10009e6:	0b853c03          	ld	s8,184(a0)
    f10009ea:	0b053b83          	ld	s7,176(a0)
    f10009ee:	0a853b03          	ld	s6,168(a0)
    f10009f2:	0a053a83          	ld	s5,160(a0)
    f10009f6:	09853a03          	ld	s4,152(a0)
    f10009fa:	09053983          	ld	s3,144(a0)
    f10009fe:	08853903          	ld	s2,136(a0)

After:
    f10009a6:	6dce                	ld	s11,208(sp)
    f10009a8:	6d2e                	ld	s10,200(sp)
    f10009aa:	6c8e                	ld	s9,192(sp)
    f10009ac:	7c6a                	ld	s8,184(sp)
    f10009ae:	7bca                	ld	s7,176(sp)
    f10009b0:	7b2a                	ld	s6,168(sp)
    f10009b2:	7a8a                	ld	s5,160(sp)
    f10009b4:	6a6a                	ld	s4,152(sp)
    f10009b6:	69ca                	ld	s3,144(sp)
    f10009b8:	692a                	ld	s2,136(sp)

Signed-off-by: Alvin Chang <alvinga@andestech.com>
  • Loading branch information
gagachang committed Sep 16, 2024
1 parent 95acc3f commit 6f750c6
Showing 1 changed file with 30 additions and 20 deletions.
50 changes: 30 additions & 20 deletions core/arch/riscv/kernel/thread_rv.S
Original file line number Diff line number Diff line change
Expand Up @@ -705,22 +705,28 @@ FUNC __thread_enter_user_mode , :
*/
csrw CSR_XSCRATCH, tp

/* Move struct thread_ctx_regs *regs to sp to reduce code size */
mv sp, a0

/* Set exception return PC */
load_xregs a0, THREAD_CTX_REG_EPC, REG_S0
load_xregs sp, THREAD_CTX_REG_EPC, REG_S0
csrw CSR_XEPC, s0
/* Set user ie */
load_xregs a0, THREAD_CTX_REG_IE, REG_S0
load_xregs sp, THREAD_CTX_REG_IE, REG_S0
csrw CSR_XIE, s0
/* Set user status */
load_xregs a0, THREAD_CTX_REG_STATUS, REG_S0
load_xregs sp, THREAD_CTX_REG_STATUS, REG_S0
csrw CSR_XSTATUS, s0
/* Load the rest of the general purpose registers */
load_xregs a0, THREAD_CTX_REG_RA, REG_RA, REG_TP
load_xregs a0, THREAD_CTX_REG_T0, REG_T0, REG_T2
load_xregs a0, THREAD_CTX_REG_S0, REG_S0, REG_S1
load_xregs a0, THREAD_CTX_REG_S2, REG_S2, REG_S11
load_xregs a0, THREAD_CTX_REG_T3, REG_T3, REG_T6
load_xregs a0, THREAD_CTX_REG_A0, REG_A0, REG_A7
load_xregs sp, THREAD_CTX_REG_RA, REG_RA
load_xregs sp, THREAD_CTX_REG_GP, REG_GP
load_xregs sp, THREAD_CTX_REG_TP, REG_TP
load_xregs sp, THREAD_CTX_REG_T0, REG_T0, REG_T2
load_xregs sp, THREAD_CTX_REG_S0, REG_S0, REG_S1
load_xregs sp, THREAD_CTX_REG_A0, REG_A0, REG_A7
load_xregs sp, THREAD_CTX_REG_S2, REG_S2, REG_S11
load_xregs sp, THREAD_CTX_REG_T3, REG_T3, REG_T6
load_xregs sp, THREAD_CTX_REG_SP, REG_SP /* sp must be last one */

/* Jump into user mode */
XRET
Expand All @@ -731,16 +737,17 @@ FUNC thread_resume , :
/* Disable global interrupts first */
csrc CSR_XSTATUS, CSR_XSTATUS_IE

/* Move struct thread_ctx_regs *regs to sp to reduce code size */
mv sp, a0

/* Restore epc */
load_xregs a0, THREAD_CTX_REG_EPC, REG_T0
load_xregs sp, THREAD_CTX_REG_EPC, REG_T0
csrw CSR_XEPC, t0

/* Restore ie */
load_xregs a0, THREAD_CTX_REG_IE, REG_T0
load_xregs sp, THREAD_CTX_REG_IE, REG_T0
csrw CSR_XIE, t0

/* Restore status */
load_xregs a0, THREAD_CTX_REG_STATUS, REG_T0
load_xregs sp, THREAD_CTX_REG_STATUS, REG_T0
csrw CSR_XSTATUS, t0

/* Check if previous privilege mode by status.SPP */
Expand All @@ -753,12 +760,15 @@ FUNC thread_resume , :
csrw CSR_XSCRATCH, tp
2:
/* Restore all general-purpose registers */
load_xregs a0, THREAD_CTX_REG_RA, REG_RA, REG_TP
load_xregs a0, THREAD_CTX_REG_T0, REG_T0, REG_T2
load_xregs a0, THREAD_CTX_REG_S0, REG_S0, REG_S1
load_xregs a0, THREAD_CTX_REG_S2, REG_S2, REG_S11
load_xregs a0, THREAD_CTX_REG_T3, REG_T3, REG_T6
load_xregs a0, THREAD_CTX_REG_A0, REG_A0, REG_A7
load_xregs sp, THREAD_CTX_REG_RA, REG_RA
load_xregs sp, THREAD_CTX_REG_GP, REG_GP
load_xregs sp, THREAD_CTX_REG_TP, REG_TP
load_xregs sp, THREAD_CTX_REG_T0, REG_T0, REG_T2
load_xregs sp, THREAD_CTX_REG_S0, REG_S0, REG_S1
load_xregs sp, THREAD_CTX_REG_A0, REG_A0, REG_A7
load_xregs sp, THREAD_CTX_REG_S2, REG_S2, REG_S11
load_xregs sp, THREAD_CTX_REG_T3, REG_T3, REG_T6
load_xregs sp, THREAD_CTX_REG_SP, REG_SP /* sp must be last one */

XRET
END_FUNC thread_resume
Expand Down

0 comments on commit 6f750c6

Please sign in to comment.