home *** CD-ROM | disk | FTP | other *** search
- GET h.asmregs
-
- AREA |C$$code|, CODE, READONLY
-
- SWIReturnInst LDR pc, [sp, #0*4]
-
- EXPORT swix
- swix ROUT
- ORR r0, r0, #&20000
-
- EXPORT swi
- swi ROUT
-
- ; Construct a stack frame that looks something like this:
- ; returnval
- ; LDMIA r12!, {r0..rn}
- ; SWI xxxxxx
- ; LDR pc, [sp]
- ; saved r4-r11,lr
- ; saved r1
- ; saved input values (r2...rn)
-
- STMFD sp!, {r1-r3} ; Save r1 and put 1st two variadic args on stack
- BIC r2, r0, #&ff000000
- ORR r2, r2, #&ef000000 ; Construct SWI instruction
- ADR r0, SWIReturn
- TST r1, #&200000 ; bit for write flags
- ADRNE r0, SWIReturnFlags
- BIC r1, r1, #&ff000000 ; Construct LDMIA R12!, {regs} instruction, if
- BICS r1, r1, #&00ff0000 ; {regs} = {} (IE no input regs) we must not
- ORRNE r1, r1, #&e8000000 ; use an LDMIA R12!, {} instruction as this is an
- ORRNE r1, r1, #&00bC0000 ; invalid instruction, we use a suitable NOP instead
- MOVEQ r1, #0 ; 0 = opcode for ANDEQ r0, r0, r0 (a suitable NOP)
- LDR r3, SWIReturnInst
- STMFD sp!, {r0-r9,r11,lr} ; Save regs and set up SWI call routine (in R0-R3)
- ADD r12, sp, #(12+1)*4 ; Point R12 at input regs on stack.
- ADD pc, sp, #4 ; Call routine on stack
- SWIReturnFlags
- LDR r11, [r12], #4
- STR pc, [r11] ; write flags
- SWIReturn
- LDR lr, [sp, #(12+0)*4] ; Fetch reg mask again
- MOVS lr, lr, ASL #1 ; Shift out setting C if R0 to be written, N
- LDRCS r11, [r12], #4 ; if R1 to be written.
- STRCS r0, [r11]
- LDRMI r11, [r12], #4
- STRMI r1, [r11]
- MOVS lr, lr, ASL #2 ; Shift 2 bits each time for the next 2 regs
- LDRCS r11, [r12], #4
- STRCS r2, [r11]
- LDRMI r11, [r12], #4
- STRMI r3, [r11]
- MOVS lr, lr, ASL #2
- LDRCS r11, [r12], #4
- STRCS r4, [r11]
- LDRMI r11, [r12], #4
- STRMI r5, [r11]
- MOVS lr, lr, ASL #2
- LDRCS r11, [r12], #4
- STRCS r6, [r11]
- LDRMI r11, [r12], #4
- STRMI r7, [r11]
- MOVS lr, lr, ASL #2
- LDRCS r11, [r12], #4
- STRCS r8, [r11]
- LDRMI r11, [r12], #4
- STRMI r9, [r11]
- LDR r1, [sp, #2*4]
- TST r1, #&20000 ; X-bit clear
- CMPEQ pc, #&80000000 ; SET V flag if so, so R0 not cleared
- MOVVC r0, #0 ; Clear R0 if no error (or X-bit clear)
- ADD sp, sp, #4*4 ; Drop SWI call routine
- LDMIA sp!, {r4-r9,r11,lr}
- ADD sp, sp, #3*4 ; Drop saved R1 and 1st two variadic args.
- MOVS pc, lr
-
- END
-