From 8d58adb3ba20869512bf3995b7e9f58fd234f091 Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Sat, 12 Dec 2020 05:57:58 +0000 Subject: [PATCH] sh: fix up setcontext/swapcontext --- arch/sh/setcontext.S | 45 ++++++++++++++++++++++++----------------- arch/sh/swapcontext.S | 47 +++++++++++++++++++++++++------------------ 2 files changed, 53 insertions(+), 39 deletions(-) diff --git a/arch/sh/setcontext.S b/arch/sh/setcontext.S index 2e05fda..1bf283c 100644 --- a/arch/sh/setcontext.S +++ b/arch/sh/setcontext.S @@ -17,8 +17,20 @@ ALIAS(setcontext, libucontext_setcontext) FUNC(libucontext_setcontext) mov r4, r0 - add #(REG_OFFSET(REG_PC)), r0 /* restore PR */ - mov.l @r0+, r2 + add #(REG_OFFSET(5)), r0 /* restore GPRs r5-15 */ + mov.l @r0+, r5 + mov.l @r0+, r6 + mov.l @r0+, r7 + mov.l @r0+, r8 + mov.l @r0+, r9 + mov.l @r0+, r10 + mov.l @r0+, r11 + mov.l @r0+, r12 + mov.l @r0+, r13 + mov.l @r0+, r14 + mov.l @r0+, r15 + + mov.l @r0+, r2 /* restore PR */ lds.l @r0+, pr mov.l @r0+, r1 /* restore T-flag */ @@ -30,23 +42,18 @@ FUNC(libucontext_setcontext) lds.l @r0+, macl mov r4, r0 /* bring r0 back to the top of the context */ + add #(REG_OFFSET(0)), r1 /* restore r0 into r1 (temporarily) */ + mov.l r1, @-r15 /* push to stack from r1 */ + mov.l r2, @-r15 /* push PC to stack */ - mov.l @(REG_OFFSET(1), r0), r1 /* restore GPRs r1-15 */ - mov.l @(REG_OFFSET(2), r0), r2 - mov.l @(REG_OFFSET(3), r0), r3 - mov.l @(REG_OFFSET(4), r0), r4 - mov.l @(REG_OFFSET(5), r0), r5 - mov.l @(REG_OFFSET(6), r0), r6 - mov.l @(REG_OFFSET(7), r0), r7 - mov.l @(REG_OFFSET(8), r0), r8 - mov.l @(REG_OFFSET(9), r0), r9 - mov.l @(REG_OFFSET(10), r0), r10 - mov.l @(REG_OFFSET(11), r0), r11 - mov.l @(REG_OFFSET(12), r0), r12 - mov.l @(REG_OFFSET(13), r0), r13 - mov.l @(REG_OFFSET(14), r0), r14 - mov.l @(REG_OFFSET(15), r0), r15 + mov.l @(REG_OFFSET(1), r0), r1 /* restore real r1 */ + mov.l @(REG_OFFSET(2), r0), r2 /* restore real r2 */ + mov.l @(REG_OFFSET(3), r0), r3 /* restore real r2 */ + mov.l @(REG_OFFSET(4), r0), r4 /* restore real r2 */ - mov.l @(REG_OFFSET(REG_PC), r0), r0 - jmp @r0 + mov.l @r15+, r0 /* pop PC from stack */ + + jmp @r0 /* jump to new PC */ + + mov.l @r15+, r0 /* pop original r0 from stack */ END(libucontext_setcontext) diff --git a/arch/sh/swapcontext.S b/arch/sh/swapcontext.S index 607d385..1a09ee8 100644 --- a/arch/sh/swapcontext.S +++ b/arch/sh/swapcontext.S @@ -52,8 +52,19 @@ FUNC(libucontext_swapcontext) mov r5, r0 /* now restore the new context */ - add #(REG_OFFSET(REG_PC)), r0 /* restore PR */ - mov.l @r0+, r2 + add #(REG_OFFSET(6)), r0 /* restore GPRs r6-15 */ + mov.l @r0+, r6 + mov.l @r0+, r7 + mov.l @r0+, r8 + mov.l @r0+, r9 + mov.l @r0+, r10 + mov.l @r0+, r11 + mov.l @r0+, r12 + mov.l @r0+, r13 + mov.l @r0+, r14 + mov.l @r0+, r15 + + mov.l @r0+, r2 /* restore PR */ lds.l @r0+, pr mov.l @r0+, r1 /* restore T-flag */ @@ -64,24 +75,20 @@ FUNC(libucontext_swapcontext) lds.l @r0+, mach /* load mach/macl registers */ lds.l @r0+, macl - mov r5, r0 /* bring r5 back to the top of the context */ + mov r5, r0 /* bring r0 back to the top of the context */ + add #(REG_OFFSET(0)), r1 /* restore r0 into r1 (temporarily) */ + mov.l r1, @-r15 /* push to stack from r1 */ + mov.l r2, @-r15 /* push PC to stack */ - mov.l @(REG_OFFSET(1), r0), r1 /* restore GPRs r1-15 */ - mov.l @(REG_OFFSET(2), r0), r2 - mov.l @(REG_OFFSET(3), r0), r3 - mov.l @(REG_OFFSET(4), r0), r4 - mov.l @(REG_OFFSET(5), r0), r5 - mov.l @(REG_OFFSET(6), r0), r6 - mov.l @(REG_OFFSET(7), r0), r7 - mov.l @(REG_OFFSET(8), r0), r8 - mov.l @(REG_OFFSET(9), r0), r9 - mov.l @(REG_OFFSET(10), r0), r10 - mov.l @(REG_OFFSET(11), r0), r11 - mov.l @(REG_OFFSET(12), r0), r12 - mov.l @(REG_OFFSET(13), r0), r13 - mov.l @(REG_OFFSET(14), r0), r14 - mov.l @(REG_OFFSET(15), r0), r15 + mov.l @(REG_OFFSET(1), r0), r1 /* restore real r1 */ + mov.l @(REG_OFFSET(2), r0), r2 /* restore real r2 */ + mov.l @(REG_OFFSET(3), r0), r3 /* restore real r3 */ + mov.l @(REG_OFFSET(4), r0), r4 /* restore real r4 */ + mov.l @(REG_OFFSET(5), r0), r5 /* restore real r5 */ - mov.l @(REG_OFFSET(REG_PC), r0), r0 - jmp @r0 + mov.l @r15+, r0 /* pop PC from stack */ + + jmp @r0 /* jump to new PC */ + + mov.l @r15+, r0 /* pop original r0 from stack */ END(libucontext_swapcontext)