diff options
author | PikalaxALT <pikalaxalt@gmail.com> | 2017-12-15 09:38:53 -0500 |
---|---|---|
committer | PikalaxALT <pikalaxalt@gmail.com> | 2017-12-15 09:39:34 -0500 |
commit | f95a4a932476be2ba99e2fd081e8d2bc6ea12813 (patch) | |
tree | 75f67192cb2d7b7b575c94edda318e475239b63c /newlib/libc/sys/a29khif/signal.s | |
parent | f60aca96985e68c7d8a52eb7bc955fb80e132f73 (diff) |
Import newlib and create makefile
Diffstat (limited to 'newlib/libc/sys/a29khif/signal.s')
-rw-r--r-- | newlib/libc/sys/a29khif/signal.s | 452 |
1 files changed, 452 insertions, 0 deletions
diff --git a/newlib/libc/sys/a29khif/signal.s b/newlib/libc/sys/a29khif/signal.s new file mode 100644 index 0000000..29273a0 --- /dev/null +++ b/newlib/libc/sys/a29khif/signal.s @@ -0,0 +1,452 @@ +;@(#)signal.s 2.15 90/10/14 21:57:55, AMD +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Copyright 1990 Advanced Micro Devices, Inc. +; +; This software is the property of Advanced Micro Devices, Inc (AMD) which +; specifically grants the user the right to modify, use and distribute this +; software provided this notice is not removed or altered. All other rights +; are reserved by AMD. +; +; AMD MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO THIS +; SOFTWARE. IN NO EVENT SHALL AMD BE LIABLE FOR INCIDENTAL OR CONSEQUENTIAL +; DAMAGES IN CONNECTION WITH OR ARISING FROM THE FURNISHING, PERFORMANCE, OR +; USE OF THIS SOFTWARE. +; +; So that all may benefit from your experience, please report any problems +; or suggestions about this software to the 29K Technical Support Center at +; 800-29-29-AMD (800-292-9263) in the USA, or 0800-89-1131 in the UK, or +; 0031-11-1129 in Japan, toll free. The direct dial number is 512-462-4118. +; +; Advanced Micro Devices, Inc. +; 29K Support Products +; Mail Stop 573 +; 5900 E. Ben White Blvd. +; Austin, TX 78741 +; 800-292-9263 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + .file "signal.s" + +; SigEntry is the address of an array of C-level user code signal handlers. +; They must return to the top-level before doing a sigret() return function. +; Nested signals are supported. + + .extern V_SPILL, V_FILL + .extern fill ; In crt0.s + + .align 4 + .comm WindowSize, 4 + .data +SigEntry: + .word 0 ; reserved + .word 0 ; adds. of #2 SIGINT handler + .word 0 ; reserved + .word 0 ; reserved + .word 0 ; reserved + .word 0 ; reserved + .word 0 ; reserved + .word 0 ; adds. of #8 SIGFPE handler + + .text + + .reg v0, gr96 + .reg v1, gr97 + .reg v2, gr98 + .reg v3, gr99 + + .reg tav, gr121 + .reg tpc, gr122 + .reg lrp, gr123 + .reg slp, gr124 + .reg msp, gr125 + .reg rab, gr126 + .reg rfb, gr127 + +;=================================================================== setjmp() +; int +; setjmp(label_t jmpbuf) +; { +; *jmpbuf = {gr1, msp, lr0, lr1}; +; return 0; +; } +; + .global _setjmp +_setjmp: + store 0, 0, gr1, lr2 + add lr2, lr2, 4 + store 0, 0, msp, lr2 + add lr2, lr2, 4 + store 0, 0, lr0, lr2 + add lr2, lr2, 4 + store 0, 0, lr1, lr2 + jmpi lr0 + const v0, 0 +; +;==================================================================== longjmp() +; int +; longjmp(label_t jmpbuf, int value) +; { +; /* BUG: check for this +; if (msp > jmpbuf->msp || gr1 > jmpbuf->gr1) +; longjmperror(); +; */ +; +; gr1 = jmpbuf->gr1; +; lr2addr = jmpbuf->gr1 + 8; +; msp = jmpbuf->msp; +; +; /* saved lr1 is invalid if saved lr2addr > rfb */ +; if (lr2addr > rfb) { +; /* +; * None of the registers are useful. +; * Set rfb to lr2addr - 512 & rab to rfb - 512. +; * the FILL assert will take care of filling +; */ +; lr1 = jmpbuf->lr1; +; rab = lr2addr - windowsize; +; rfb = lr2addr; +; } +; +; lr0 = jmpbuf->lr0; +; if (rfb < lr1) +; raise V_FILL; +; return value; +; } +; + .global _longjmp +_longjmp: + load 0, 0, tav, lr2 ; copy in gr1 + add v1, lr2, 4 ; v1 points to msp + ; make sure we return a non-zero value + cpeq v0, lr3, 0 + srl v0, v0, 31 + or v0, lr3, v0 + + add gr1, tav, 0 ; now update gr1 + add tav, tav, 8 ; calculate lr2addr + load 0, 0, msp, v1 ; update msp from jmpbuf + cpleu v3, tav, rfb ; if (lr2addr > rfb) + jmpt v3, $1 ; { + add v1, v1, 4 ; v1 points to lr0 + add v2, v1, 4 ; v2 points to lr1 + load 0, 0, lr1, v2 ; lr1 = value from jmpbuf + sub v3, rfb, rab ; + sub rab, tav, v3 ; rab = lr2addr - windowsize + add rfb, tav, 0 ; rfb = lr2addr +$1: ; } + load 0, 0, lr0, v1 + jmpi lr0 + asgeu V_FILL, rfb, lr1 ; may fill from rfb to lr1 +; +;================================================================== sigcode +; About to deliver a signal to a user mode signal handler. +; msp+(15*4) = signal_number +; msp+(14*4) = gr1 +; msp+(13*4) = rab +; msp+(12*4) = PC0 +; msp+(11*4) = PC1 +; msp+(10*4) = PC2 +; msp+( 9*4) = CHA +; msp+( 8*4) = CHD +; msp+( 7*4) = CHC +; msp+( 6*4) = ALU +; msp+( 5*4) = OPS +; msp+( 4*4) = gr121 +; msp+( 3*4) = gr99 +; msp+( 2*4) = gr98 +; msp+( 1*4) = gr97 +; msp = gr96 +; The state of all the registers (except for msp, chc and rab) +; is the same as when the process was interrupted. +; +; We must make the stack and window consistent before calling the handler +; The orignal rab value is on the stack. The interrupt handler placed +; rfb-Windowsize in rab. This is required to support nested interrupts. +; +; Note that the window becomes incosistent only during certain +; critical sections in spill, fill, longjmp and sigcode. +; rfb - rab > windowsize => we are in spill +; rfb - rab < windowsize => we are in fill +; gr1 + 8 > rfb => we are in long-longjmp case +; In case of spill, fill and lonjmp; rab is modified first, +; so if we are in one of these critical sections, +; we set rab to rfb - WINDOWSIZE. +; + .equ SIGCTX_SIZE, (16)*4 + .equ SIGCTX_SIGNUMB, (15)*4 + .equ SIGCTX_GR1_OFFSET, (14)*4 + .equ SIGCTX_RAB_OFFSET, (13)*4 + .equ SIGCTX_PC0_OFFSET, (12)*4 + .equ SIGCTX_PC1_OFFSET, (11)*4 + .equ SIGCTX_PC2_OFFSET, (10)*4 + .equ SIGCTX_CHC_OFFSET, (7)*4 + .equ SIGCTX_OPS_OFFSET, (5)*4 + .equ SIGCTX_TAV_OFFSET, (4)*4 + .global sigcode +sigcode: +; -------------------------------------------------------- R-Stack fixup + const v0, WindowSize ; get register cache size + consth v0, WindowSize + load 0, 0, v0, v0 + add v2, msp, SIGCTX_RAB_OFFSET + load 0, 0, v2, v2 ; get interrupted rab value + sub v1, rfb, v2 ; determine if rfb-rab <= WINDOW_SIZE + cpgeu v1, v1, v0 ; + jmpt v1, nfill ; jmp if spill or 'normal' interrupt + add v1, gr1, 8 + cpgt v1, v1, rfb ; interrupted longjmp can look like fill + jmpf v1, nfill ; test for long-longjmp interruption + nop ; jmp if gr1+8 <= rfb +; Fixup signal stack to re-start interrupted fill +; backup pc1 -- this is needed for the partial fill case. +; Clear chc so an interrupted load/store does not restart. +; Reset rab to a window distance below rfb, rab shall be +; decremented again on re-starting the interrupted fill. +; The interrupt handler set rab=rfb-WindowSize. +; + add v0, msp, SIGCTX_RAB_OFFSET + store 0, 0, rab, v0 ; re-store (rfb-WindowSize) for rab + const v2, fill + consth v2, fill + add v0, msp, SIGCTX_PC1_OFFSET + store 0, 0, v2, v0 + sub v2, v2, 4 ; determine pc0 + add v0, msp, SIGCTX_PC0_OFFSET + store 0, 0, v2, v0 + const v2, 0 ; clear chc + add v0, msp, SIGCTX_CHC_OFFSET + store 0, 0, v2, v0 + +nfill: + cpgt v0, gr1, rfb ; if gr1 > rfb then gr1 = rfb + jmpt v0, lower + cplt v0, gr1, rab ; if gr1 < rab then gr1 = rab + jmpt v0, raise + nop +; -------------------------------------------------------- save_regs +sig1: sub msp, msp, (4+2+25)*4 ; reserve space for regs + mfsr gr96, ipc + mfsr gr97, ipa + mfsr gr98, ipb + mfsr gr99, q + mtsrim cr, 4-1 + storem 0, 0, gr96, msp +; "push" registers stack support + add gr96, lr1, 0 + add gr97, rfb, 0 + mtsrim cr, 2-1 + add gr99, msp, 2*4 + storem 0, 0, gr96, gr99 +; "push" remaining global registers + mtsrim cr, 25-1 ; gr100-gr124 + add gr96, msp, (4+2)*4 + storem 0, 0, gr100, gr96 +; +; -------------------------------------------------------- Dummy Call + .equ RALLOC, 4*4 ; make space for function calls + add v0, rfb, 0 ; store original rfb + sub gr1, gr1, RALLOC + asgeu V_SPILL, gr1, rab + add lr1, v0, 0 ; set lr1 = original rfb + add v1, msp, (4+2+25)*4 + SIGCTX_SIGNUMB + load 0, 0, lr2, v1 ; restore signal number + sub v1, lr2, 1 ; get handler index + sll v1, v1, 2 ; point to addresses +; +; -------------------------------------------------------- call C-level +; Handler must not use HIF services other than the _sigret() type. + const v0, SigEntry + consth v0, SigEntry + add v0, v0, v1 + load 0, 0, v0, v0 ; determine if handler registered + cpeq v1, v0, 0 + jmpt v1, NoHandler + nop + calli lr0, v0 ; call C-level signal handler + nop +; +; -------------------------------------------------------- default return +NoHandler: + jmp __sigdfl + nop + +; -------------------------------------------------------- support bits +lower: sll gr1, rfb, 0 + jmp sig1 + nop +raise: sll gr1, rab, 0 + jmp sig1 + nop +/* +; -------------------------------------------------------- repair_regs + mtsrim cr, 4-1 + loadm 0, 0, gr96, msp + mtsr ipc, gr96 + mtsr ipa, gr97 + mtsr ipb, gr98 + mtsr Q, gr99 +; "pop" registers stack support + mtsrim cr, 2-1 + add gr99, msp, 2*4 + loadm 0, 0, gr96, gr99 + add lr1, gr96, 0 + add rfb, gr97, 0 +; "pop" remaining global registers + mtsrim cr, 25-1 ; gr100-gr124 + add gr96, msp, (4+2)*4 + loadm 0, 0, gr100, gr96 + add msp, msp, (4+2+25)*4 ; repair msp to save_regs entry value +; -------------------------------------------------------- end repair +*/ + +; ======================================================== _sigret() + .global __sigret +__sigret: +; repair_regs +; -------------------------------------------------------- repair_regs + mtsrim cr, 4-1 + loadm 0, 0, gr96, msp + mtsr ipc, gr96 + mtsr ipa, gr97 + mtsr ipb, gr98 + mtsr q, gr99 +; "pop" registers stack support + mtsrim cr, 2-1 + add gr99, msp, 2*4 + loadm 0, 0, gr96, gr99 + add lr1, gr96, 0 + add rfb, gr97, 0 +; "pop" remaining global registers + mtsrim cr, 25-1 ; gr100-gr124 + add gr96, msp, (4+2)*4 + loadm 0, 0, gr100, gr96 + add msp, msp, (4+2+25)*4 ; repair msp to save_regs entry value +; -------------------------------------------------------- end repair + const tav, 323 ; HIF _sigret + asneq 69, gr1,gr1 + halt ; commit suicide if returns + +; ======================================================== _sigdfl() + .global __sigdfl +__sigdfl: +; repair_regs +; -------------------------------------------------------- repair_regs + mtsrim cr, 4-1 + loadm 0, 0, gr96, msp + mtsr ipc, gr96 + mtsr ipa, gr97 + mtsr ipb, gr98 + mtsr q, gr99 +; "pop" registers stack support + mtsrim cr, 2-1 + add gr99, msp, 2*4 + loadm 0, 0, gr96, gr99 + add lr1, gr96, 0 + add rfb, gr97, 0 +; "pop" remaining global registers + mtsrim cr, 25-1 ; gr100-gr124 + add gr96, msp, (4+2)*4 + loadm 0, 0, gr100, gr96 + add msp, msp, (4+2+25)*4 ; repair msp to save_regs entry value +; -------------------------------------------------------- end repair + const tav, 322 ; HIF _sigdfl + asneq 69, gr1,gr1 + halt ; commit suicide if returns + +; ======================================================== _sigrep() +__sigrep: + .global __sigrep +; repair_regs +; -------------------------------------------------------- repair_regs + mtsrim cr, 4-1 + loadm 0, 0, gr96, msp + mtsr ipc, gr96 + mtsr ipa, gr97 + mtsr ipb, gr98 + mtsr q, gr99 +; "pop" registers stack support + mtsrim cr, 2-1 + add gr99, msp, 2*4 + loadm 0, 0, gr96, gr99 + add lr1, gr96, 0 + add rfb, gr97, 0 +; "pop" remaining global registers + mtsrim cr, 25-1 ; gr100-gr124 + add gr96, msp, (4+2)*4 + loadm 0, 0, gr100, gr96 + add msp, msp, (4+2+25)*4 ; repair msp to save_regs entry value +; -------------------------------------------------------- end repair + const tav, 324 ; HIF _sigrep + asneq 69, gr1,gr1 + halt ; commit suicide if returns + +; ======================================================== _sigskp() + .global __sigskp +__sigskp: +; repair_regs +; -------------------------------------------------------- repair_regs + mtsrim cr, 4-1 + loadm 0, 0, gr96, msp + mtsr ipc, gr96 + mtsr ipa, gr97 + mtsr ipb, gr98 + mtsr q, gr99 +; "pop" registers stack support + mtsrim cr, 2-1 + add gr99, msp, 2*4 + loadm 0, 0, gr96, gr99 + add lr1, gr96, 0 + add rfb, gr97, 0 +; "pop" remaining global registers + mtsrim cr, 25-1 ; gr100-gr124 + add gr96, msp, (4+2)*4 + loadm 0, 0, gr100, gr96 + add msp, msp, (4+2+25)*4 ; repair msp to save_regs entry value +; -------------------------------------------------------- end repair + const tav, 325 ; HIF _sigskp + asneq 69, gr1,gr1 + halt ; commit suicide if returns + +; ======================================================== _sendsig() +; lr2 = signal number + .global _raise + .global __sendsig +_raise: +__sendsig: + const tav, 326 ; HIF sendsig + asneq 69, gr1,gr1 + jmpi lr0 + nop + +; +; ======================================================== signal() +; lr2 = signal number +; lr3 = handler address + .global _signal +_signal: +; the memory variable WindowSize must be initalised at the +; start when rfb and rab are a window size apart. + const v0, WindowSize ; get register cache size + consth v0, WindowSize + load 0, 0, v1, v0 + cpeq v1, v1, 0 + jmpf v1, WindowSizeOK + sub v1, rfb, rab ; rfb-rab = WINDOW_SIZE + store 0, 0, v1, v0 +WindowSizeOK: + const v1, SigEntry + consth v1, SigEntry + sub v3, lr2, 1 ; get handler index + sll v3, v3, 2 ; pointer to addresses + add v1, v1, v3 + store 0,0, lr3, v1 ; save new handler + + const lr2, sigcode + consth lr2, sigcode + ;Fall through to __signal +; ======================================================== _signal() + .global __signal +__signal: + const tav, 321 ; HIF signal + asneq 69, gr1,gr1 + jmpi lr0 + nop |