diff --git a/kernel/s/swiv b/kernel/s/swiv index 305679c36e86389e578acf25a3f000cdb7e4dcd1..25f9ab0726f7f717c7f1e782b2e23e768ac33f8d 100644 --- a/kernel/s/swiv +++ b/kernel/s/swiv @@ -30,10 +30,175 @@ lr RN 14 pc RN 15 + GET s.h_StrongA + AREA |C$$code|, CODE, READONLY EXPORT |_swix| EXPORT |_swi| + + [ StrongARM + ; tedious static _swi(x) entry handling, to avoid generating dynamic code, and + ; requiring an expensive XOS_SynchroniseCodeAreas + +|_swix| + ORR r0, r0, #&20000 + TST r1, #&FF0 ; check for use of input regs. 4 to 9, or of block param + BNE swix_even_more_tedious ; if so, do full stuff + + STMFD sp!, {r2, r3} ; put 1st two variadic args on stack + STMDB sp!, {r1, r4-r9, lr} ; save stuff + + SUB sp, sp, #5*4 ; so we can use tail code common with dynamic version (and room for regs stash) + + ADD r14, sp, #(5+8)*4 ; r14 -> input args + MOV r12, r0 ; target SWI code + STR fp, [sp] ; stash fp + + MOV r11, r1 + TST r11, #&001 + LDRNE r0, [r14], #4 + TST r11, #&002 + LDRNE r1, [r14], #4 + TST r11, #&004 + LDRNE r2, [r14], #4 + TST r11, #&008 + LDRNE r3, [r14], #4 + + STR r14, [sp, #4] ; stash args ptr + SWI XOS_CallASWIR12 + LDMIA sp, {fp, ip} ; restore (ip -> args) + B SWIXReturn + +swix_even_more_tedious +|_swi| + STMFD sp!, {r2, r3} ; put 1st two variadic args on stack + STMDB sp!, {r1, r4-r9, lr} ; save stuff + + SUB sp, sp, #5*4 ; so we can use tail code common with dynamic version (and room for regs stash) + + ADD r14, sp, #(5+8)*4 ; r14 -> input args + MOV r12, r0 ; target SWI code + STR fp, [sp] ; stash fp + + + MOV r11, r1 + TST r11, #&001 + LDRNE r0, [r14], #4 + TST r11, #&002 + LDRNE r1, [r14], #4 + TST r11, #&004 + LDRNE r2, [r14], #4 + TST r11, #&008 + LDRNE r3, [r14], #4 + TST r11, #&010 + LDRNE r4, [r14], #4 + TST r11, #&020 + LDRNE r5, [r14], #4 + TST r11, #&040 + LDRNE r6, [r14], #4 + TST r11, #&080 + LDRNE r7, [r14], #4 + TST r11, #&100 + LDRNE r8, [r14], #4 + TST r11, #&200 + LDRNE r9, [r14], #4 + + STR r14, [sp, #4] ; stash args ptr + TST r11, #&800 ; use of block parameter input? + BLNE swi_blockhead ; if so, handle it and... + LDRNE r14, [sp, #4] ; ...restore arg ptr + + TST r12, #&20000 ; if non X SWI, could be a return value register + BEQ swi_beyond_a_joke + + SWI XOS_CallASWIR12 + LDMIA sp, {fp, ip} ; restore (ip -> args) + B SWIXReturn + +swi_beyond_a_joke +;so we have to deal with a return value then + SWI XOS_CallASWIR12 + LDMIA sp, {fp, ip} ;restore (ip -> args) + STR pc, [sp, #4*4]! + LDR lr, [sp, #1*4] +;right, if R0 is also required as an output param, we'd better sort that first + TST lr,#&80000000 + BEQ swi_beyond_a_joke_R0safe + LDRNE lr, [r12], #4 + STRNE r0, [lr] + LDR lr, [sp, #1*4] + BIC lr,lr,#&80000000 ;done it now + STR lr, [sp, #1*4] +swi_beyond_a_joke_R0safe + ANDS lr, lr, #&000F0000 ;select return value register + BEQ SWIReturn2 + CMP lr, #&00010000 + MOVEQ r0, r1 + CMP lr, #&00020000 + MOVEQ r0, r2 + CMP lr, #&00030000 + MOVEQ r0, r3 + CMP lr, #&00040000 + MOVEQ r0, r4 + CMP lr, #&00050000 + MOVEQ r0, r5 + CMP lr, #&00060000 + MOVEQ r0, r6 + CMP lr, #&00070000 + MOVEQ r0, r7 + CMP lr, #&00080000 + MOVEQ r0, r8 + CMP lr, #&00090000 + MOVEQ r0, r9 + CMP lr, #&000F0000 ;for goodness sake! + LDREQ r0, [sp] + B SWIReturn2 + +swi_blockhead + STMFD sp!, {r10-r12, lr} + LDR r12, [sp, #(4+1)*4] ;pick up args ptr from stack +;r12 currently -> first output arg, so crank it past them + MOVS r11, r11, ASL #1 + ADDCS r12, r12, #4 ;tests R0 output bit + ADDMI r12, r12, #4 ;tests R1 output bit + MOV r10, #5 ;5 more reg bit pairs to go (includes PC and one dummy) +swi_blockhead1 + MOVS r11, r11, ASL #2 + ADDCS r12, r12, #4 + ADDMI r12, r12, #4 + SUBS r10, r10, #1 + BNE swi_blockhead1 +;now r12 -> parameter block args on stack + LDR r11, [sp,#4] + ANDS r11, r11, #&f000 ;select reg for parameter block pointer + MOVEQ r0, r12 + CMP r11, #&1000 + MOVEQ r1, r12 + CMP r11, #&2000 + MOVEQ r2, r12 + CMP r11, #&3000 + MOVEQ r3, r12 + CMP r11, #&4000 + MOVEQ r4, r12 + CMP r11, #&5000 + MOVEQ r5, r12 + CMP r11, #&6000 + MOVEQ r6, r12 + CMP r11, #&7000 + MOVEQ r7, r12 + CMP r11, #&8000 + MOVEQ r8, r12 + CMP r11, #&9000 + MOVEQ r9, r12 + + LDMFD sp!, {r10-r12, pc}^ ;must restore flags + + ] ; StrongARM + + + [ :LNOT: StrongARM + |_swi| ; Construct a stack frame that looks something like this: @@ -73,9 +238,16 @@ swix0 ADD r6, r6, #&ea000000 STMDB sp!, {r0,r2,r3,r5,r6} ADD r12, sp, #(5+8)*4 ; Point R12 at input regs on stack. + [ StrongARMfudge + ; so that dynamic version would at least work + SyncStackCode 5 + ] MOV pc, sp ; Call routine on stack + SWIReturn STR pc, [sp, #4*4]! + ] ; not StrongARM +SWIReturn2 LDR lr, [sp, #1*4] MOVS lr, lr, ASL #1 ; Shift out setting C if R0 to be written, N LDRCS lr, [r12], #4 ; if R1 to be written. @@ -129,6 +301,7 @@ VSetReturn ADD sp, sp, #2 * 4 MOVS pc, lr + [ :LNOT: StrongARM BuildBlockInst MOV r4, #6 AND r2, r1, #&f000 @@ -141,5 +314,6 @@ BuildBlockInst1 SUBS r4, r4, #1 BNE BuildBlockInst1 MOVS pc, lr + ] END diff --git a/rlib/s/swi b/rlib/s/swi index e7656c823f6abefdad731be002c3a9b4e1ca7e10..5c3f1510bd56d1b380b476416eb3be93f497a1a6 100644 --- a/rlib/s/swi +++ b/rlib/s/swi @@ -166,6 +166,15 @@ lr RN 14 pc RN 15 GET rlib.s.asmdefs + GET s.h_StrongA + +;whether to avoid dynamic code for swi veneers + GBLL StaticSWIVeneer +StaticSWIVeneer SETL StrongARM :LAND: {TRUE} + +;fudge needed for StrongARM when dynamic code used + GBLL StrongARMfudge +StrongARMfudge SETL StrongARM :LAND: {TRUE} [ :LNOT:UROM EXPORT |bbc_get| @@ -228,41 +237,77 @@ bbc_vdu SWI XOS_MASK :OR: WriteC ; In a1 contains swi number, a2 points to ARM register structure -os_swi STMDB sp!, {v1-v6, lk} - +os_swi + [ StaticSWIVeneer + STMDB sp!, {v1-v6, lk} + MOV r12, r0 + CMP r1, #0 + BEQ os_swi_noregset + STMDB sp!, {r1} + LDMIA r1, {r0-r9} + SWI XOS_CallASWIR12 + LDMIA sp!, {ip} + STMIA ip, {r0-r9} + LDMIA sp!, {v1-v6, pc}^ +os_swi_noregset + SWI XOS_CallASWIR12 + LDMIA sp!, {v1-v6, pc}^ + | + STMDB sp!, {v1-v6, lk} ORR a1, a1, #SWI_OP ; make into SWI operation - ADR v1, exit_sequence LDMIA v1, {v2,v3} MOVS ip, a2 MOVEQ v2, #0 STMDB sp!, {a1, v2,v3} ; copy SWI and exit code onto stack + [ StrongARMfudge + SyncStackCode 3 + ] LDMNEIA a2, {r0-r9} ; load up registers for SWI if wanted MOV pc, sp ; and jump to the sequence - ; SWI whatever ; <- sp exit_sequence STMIA ip, {r0-r9} LDMIA sp!, {a2-a4, v1-v6, pc}^ ; a2-a4 just to pop stack + ] ; os_error *os_swix(int swicode, os_regset* /*inout*/); ; In a1 contains swi number, a2 points to ARM register structure -os_swix STMDB sp!, {v1-v6, lk} - - ORR a1, a1, #SWI_OP ; make into SWI operation +os_swix + [ StaticSWIVeneer + STMDB sp!, {v1-v6, lk} ORR a1, a1, #XOS_MASK ; make a SWI of V-error type - + MOV r12, r0 + CMP r1, #0 + BEQ os_swix_noregset + STMDB sp!, {r1} + LDMIA r1, {r0-r9} + SWI XOS_CallASWIR12 + LDMIA sp!, {ip} + STMIA ip, {r0-r9} + MOVVC a1, #0 + LDMIA sp!, {v1-v6, pc}^ +os_swix_noregset + SWI XOS_CallASWIR12 + MOVVC a1, #0 + LDMIA sp!, {v1-v6, pc}^ + | + STMDB sp!, {v1-v6, lk} + ORR a1, a1, #XOS_MASK ; make a SWI of V-error type + ORR a1, a1, #SWI_OP ; make into SWI operation ADR v1, xexit_sequence LDMIA v1, {v2,v3,v4,v5} MOVS ip, a2 MOVEQ v2, #0 STMDB sp!, {a1, v2,v3,v4,v5} ; copy SWI and exit code onto stack + [ StrongARMfudge + SyncStackCode 5 + ] LDMNEIA ip, {r0-r9} ; load up registers for SWI if wanted MOV pc, sp ; and jump to the sequence - ; SWI Xwhatever ; <- sp xexit_sequence STMIA ip, {r0-r9} @@ -272,6 +317,8 @@ xexit_sequence ; a3 is junk (LDM) ; Note: CAN NOT move stack past LDM ; before instruction executes + ] + os_swix0 os_swix1 os_swix2 @@ -288,21 +335,36 @@ os_swi3 os_swi4 os_swi5 os_swi6 + [ StaticSWIVeneer + STMDB sp!, {v1-v6, lk} + MOV r12, r0 + MOV a1, a2 + MOV a2, a3 + MOV a3, a4 + ADD lk, sp, #7*4 + LDMIA lk, {a4, v1, v2} + SWI XOS_CallASWIR12 + MOVVC a1, #0 + LDMIA sp!, {v1-v6, pc}^ + | STMDB sp!, {v1-v6, lk} ORR a1, a1, #SWI_OP ADR ip, swi6_exit_sequence LDMIA ip, {ip, lk} STMDB sp!, {a1, ip, lk} + [ StrongARMfudge + SyncStackCode 3 + ] MOV a1, a2 MOV a2, a3 MOV a3, a4 ADD ip, sp, #10 * 4 LDMIA ip, {a4, v1, v2} MOV pc, sp - swi6_exit_sequence MOVVC a1, #0 LDMIA sp!, {a2-a4, v1-v6, pc}^ + ] swi_ret_inst MOV pc, ip @@ -310,9 +372,24 @@ swi_ret_inst os_swix1r ORR a1, a1, #&20000 os_swi1r + [ StaticSWIVeneer + STMDB sp!, {a3, v1-v6, lk} + MOV r12, r0 + MOV r0, a2 + SWI XOS_CallASWIR12 + LDR ip, [sp] + LDMVSIA sp!, {a2, v1-v6, pc}^ + TEQ ip, #0 + STRNE a1, [ip] + MOV a1, #0 + LDMIA sp!, {a2, v1-v6, pc}^ + | ORR a1, a1, #&ef000000 LDR a2, swi_ret_inst STMDB sp!, {a1, a2, a3, v1-v6, lk} + [ StrongARMfudge + SyncStackCode 2 + ] MOV a1, a2 MOV ip, pc MOV pc, sp @@ -322,14 +399,34 @@ os_swi1r STRNE a1, [ip] MOV a1, #0 LDMIA sp!, {a2, v1-v6, pc}^ + ] os_swix2r ORR a1, a1, #&20000 os_swi2r + [ StaticSWIVeneer + STMDB sp!, {a4, v1-v6, lk} + MOV r12, r0 + MOV a1, a2 + MOV a2, a3 + SWI XOS_CallASWIR12 + LDR ip, [sp] + LDMVSIA sp!, {a2, v1-v6, pc}^ + TEQ ip, #0 + STRNE a1, [ip] + LDR ip, [sp, #8 * 4] + TEQ ip, #0 + STRNE a2, [ip] + MOV a1, #0 + LDMIA sp!, {a2, v1-v6, pc}^ + | MOV ip, a2 ORR a1, a1, #&ef000000 LDR a2, swi_ret_inst STMDB sp!, {a1, a2, a4, v1-v6, lk} + [ StrongARMfudge + SyncStackCode 2 + ] MOV a1, ip MOV a2, a3 MOV ip, pc @@ -343,14 +440,37 @@ os_swi2r STRNE a2, [ip] MOV a1, #0 LDMIA sp!, {a2, v1-v6, pc}^ + ] os_swix3r ORR a1, a1, #&20000 os_swi3r + [ StaticSWIVeneer + STMDB sp!, {v1-v6, lk} + MOV r12, r0 + MOV a1, a2 + MOV a2, a3 + MOV a3, a4 + SWI XOS_CallASWIR12 + ADD ip, sp, #7 * 4 + LDMIA ip, {v1, v2, v3} + LDMVSIA sp!, {v1-v6, pc}^ + TEQ v1, #0 + STRNE a1, [v1] + TEQ v2, #0 + STRNE a2, [v2] + TEQ v3, #0 + STRNE a3, [v3] + MOV a1, #0 + LDMIA sp!, {v1-v6, pc}^ + | MOV ip, a2 ORR a1, a1, #&ef000000 LDR a2, swi_ret_inst STMDB sp!, {a1, a2, v1-v6, lk} + [ StrongARMfudge + SyncStackCode 2 + ] MOV a1, ip MOV a2, a3 MOV a3, a4 @@ -367,14 +487,40 @@ os_swi3r STRNE a3, [v3] MOV a1, #0 LDMIA sp!, {a2, a3, v1-v6, pc}^ + ] os_swix4r ORR a1, a1, #&20000 os_swi4r + [ StaticSWIVeneer + STMDB sp!, {v1-v6, lk} + MOV r12, r0 + MOV a1, a2 + MOV a2, a3 + MOV a3, a4 + LDR a4, [sp, #7 * 4] + SWI XOS_CallASWIR12 + ADD ip, sp, #8 * 4 + LDMIA ip, {v1-v4} + LDMVSIA sp!, {v1-v6, pc}^ + TEQ v1, #0 + STRNE a1, [v1] + TEQ v2, #0 + STRNE a2, [v2] + TEQ v3, #0 + STRNE a3, [v3] + TEQ v4, #0 + STRNE a4, [v4] + MOV a1, #0 + LDMIA sp!, {v1-v6, pc}^ + | MOV ip, a2 ORR a1, a1, #&ef000000 LDR a2, swi_ret_inst STMDB sp!, {a1, a2, v1-v6, lk} + [ StrongARMfudge + SyncStackCode 2 + ] MOV a1, ip MOV a2, a3 MOV a3, a4 @@ -394,14 +540,43 @@ os_swi4r STRNE a4, [v4] MOV a1, #0 LDMIA sp!, {a2, a3, v1-v6, pc}^ + ] os_swix5r ORR a1, a1, #&20000 os_swi5r + [ StaticSWIVeneer + STMDB sp!, {v1-v6, lk} + MOV r12, r0 + MOV a1, a2 + MOV a2, a3 + MOV a3, a4 + ADD lk, sp, #7 * 4 + LDMIA lk, {a4, v1} + SWI XOS_CallASWIR12 + ADD ip, sp, #9 * 4 + LDMIA ip, {v3-v6, ip} + LDMVSIA sp!, {v1-v6, pc}^ + TEQ v3, #0 + STRNE a1, [v3] + TEQ v4, #0 + STRNE a2, [v4] + TEQ v5, #0 + STRNE a3, [v5] + TEQ v6, #0 + STRNE a4, [v6] + TEQ ip, #0 + STRNE v1, [ip] + MOV a1, #0 + LDMIA sp!, {v1-v6, pc}^ + | MOV ip, a2 ORR a1, a1, #&ef000000 LDR a2, swi_ret_inst STMDB sp!, {a1, a2, v1-v6, lk} + [ StrongARMfudge + SyncStackCode 2 + ] MOV a1, ip MOV a2, a3 MOV a3, a4 @@ -424,14 +599,45 @@ os_swi5r STRNE v1, [ip] MOV a1, #0 LDMIA sp!, {a3, a4, v1-v6, pc}^ + ] os_swix6r ORR a1, a1, #&20000 os_swi6r + [ StaticSWIVeneer + STMDB sp!, {v1-v6, lk} + MOV r12, r0 + MOV a1, a2 + MOV a2, a3 + MOV a3, a4 + ADD lk, sp, #7 * 4 + LDMIA lk, {a4, v1, v2} + SWI XOS_CallASWIR12 + ADD ip, sp, #10 * 4 + LDMIA ip, {v3-v6, ip, lk} ; APCS-R assumption here + LDMVSIA sp!, {v1-v6, pc}^ + TEQ v3, #0 + STRNE a1, [v3] + TEQ v4, #0 + STRNE a2, [v4] + TEQ v5, #0 + STRNE a3, [v5] + TEQ v6, #0 + STRNE a4, [v6] + TEQ ip, #0 + STRNE v1, [ip] + TEQ lk, #0 + STRNE v2, [lk] + MOV a1, #0 + LDMIA sp!, {v1-v6, pc}^ + | MOV ip, a2 ORR a1, a1, #&ef000000 LDR a2, swi_ret_inst STMDB sp!, {a1, a2, v1-v6, lk} + [ StrongARMfudge + SyncStackCode 2 + ] MOV a1, ip MOV a2, a3 MOV a3, a4 @@ -456,6 +662,7 @@ os_swi6r STRNE v2, [lk] MOV a1, #0 LDMIA sp!, {a3, a4, v1-v6, pc}^ + ] os_byte STMDB sp!, {lk} diff --git a/s/arthurasm b/s/arthurasm index 8276d3877cbbfbc847774a02957953ebf46cf261..65211c1df0c93af45a7dd62a288d380e1208ad5b 100644 --- a/s/arthurasm +++ b/s/arthurasm @@ -15,6 +15,8 @@ ; >s.ArthurAsm ; Copyright (C) Acorn Computers Ltd., 1988 + GET s.h_StrongA + SWI_OP * &ef000000 ; SWIAL op-code ; in s.ArthurAsm ... @@ -80,7 +82,9 @@ $Pfx.swi ORR a2, a2, #SWI_OP ; make into swi operation LDR a4, return_inst ; get a return instruction STMDB sp!, {a2,a4} ; then put both on the stack - + [ StrongARM + SyncStackCode 2 + ] MOV ip, a1 ; save return pointer out of way LDMIA a3, {a1-v6} ; get user's input registers @@ -113,7 +117,9 @@ $Pfx.swix ORR a1, a1, #X ; make a swi of V-error type LDR a3, return_inst ; get a return instruction STMDB sp!, {a1,a3} ; then put both on the stack - + [ StrongARM + SyncStackCode 2 + ] MOV ip, a2 ; save return pointer out of way LDMIA a2, {a1-v6} ; get user's input registers diff --git a/s/initmodule b/s/initmodule index 0dc0a7b63ffd0ebd845815f1e6becd1ffb4f67ee..80035f4fa0620d16506725482a0fd1300689138c 100644 --- a/s/initmodule +++ b/s/initmodule @@ -19,6 +19,8 @@ ; ; IDJ: 19-Jul-91: removed message C03 + GET s.h_StrongA + GBLL SharedLibrary SharedLibrary SETL {TRUE} @@ -442,7 +444,12 @@ EndStubInit LDR r12, [r13, #4] ; r1 out STR r5, [r12, #SC_SLOffset+SL_Lib_Offset] - ; return + [ StrongARM + ; patched branch code requires SynchroniseCodeAreas + MOV r0,#0 ;fully synchronise (too lazy to narrow down address range) + SWI XOS_SynchroniseCodeAreas + ] + MOV r6, #LibraryVersionNumber LDMFD r13!, {r0-r5, pc}^ diff --git a/s/overmgr b/s/overmgr index 3585d9ef7539643f5178eb1ff58d664f1fd3da82..e175e8a6e60ab226ee72e611631111e32d5a18cf 100644 --- a/s/overmgr +++ b/s/overmgr @@ -41,6 +41,8 @@ ; ; ENTRIES: + GET s.h_StrongA + EXPORT |Image$$overlay_init| EXPORT |Image$$load_seg| @@ -302,6 +304,11 @@ Retry STR R2, [R3], #-4 ;>the segment's PCIT SUBS R1, R1, #4 ;>section into the BGT %B01 ;>global PCIT + [ StrongARM + ;there may have been some poking about with code, for invalidated returns, so synchronise + MOV r0,#0 + SWI XOS_SynchroniseCodeAreas + ] ; Finally, continue, unabashed... LDMIA IP, {R0-R8, LR, PC}^ diff --git a/s/version b/s/version index 9aebc2fa503c849823abb656c5e5e1f467410ec2..0069f06ed2168e377b4fbd5ab1ff0189e343854e 100644 --- a/s/version +++ b/s/version @@ -12,5 +12,5 @@ ; See the License for the specific language governing permissions and ; limitations under the License. ; - DCB "4.79 (01 Mar 1995)" + DCB "4.84 (04 Jul 1996)" END