Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / arch / metag / tbx / tbipcx.S
1 /*
2  * tbipcx.S
3  *
4  * Copyright (C) 2001, 2002, 2007, 2009, 2012 Imagination Technologies.
5  *
6  * This program is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License version 2 as published by the
8  * Free Software Foundation.
9  *
10  * Asyncronous trigger handling including exceptions
11  */
12
13         .file   "tbipcx.S"
14 #include <asm/metag_regs.h>
15 #include <asm/tbx.h>
16
17 /* BEGIN HACK */
18 /* define these for now while doing inital conversion to GAS 
19    will fix properly later */
20
21 /* Signal identifiers always have the TBID_SIGNAL_BIT set and contain the
22    following related bit-fields */
23 #define TBID_SIGNUM_S       2
24
25 /* END HACK */
26
27 #ifdef METAC_1_0
28 /* Ax.4 is saved in TBICTX */
29 #define A0_4  ,A0.4
30 #else
31 /* Ax.4 is NOT saved in TBICTX */
32 #define A0_4
33 #endif
34
35 /* Size of the TBICTX structure */
36 #define TBICTX_BYTES ((TBICTX_AX_REGS*8)+TBICTX_AX)
37
38 #ifdef METAC_1_1
39 #ifndef BOOTROM
40 #ifndef SPECIAL_BUILD
41 /* Jump straight into the boot ROM version of this code */
42 #define CODE_USES_BOOTROM
43 #endif
44 #endif
45 #endif
46
47 /* Define space needed for CATCH buffer state in traditional units */
48 #define CATCH_ENTRIES      5
49 #define CATCH_ENTRY_BYTES 16
50
51 #ifndef CODE_USES_BOOTROM
52 #define A0GblIStP       A0.15  /* PTBICTX for current thread in PRIV system */
53 #define A1GblIGbP       A1.15  /* Interrupt A1GbP value in PRIV system */
54 #endif
55
56 /*
57  * TBIRES __TBIASyncTrigger( TBIRES State )
58  */
59         .text
60         .balign 4
61         .global ___TBIASyncTrigger
62         .type   ___TBIASyncTrigger,function
63 ___TBIASyncTrigger:
64 #ifdef CODE_USES_BOOTROM
65         MOVT    D0Re0,#HI(LINCORE_BASE)
66         JUMP    D0Re0,#0xA0
67 #else
68         MOV     D0FrT,A0FrP                     /* Boing entry sequence */
69         ADD     A0FrP,A0StP,#0
70         SETL    [A0StP++],D0FrT,D1RtP
71         MOV     D0Re0,PCX                       /* Check for repeat call */
72         MOVT    D0FrT,#HI(___TBIBoingRTI+4)
73         ADD     D0FrT,D0FrT,#LO(___TBIBoingRTI+4)
74         CMP     D0Re0,D0FrT
75         BEQ     ___TBIBoingExit                 /* Already set up - come out */
76         ADD     D1Ar1,D1Ar1,#7                  /* PRIV system stack here */
77         MOV     A0.2,A0StP                      /*  else push context here */
78         MOVS    D0Re0,D0Ar2                     /* Return in user mode? */
79         ANDMB   D1Ar1,D1Ar1,#0xfff8             /*  align priv stack to 64-bit */
80         MOV     D1Re0,D1Ar1                     /*   and set result to arg */
81         MOVMI   A0.2,D1Ar1                      /*  use priv stack if PRIV set                   */
82 /*
83  * Generate an initial TBICTX to return to our own current call context
84  */
85         MOVT    D1Ar5,#HI(___TBIBoingExit)      /* Go here to return */
86         ADD     D1Ar5,D1Ar5,#LO(___TBIBoingExit)
87         ADD     A0.3,A0.2,#TBICTX_DX            /* DX Save area */
88         ANDT    D0Ar2,D0Ar2,#TBICTX_PRIV_BIT    /* Extract PRIV bit */
89         MOVT    D0Ar6,#TBICTX_SOFT_BIT          /* Only soft thread state */
90         ADD     D0Ar6,D0Ar6,D0Ar2               /* Add in PRIV bit if requested */
91         SETL    [A0.2],D0Ar6,D1Ar5              /* Push header fields */
92         ADD     D0FrT,A0.2,#TBICTX_AX           /* Address AX save area */
93         MSETL   [A0.3],D0Re0,D0Ar6,D0Ar4,D0Ar2,D0FrT,D0.5,D0.6,D0.7
94         MOV     D0Ar6,#0
95         MOV     D1Ar5,#0
96         SETL    [A0.3++],D0Ar6,D1Ar5            /* Zero CT register states */
97         SETL    [A0.3++],D0Ar6,D1Ar5
98         MSETL   [D0FrT],A0StP,A0FrP,A0.2,A0.3 A0_4 /* Save AX regs */
99         MOV     A0FrP,A0.2                      /* Restore me! */
100         B       ___TBIResume
101         .size   ___TBIASyncTrigger,.-___TBIASyncTrigger
102
103 /*
104  * Optimised return to handler for META Core
105  */
106 ___TBIBoingRTH:
107         RTH                                     /* Go to background level */
108         MOVT    A0.2,     #HI($Lpcx_target)
109         ADD     A0.2,A0.2,#LO($Lpcx_target)
110         MOV     PCX,A0.2                        /* Setup PCX for interrupts */
111         MOV     PC,D1Re0                        /* Jump to handler */
112 /*
113  * This is where the code below needs to jump to wait for outermost interrupt
114  * event in a non-privilege mode system (single shared interrupt stack).
115  */
116 ___TBIBoingPCX:
117         MGETL   A0StP,A0FrP,A0.2,A0.3 A0_4,[D1Re0] /* Restore AX regs */
118         MOV     TXSTATUS,D0Re0                  /* Restore flags */
119         GETL    D0Re0,D1Re0,[D1Re0+#TBICTX_DX-TBICTX_BYTES]
120 ___TBIBoingRTI:
121         RTI                                     /* Wait for interrupt */
122 $Lpcx_target:
123 /*
124  * Save initial interrupt state on current stack
125  */
126         SETL    [A0StP+#TBICTX_DX],D0Re0,D1Re0  /* Save key registers */
127         ADD     D1Re0,A0StP,#TBICTX_AX          /* Address AX save area */
128         MOV     D0Re0,TXSTATUS                  /* Read TXSTATUS into D0Re0 */
129         MOV     TXSTATUS,#0                     /* Clear TXSTATUS */
130         MSETL   [D1Re0],A0StP,A0FrP,A0.2,A0.3 A0_4 /* Save AX critical regs */
131 /*
132  * Register state at this point is-
133  *
134  *      D0Re0 - Old TXSTATUS with PRIV and CBUF bits set if appropriate
135  *      A0StP - Is call stack frame and base of TBICTX being generated
136  *      A1GbP - Is valid static access link
137  */
138 ___TBIBoing:
139         LOCK0                                   /* Make sure we have no locks! */
140         ADD     A1.2,A0StP,#TBICTX_DX+(8*1)     /* Address DX.1 save area */
141         MOV     A0FrP,A0StP                     /* Setup frame pointer */
142         MSETL   [A1.2],D0Ar6,D0Ar4,D0Ar2,D0FrT,D0.5,D0.6,D0.7
143         MOV     D0Ar4,TXRPT                     /* Save critical CT regs */
144         MOV     D1Ar3,TXBPOBITS
145         MOV     D1Ar1,TXDIVTIME                 /* Calc catch buffer pSrc */
146         MOV     D0Ar2,TXMODE
147         MOV     TXMODE,#0                       /* Clear TXMODE */
148 #ifdef TXDIVTIME_RPDIRTY_BIT
149         TSTT    D1Ar1,#HI(TXDIVTIME_RPDIRTY_BIT)/* NZ = RPDIRTY */
150         MOVT    D0Ar6,#TBICTX_CBRP_BIT
151         ORNZ    D0Re0,D0Re0,D0Ar6               /* Set CBRP if RPDIRTY set */
152 #endif
153         MSETL   [A1.2],D0Ar4,D0Ar2              /* Save CT regs state */
154         MOV     D0Ar2,D0Re0                     /* Copy TXSTATUS */
155         ANDMT   D0Ar2,D0Ar2,#TBICTX_CBUF_BIT+TBICTX_CBRP_BIT
156 #ifdef TBI_1_4
157         MOVT    D1Ar1,#TBICTX_FPAC_BIT          /* Copy FPActive into FPAC */
158         TSTT    D0Re0,#HI(TXSTATUS_FPACTIVE_BIT)
159         ORNZ    D0Ar2,D0Ar2,D1Ar1
160 #endif
161         MOV     D1Ar1,PCX                       /* Read CurrPC */
162         ORT     D0Ar2,D0Ar2,#TBICTX_CRIT_BIT    /* SaveMask + CRIT bit */
163         SETL    [A0FrP+#TBICTX_Flags],D0Ar2,D1Ar1 /* Set pCtx header fields */
164 /*
165  * Completed context save, now we need to make a call to an interrupt handler
166  *
167  *      D0Re0 - holds PRIV, WAIT, CBUF flags, HALT reason if appropriate
168  *      A0FrP - interrupt stack frame and base of TBICTX being generated
169  *      A0StP - same as A0FrP
170  */
171 ___TBIBoingWait:
172                                 /* Reserve space for TBICTX and CBUF */
173         ADD     A0StP,A0StP,#TBICTX_BYTES+(CATCH_ENTRY_BYTES*CATCH_ENTRIES)
174         MOV     D0Ar4,TXSTATI                   /* Read the Triggers data */
175         MOV     D1Ar3,TXDIVTIME                 /* Read IRQEnc bits */
176         MOV     D0Ar2,D0Re0                     /* Copy PRIV and WAIT flags */
177         ANDT    D0Ar2,D0Ar2,#TBICTX_PRIV_BIT+TBICTX_WAIT_BIT+TBICTX_CBUF_BIT
178 #ifdef TBI_1_4
179         MOVT    D1Ar5,#TBICTX_FPAC_BIT          /* Copy FPActive into FPAC */
180         TSTT    D0Re0,#HI(TXSTATUS_FPACTIVE_BIT)
181         ORNZ    D0Ar2,D0Ar2,D1Ar5
182 #endif
183         ANDT    D1Ar3,D1Ar3,#HI(TXDIVTIME_IRQENC_BITS)
184         LSR     D1Ar3,D1Ar3,#TXDIVTIME_IRQENC_S
185         AND     TXSTATI,D0Ar4,#TXSTATI_BGNDHALT_BIT/* Ack any HALT seen */
186         ANDS    D0Ar4,D0Ar4,#0xFFFF-TXSTATI_BGNDHALT_BIT /* Only seen HALT? */
187         ORT     D0Ar2,D0Ar2,#TBICTX_CRIT_BIT    /* Set CRIT */
188 #ifndef BOOTROM
189         MOVT    A1LbP,#HI(___pTBIs)
190         ADD     A1LbP,A1LbP,#LO(___pTBIs)
191         GETL    D1Ar5,D0Ar6,[A1LbP]             /* D0Ar6 = ___pTBIs[1] */
192 #else
193 /*
194  * For BOOTROM support ___pTBIs must be allocated at offset 0 vs A1GbP
195  */
196         GETL    D1Ar5,D0Ar6,[A1GbP]                     /* D0Ar6 = ___pTBIs[1] */
197 #endif
198         BZ      ___TBIBoingHalt                 /* Yes: Service HALT */
199 /*
200  * Encode interrupt as signal vector, strip away same/lower TXMASKI bits
201  */
202         MOV     D1Ar1,#1                        /* Generate mask for this bit */
203         MOV     D0Re0,TXMASKI                   /* Get interrupt mask */
204         LSL     TXSTATI,D1Ar1,D1Ar3             /* Acknowledge trigger */
205         AND     TXMASKI,D0Re0,#TXSTATI_BGNDHALT_BIT     /* Only allow HALTs */
206         OR      D0Ar2,D0Ar2,D0Re0               /* Set TBIRES.Sig.TrigMask */
207         ADD     D1Ar3,D1Ar3,#TBID_SIGNUM_TRT    /* Offset into interrupt sigs */
208         LSL     D0Re0,D1Ar3,#TBID_SIGNUM_S      /* Generate offset from SigNum */
209 /*
210  * This is a key moment we are about to call the handler, register state is
211  * as follows-
212  *
213  *      D0Re0 - Handler vector (SigNum<<TBID_SIGNUM_S)
214  *      D0Ar2 - TXMASKI:TBICTX_CRIT_BIT with optional CBUF and PRIV bits
215  *      D1Ar3 - SigNum
216  *      D0Ar4 - State read from TXSTATI
217  *      D1Ar5 - Inst for SWITCH trigger case only, otherwise undefined
218  *      D0Ar6 - pTBI
219  */
220 ___TBIBoingVec:
221         ADD     D0Re0,D0Re0,#TBI_fnSigs         /* Offset into signal table */
222         GETD    D1Re0,[D0Ar6+D0Re0]             /* Get address for Handler */
223 /*
224  * Call handler at interrupt level, when it returns simply resume execution
225  * of state indicated by D1Re0.
226  */
227         MOV     D1Ar1,A0FrP                     /* Pass in pCtx */
228         CALLR   D1RtP,___TBIBoingRTH            /* Use RTH to invoke handler */
229         
230 /*
231  * Perform critical state restore and execute background thread.
232  *
233  *      A0FrP - is pointer to TBICTX structure to resume
234  *      D0Re0 - contains additional TXMASKI triggers
235  */
236         .text
237         .balign 4
238 #ifdef BOOTROM
239         .global ___TBIResume
240 #endif
241 ___TBIResume:
242 /*
243  * New META IP method
244  */
245         RTH                                     /* Go to interrupt level */
246         MOV     D0Ar4,TXMASKI                   /* Read TXMASKI */
247         OR      TXMASKI,D0Ar4,D0Re0             /* -Write-Modify TXMASKI */
248         GETL    D0Re0,D1Re0,[A0FrP+#TBICTX_Flags]/* Get Flags:SaveMask, CurrPC */
249         MOV     A0StP,A0FrP                     /* Position stack pointer */
250         MOV     D0Ar2,TXPOLLI                   /* Read pending triggers */
251         MOV     PCX,D1Re0                       /* Set resumption PC */
252         TST     D0Ar2,#0xFFFF                   /* Any pending triggers? */
253         BNZ     ___TBIBoingWait                 /* Yes: Go for triggers */
254         TSTT    D0Re0,#TBICTX_WAIT_BIT          /* Do we WAIT anyway? */
255         BNZ     ___TBIBoingWait                 /* Yes: Go for triggers */
256         LSLS    D1Ar5,D0Re0,#1                  /* Test XCBF (MI) & PRIV (CS)? */
257         ADD     D1Re0,A0FrP,#TBICTX_CurrRPT     /* Address CT save area */
258         ADD     A0StP,A0FrP,#TBICTX_DX+(8*1)    /* Address DX.1 save area */
259         MGETL   A0.2,A0.3,[D1Re0]               /* Get CT reg states */
260         MOV     D1Ar3,A1.3                      /* Copy old TXDIVTIME */
261         BPL     ___TBIResCrit                   /* No: Skip logic */
262         ADD     D0Ar4,A0FrP,#TBICTX_BYTES       /* Source is after TBICTX */
263         ANDST   D1Ar3,D1Ar3,#HI(TXDIVTIME_RPMASK_BITS)/* !Z if RPDIRTY */
264         MGETL   D0.5,D0.6,[D0Ar4]               /* Read Catch state */
265         MOV     TXCATCH0,D0.5                   /* Restore TXCATCHn */
266         MOV     TXCATCH1,D1.5
267         MOV     TXCATCH2,D0.6
268         MOV     TXCATCH3,D1.6
269         BZ      ___TBIResCrit
270         MOV     D0Ar2,#(1*8)
271         LSRS    D1Ar3,D1Ar3,#TXDIVTIME_RPMASK_S+1 /* 2nd RPMASK bit -> bit 0 */
272         ADD     RA,D0Ar4,#(0*8)                 /* Re-read read pipeline */
273         ADDNZ   RA,D0Ar4,D0Ar2                  /* If Bit 0 set issue RA */
274         LSRS    D1Ar3,D1Ar3,#2                  /* Bit 1 -> C, Bit 2 -> Bit 0 */
275         ADD     D0Ar2,D0Ar2,#8
276         ADDCS   RA,D0Ar4,D0Ar2                  /* If C issue RA */
277         ADD     D0Ar2,D0Ar2,#8
278         ADDNZ   RA,D0Ar4,D0Ar2                  /* If Bit 0 set issue RA */
279         LSRS    D1Ar3,D1Ar3,#2                  /* Bit 1 -> C, Bit 2 -> Bit 0 */
280         ADD     D0Ar2,D0Ar2,#8
281         ADDCS   RA,D0Ar4,D0Ar2                  /* If C issue RA */
282         ADD     D0Ar2,D0Ar2,#8
283         ADDNZ   RA,D0Ar4,D0Ar2                  /* If Bit 0 set issue RA */
284         MOV     TXDIVTIME,A1.3                  /* Set RPDIRTY again */
285 ___TBIResCrit:
286         LSLS    D1Ar5,D0Re0,#1                  /* Test XCBF (MI) & PRIV (CS)? */
287 #ifdef TBI_1_4
288         ANDT    D1Ar5,D1Ar5,#(TBICTX_FPAC_BIT*2)
289         LSL     D0Ar6,D1Ar5,#3                  /* Convert FPAC into FPACTIVE */
290 #endif
291         ANDMT   D0Re0,D0Re0,#TBICTX_CBUF_BIT    /* Keep CBUF bit from SaveMask */
292 #ifdef TBI_1_4
293         OR      D0Re0,D0Re0,D0Ar6               /* Combine FPACTIVE with others */
294 #endif
295         MGETL   D0Ar6,D0Ar4,D0Ar2,D0FrT,D0.5,D0.6,D0.7,[A0StP] /* Restore DX */
296         MOV     TXRPT,A0.2                      /* Restore CT regs */
297         MOV     TXBPOBITS,A1.2
298         MOV     TXMODE,A0.3
299         BCC     ___TBIBoingPCX                  /* Do non-PRIV wait! */
300         MOV     A1GblIGbP,A1GbP                 /* Save A1GbP too */
301         MGETL   A0StP,A0FrP,A0.2,A0.3 A0_4,[D1Re0] /* Restore AX regs */
302 /*
303  * Wait for the first interrupt/exception trigger in a privilege mode system
304  * (interrupt stack area for current TASK to be pointed to by A0GblIStP
305  * or per_cpu__stack_save[hwthread_id]).
306  */
307         MOV     TXSTATUS,D0Re0                  /* Restore flags */
308         MOV     D0Re0,TXPRIVEXT                 /* Set TXPRIVEXT_TXTOGGLEI_BIT */
309         SUB     D1Re0,D1Re0,#TBICTX_BYTES       /* TBICTX is top of int stack */
310 #ifdef TBX_PERCPU_SP_SAVE
311         SWAP    D1Ar3,A1GbP
312         MOV     D1Ar3,TXENABLE                  /* Which thread are we? */
313         AND     D1Ar3,D1Ar3,#TXENABLE_THREAD_BITS
314         LSR     D1Ar3,D1Ar3,#TXENABLE_THREAD_S-2
315         ADDT    D1Ar3,D1Ar3,#HI(_per_cpu__stack_save)
316         ADD     D1Ar3,D1Ar3,#LO(_per_cpu__stack_save)
317         SETD    [D1Ar3],D1Re0
318         SWAP    D1Ar3,A1GbP
319 #else
320         MOV     A0GblIStP, D1Re0
321 #endif
322         OR      D0Re0,D0Re0,#TXPRIVEXT_TXTOGGLEI_BIT
323         MOV     TXPRIVEXT,D0Re0                 /* Cannot set TXPRIVEXT if !priv */
324         GETL    D0Re0,D1Re0,[D1Re0+#TBICTX_DX]
325         RTI                                     /* Wait for interrupt */
326 /*
327  * Save initial interrupt state on A0GblIStP, switch to A0GblIStP if
328  * BOOTROM code, save and switch to [A1GbP] otherwise.
329  */
330 ___TBIBoingPCXP:
331 #ifdef TBX_PERCPU_SP_SAVE
332         SWAP    D1Ar3,A1GbP                     /* Get PRIV stack base */
333         MOV     D1Ar3,TXENABLE                  /* Which thread are we? */
334         AND     D1Ar3,D1Ar3,#TXENABLE_THREAD_BITS
335         LSR     D1Ar3,D1Ar3,#TXENABLE_THREAD_S-2
336         ADDT    D1Ar3,D1Ar3,#HI(_per_cpu__stack_save)
337         ADD     D1Ar3,D1Ar3,#LO(_per_cpu__stack_save)
338         GETD    D1Ar3,[D1Ar3]
339 #else
340         SWAP    D1Ar3,A0GblIStP                 /* Get PRIV stack base */
341 #endif
342         SETL    [D1Ar3+#TBICTX_DX],D0Re0,D1Re0 /* Save key registers */
343         MOV     D0Re0,TXPRIVEXT                 /* Clear TXPRIVEXT_TXTOGGLEI_BIT */
344         ADD     D1Re0,D1Ar3,#TBICTX_AX  /* Address AX save area */
345         ANDMB   D0Re0,D0Re0,#0xFFFF-TXPRIVEXT_TXTOGGLEI_BIT
346         MOV     TXPRIVEXT,D0Re0                 /* Cannot set TXPRIVEXT if !priv */
347         MOV     D0Re0,TXSTATUS                  /* Read TXSTATUS into D0Re0 */
348         MOV     TXSTATUS,#0                     /* Clear TXSTATUS */
349         MSETL   [D1Re0],A0StP,A0FrP,A0.2,A0.3 A0_4 /* Save AX critical regs */
350         MOV     A0StP,D1Ar3                     /* Switch stacks */
351 #ifdef TBX_PERCPU_SP_SAVE
352         MOV     D1Ar3,A1GbP                     /* Get D1Ar2 back */
353 #else
354         MOV     D1Ar3,A0GblIStP                 /* Get D1Ar2 back */
355 #endif
356         ORT     D0Re0,D0Re0,#TBICTX_PRIV_BIT    /* Add PRIV to TXSTATUS */
357         MOV     A1GbP,A1GblIGbP                 /* Restore A1GbP */
358         B       ___TBIBoing                     /* Enter common handler code */
359 /*
360  * At this point we know it's a background HALT case we are handling.
361  * The restored TXSTATUS always needs to have zero in the reason bits.
362  */
363 ___TBIBoingHalt:
364         MOV     D0Ar4,TXMASKI                   /* Get interrupt mask */
365         ANDST   D0Re0,D0Re0,#HI(TXSTATUS_MAJOR_HALT_BITS+TXSTATUS_MEM_FAULT_BITS)
366         AND     TXMASKI,D0Ar4,#TXSTATI_BGNDHALT_BIT /* Only allow HALTs */
367         AND     D0Ar4,D0Ar4,#0xFFFF-TXSTATI_BGNDHALT_BIT /* What ints are off? */
368         OR      D0Ar2,D0Ar2,D0Ar4               /* Set TBIRES.Sig.TrigMask */
369         MOV     D0Ar4,#TXSTATI_BGNDHALT_BIT     /* This was the trigger state */
370         LSR     D1Ar3,D0Re0,#TXSTATUS_MAJOR_HALT_S
371         MOV     D0Re0,#TBID_SIGNUM_XXF<<TBID_SIGNUM_S
372         BNZ     ___TBIBoingVec                  /* Jump to XXF exception handler */
373 /*
374  * Only the SWITCH cases are left, PCX must be valid
375  */
376 #ifdef TBI_1_4
377         MOV     D1Ar5,TXPRIVEXT
378         TST     D1Ar5,#TXPRIVEXT_MINIMON_BIT
379         LSR     D1Ar3,D1Ar1,#1                  /* Shift needed for MINIM paths (fill stall) */
380         BZ      $Lmeta                          /* If META only, skip */
381         TSTT    D1Ar1,#HI(0x00800000)
382         ANDMT   D1Ar3,D1Ar3,#HI(0x007FFFFF >> 1)/* Shifted mask for large MINIM */
383         ANDT    D1Ar1,D1Ar1,#HI(0xFFE00000)     /* Static mask for small MINIM */
384         BZ      $Llarge_minim                   /* If large MINIM */
385 $Lsmall_minim:
386         TSTT    D1Ar3,#HI(0x00100000 >> 1)
387         ANDMT   D1Ar3,D1Ar3,#HI(0x001FFFFF >> 1)/* Correct shifted mask for large MINIM */
388         ADDZ    D1Ar1,D1Ar1,D1Ar3               /* If META rgn, add twice to undo LSR #1 */
389         B       $Lrecombine
390 $Llarge_minim:
391         ANDST   D1Ar1,D1Ar1,#HI(0xFF800000)     /* Correct static mask for small MINIM */
392                                                 /* Z=0 (Cannot place code at NULL) */
393 $Lrecombine:
394         ADD     D1Ar1,D1Ar1,D1Ar3               /* Combine static and shifted parts */
395 $Lmeta:
396         GETW    D1Ar5,[D1Ar1++]                 /* META: lo-16, MINIM: lo-16 (all-16 if short) */
397         GETW    D1Ar3,[D1Ar1]                   /* META: hi-16, MINIM: hi-16 (only if long) */
398         MOV     D1Re0,D1Ar5
399         XOR     D1Re0,D1Re0,#0x4000
400         LSLSNZ  D1Re0,D1Re0,#(32-14)            /* MINIM: If long C=0, if short C=1 */
401         LSLCC   D1Ar3,D1Ar3,#16                 /* META/MINIM long: Move hi-16 up */
402         LSLCS   D1Ar3,D1Ar5,#16                 /* MINIM short: Dup all-16 */
403         ADD     D1Ar5,D1Ar5,D1Ar3               /* ALL: Combine both 16-bit parts */
404 #else
405         GETD    D1Ar5,[D1Ar1]                   /* Read instruction for switch */
406 #endif
407         LSR     D1Ar3,D1Ar5,#22                 /* Convert into signal number */
408         AND     D1Ar3,D1Ar3,#TBID_SIGNUM_SW3-TBID_SIGNUM_SW0
409         LSL     D0Re0,D1Ar3,#TBID_SIGNUM_S      /* Generate offset from SigNum */
410         B       ___TBIBoingVec                  /* Jump to switch handler */
411 /*
412  * Exit from TBIASyncTrigger call
413  */
414 ___TBIBoingExit:
415         GETL    D0FrT,D1RtP,[A0FrP++]           /* Restore state from frame */
416         SUB     A0StP,A0FrP,#8                  /* Unwind stack */
417         MOV     A0FrP,D0FrT                     /* Last memory read completes */
418         MOV     PC,D1RtP                        /* Return to caller */
419 #endif /* ifdef CODE_USES_BOOTROM */
420         .size   ___TBIResume,.-___TBIResume
421
422 #ifndef BOOTROM
423 /*
424  * void __TBIASyncResume( TBIRES State )
425  */
426         .text
427         .balign 4
428         .global ___TBIASyncResume
429         .type   ___TBIASyncResume,function
430 ___TBIASyncResume:
431 /*
432  * Perform CRIT|SOFT state restore and execute background thread.
433  */
434         MOV     D1Ar3,D1Ar1                     /* Restore this context */
435         MOV     D0Re0,D0Ar2                     /* Carry in additional triggers */
436                                                 /* Reserve space for TBICTX */
437         ADD     D1Ar3,D1Ar3,#TBICTX_BYTES+(CATCH_ENTRY_BYTES*CATCH_ENTRIES)
438         MOV     A0StP,D1Ar3                     /* Enter with protection of */
439         MOV     A0FrP,D1Ar1                     /*   TBICTX on our stack */
440 #ifdef CODE_USES_BOOTROM
441         MOVT    D1Ar1,#HI(LINCORE_BASE)
442         JUMP    D1Ar1,#0xA4
443 #else
444         B       ___TBIResume
445 #endif
446         .size   ___TBIASyncResume,.-___TBIASyncResume
447 #endif /* ifndef BOOTROM */
448
449 /*
450  * End of tbipcx.S
451  */