~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/m68k/ifpsp060/src/isp.S

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /arch/m68k/ifpsp060/src/isp.S (Architecture sparc) and /arch/m68k/ifpsp060/src/isp.S (Architecture m68k)


  1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~      1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2 MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GR      2 MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
  3 M68000 Hi-Performance Microprocessor Division       3 M68000 Hi-Performance Microprocessor Division
  4 M68060 Software Package                             4 M68060 Software Package
  5 Production Release P1.00 -- October 10, 1994        5 Production Release P1.00 -- October 10, 1994
  6                                                     6 
  7 M68060 Software Package Copyright © 1993, 199      7 M68060 Software Package Copyright © 1993, 1994 Motorola Inc.  All rights reserved.
  8                                                     8 
  9 THE SOFTWARE is provided on an "AS IS" basis a      9 THE SOFTWARE is provided on an "AS IS" basis and without warranty.
 10 To the maximum extent permitted by applicable      10 To the maximum extent permitted by applicable law,
 11 MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPR     11 MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
 12 INCLUDING IMPLIED WARRANTIES OF MERCHANTABILIT     12 INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
 13 and any warranty against infringement with reg     13 and any warranty against infringement with regard to the SOFTWARE
 14 (INCLUDING ANY MODIFIED VERSIONS THEREOF) and      14 (INCLUDING ANY MODIFIED VERSIONS THEREOF) and any accompanying written materials.
 15                                                    15 
 16 To the maximum extent permitted by applicable      16 To the maximum extent permitted by applicable law,
 17 IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY D     17 IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
 18 (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOS     18 (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
 19 BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORM     19 BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS)
 20 ARISING OF THE USE OR INABILITY TO USE THE SOF     20 ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE.
 21 Motorola assumes no responsibility for the mai     21 Motorola assumes no responsibility for the maintenance and support of the SOFTWARE.
 22                                                    22 
 23 You are hereby granted a copyright license to      23 You are hereby granted a copyright license to use, modify, and distribute the SOFTWARE
 24 so long as this entire notice is retained with     24 so long as this entire notice is retained without alteration in any modified and/or
 25 redistributed versions, and that such modified     25 redistributed versions, and that such modified versions are clearly identified as such.
 26 No licenses are granted by implication, estopp     26 No licenses are granted by implication, estoppel or otherwise under any patents
 27 or trademarks of Motorola, Inc.                    27 or trademarks of Motorola, Inc.
 28 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~     28 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 29 # ireal.s:                                         29 # ireal.s:
 30 #       This file is appended to the top of th     30 #       This file is appended to the top of the 060ISP package
 31 # and contains the entry points into the packa     31 # and contains the entry points into the package. The user, in
 32 # effect, branches to one of the branch table      32 # effect, branches to one of the branch table entries located
 33 # after _060ISP_TABLE.                             33 # after _060ISP_TABLE.
 34 #       Also, subroutine stubs exist in this f     34 #       Also, subroutine stubs exist in this file (_isp_done for
 35 # example) that are referenced by the ISP pack     35 # example) that are referenced by the ISP package itself in order
 36 # to call a given routine. The stub routine ac     36 # to call a given routine. The stub routine actually performs the
 37 # callout. The ISP code does a "bsr" to the st     37 # callout. The ISP code does a "bsr" to the stub routine. This
 38 # extra layer of hierarchy adds a slight perfo     38 # extra layer of hierarchy adds a slight performance penalty but
 39 # it makes the ISP code easier to read and mor     39 # it makes the ISP code easier to read and more mainatinable.
 40 #                                                  40 #
 41                                                    41 
 42 set     _off_chk,       0x00                       42 set     _off_chk,       0x00
 43 set     _off_divbyzero, 0x04                       43 set     _off_divbyzero, 0x04
 44 set     _off_trace,     0x08                       44 set     _off_trace,     0x08
 45 set     _off_access,    0x0c                       45 set     _off_access,    0x0c
 46 set     _off_done,      0x10                       46 set     _off_done,      0x10
 47                                                    47 
 48 set     _off_cas,       0x14                       48 set     _off_cas,       0x14
 49 set     _off_cas2,      0x18                       49 set     _off_cas2,      0x18
 50 set     _off_lock,      0x1c                       50 set     _off_lock,      0x1c
 51 set     _off_unlock,    0x20                       51 set     _off_unlock,    0x20
 52                                                    52 
 53 set     _off_imr,       0x40                       53 set     _off_imr,       0x40
 54 set     _off_dmr,       0x44                       54 set     _off_dmr,       0x44
 55 set     _off_dmw,       0x48                       55 set     _off_dmw,       0x48
 56 set     _off_irw,       0x4c                       56 set     _off_irw,       0x4c
 57 set     _off_irl,       0x50                       57 set     _off_irl,       0x50
 58 set     _off_drb,       0x54                       58 set     _off_drb,       0x54
 59 set     _off_drw,       0x58                       59 set     _off_drw,       0x58
 60 set     _off_drl,       0x5c                       60 set     _off_drl,       0x5c
 61 set     _off_dwb,       0x60                       61 set     _off_dwb,       0x60
 62 set     _off_dww,       0x64                       62 set     _off_dww,       0x64
 63 set     _off_dwl,       0x68                       63 set     _off_dwl,       0x68
 64                                                    64 
 65 _060ISP_TABLE:                                     65 _060ISP_TABLE:
 66                                                    66 
 67 # Here's the table of ENTRY POINTS for those l     67 # Here's the table of ENTRY POINTS for those linking the package.
 68         bra.l           _isp_unimp                 68         bra.l           _isp_unimp
 69         short           0x0000                     69         short           0x0000
 70                                                    70 
 71         bra.l           _isp_cas                   71         bra.l           _isp_cas
 72         short           0x0000                     72         short           0x0000
 73                                                    73 
 74         bra.l           _isp_cas2                  74         bra.l           _isp_cas2
 75         short           0x0000                     75         short           0x0000
 76                                                    76 
 77         bra.l           _isp_cas_finish            77         bra.l           _isp_cas_finish
 78         short           0x0000                     78         short           0x0000
 79                                                    79 
 80         bra.l           _isp_cas2_finish           80         bra.l           _isp_cas2_finish
 81         short           0x0000                     81         short           0x0000
 82                                                    82 
 83         bra.l           _isp_cas_inrange           83         bra.l           _isp_cas_inrange
 84         short           0x0000                     84         short           0x0000
 85                                                    85 
 86         bra.l           _isp_cas_terminate         86         bra.l           _isp_cas_terminate
 87         short           0x0000                     87         short           0x0000
 88                                                    88 
 89         bra.l           _isp_cas_restart           89         bra.l           _isp_cas_restart
 90         short           0x0000                     90         short           0x0000
 91                                                    91 
 92         space           64                         92         space           64
 93                                                    93 
 94 ##############################################     94 #############################################################
 95                                                    95 
 96         global          _real_chk                  96         global          _real_chk
 97 _real_chk:                                         97 _real_chk:
 98         mov.l           %d0,-(%sp)                 98         mov.l           %d0,-(%sp)
 99         mov.l           (_060ISP_TABLE-0x80+_o     99         mov.l           (_060ISP_TABLE-0x80+_off_chk,%pc),%d0
100         pea.l           (_060ISP_TABLE-0x80,%p    100         pea.l           (_060ISP_TABLE-0x80,%pc,%d0)
101         mov.l           0x4(%sp),%d0              101         mov.l           0x4(%sp),%d0
102         rtd             &0x4                      102         rtd             &0x4
103                                                   103 
104         global          _real_divbyzero           104         global          _real_divbyzero
105 _real_divbyzero:                                  105 _real_divbyzero:
106         mov.l           %d0,-(%sp)                106         mov.l           %d0,-(%sp)
107         mov.l           (_060ISP_TABLE-0x80+_o    107         mov.l           (_060ISP_TABLE-0x80+_off_divbyzero,%pc),%d0
108         pea.l           (_060ISP_TABLE-0x80,%p    108         pea.l           (_060ISP_TABLE-0x80,%pc,%d0)
109         mov.l           0x4(%sp),%d0              109         mov.l           0x4(%sp),%d0
110         rtd             &0x4                      110         rtd             &0x4
111                                                   111 
112         global          _real_trace               112         global          _real_trace
113 _real_trace:                                      113 _real_trace:
114         mov.l           %d0,-(%sp)                114         mov.l           %d0,-(%sp)
115         mov.l           (_060ISP_TABLE-0x80+_o    115         mov.l           (_060ISP_TABLE-0x80+_off_trace,%pc),%d0
116         pea.l           (_060ISP_TABLE-0x80,%p    116         pea.l           (_060ISP_TABLE-0x80,%pc,%d0)
117         mov.l           0x4(%sp),%d0              117         mov.l           0x4(%sp),%d0
118         rtd             &0x4                      118         rtd             &0x4
119                                                   119 
120         global          _real_access              120         global          _real_access
121 _real_access:                                     121 _real_access:
122         mov.l           %d0,-(%sp)                122         mov.l           %d0,-(%sp)
123         mov.l           (_060ISP_TABLE-0x80+_o    123         mov.l           (_060ISP_TABLE-0x80+_off_access,%pc),%d0
124         pea.l           (_060ISP_TABLE-0x80,%p    124         pea.l           (_060ISP_TABLE-0x80,%pc,%d0)
125         mov.l           0x4(%sp),%d0              125         mov.l           0x4(%sp),%d0
126         rtd             &0x4                      126         rtd             &0x4
127                                                   127 
128         global          _isp_done                 128         global          _isp_done
129 _isp_done:                                        129 _isp_done:
130         mov.l           %d0,-(%sp)                130         mov.l           %d0,-(%sp)
131         mov.l           (_060ISP_TABLE-0x80+_o    131         mov.l           (_060ISP_TABLE-0x80+_off_done,%pc),%d0
132         pea.l           (_060ISP_TABLE-0x80,%p    132         pea.l           (_060ISP_TABLE-0x80,%pc,%d0)
133         mov.l           0x4(%sp),%d0              133         mov.l           0x4(%sp),%d0
134         rtd             &0x4                      134         rtd             &0x4
135                                                   135 
136 #######################################           136 #######################################
137                                                   137 
138         global          _real_cas                 138         global          _real_cas
139 _real_cas:                                        139 _real_cas:
140         mov.l           %d0,-(%sp)                140         mov.l           %d0,-(%sp)
141         mov.l           (_060ISP_TABLE-0x80+_o    141         mov.l           (_060ISP_TABLE-0x80+_off_cas,%pc),%d0
142         pea.l           (_060ISP_TABLE-0x80,%p    142         pea.l           (_060ISP_TABLE-0x80,%pc,%d0)
143         mov.l           0x4(%sp),%d0              143         mov.l           0x4(%sp),%d0
144         rtd             &0x4                      144         rtd             &0x4
145                                                   145 
146         global          _real_cas2                146         global          _real_cas2
147 _real_cas2:                                       147 _real_cas2:
148         mov.l           %d0,-(%sp)                148         mov.l           %d0,-(%sp)
149         mov.l           (_060ISP_TABLE-0x80+_o    149         mov.l           (_060ISP_TABLE-0x80+_off_cas2,%pc),%d0
150         pea.l           (_060ISP_TABLE-0x80,%p    150         pea.l           (_060ISP_TABLE-0x80,%pc,%d0)
151         mov.l           0x4(%sp),%d0              151         mov.l           0x4(%sp),%d0
152         rtd             &0x4                      152         rtd             &0x4
153                                                   153 
154         global          _real_lock_page           154         global          _real_lock_page
155 _real_lock_page:                                  155 _real_lock_page:
156         mov.l           %d0,-(%sp)                156         mov.l           %d0,-(%sp)
157         mov.l           (_060ISP_TABLE-0x80+_o    157         mov.l           (_060ISP_TABLE-0x80+_off_lock,%pc),%d0
158         pea.l           (_060ISP_TABLE-0x80,%p    158         pea.l           (_060ISP_TABLE-0x80,%pc,%d0)
159         mov.l           0x4(%sp),%d0              159         mov.l           0x4(%sp),%d0
160         rtd             &0x4                      160         rtd             &0x4
161                                                   161 
162         global          _real_unlock_page         162         global          _real_unlock_page
163 _real_unlock_page:                                163 _real_unlock_page:
164         mov.l           %d0,-(%sp)                164         mov.l           %d0,-(%sp)
165         mov.l           (_060ISP_TABLE-0x80+_o    165         mov.l           (_060ISP_TABLE-0x80+_off_unlock,%pc),%d0
166         pea.l           (_060ISP_TABLE-0x80,%p    166         pea.l           (_060ISP_TABLE-0x80,%pc,%d0)
167         mov.l           0x4(%sp),%d0              167         mov.l           0x4(%sp),%d0
168         rtd             &0x4                      168         rtd             &0x4
169                                                   169 
170 #######################################           170 #######################################
171                                                   171 
172         global          _imem_read                172         global          _imem_read
173 _imem_read:                                       173 _imem_read:
174         mov.l           %d0,-(%sp)                174         mov.l           %d0,-(%sp)
175         mov.l           (_060ISP_TABLE-0x80+_o    175         mov.l           (_060ISP_TABLE-0x80+_off_imr,%pc),%d0
176         pea.l           (_060ISP_TABLE-0x80,%p    176         pea.l           (_060ISP_TABLE-0x80,%pc,%d0)
177         mov.l           0x4(%sp),%d0              177         mov.l           0x4(%sp),%d0
178         rtd             &0x4                      178         rtd             &0x4
179                                                   179 
180         global          _dmem_read                180         global          _dmem_read
181 _dmem_read:                                       181 _dmem_read:
182         mov.l           %d0,-(%sp)                182         mov.l           %d0,-(%sp)
183         mov.l           (_060ISP_TABLE-0x80+_o    183         mov.l           (_060ISP_TABLE-0x80+_off_dmr,%pc),%d0
184         pea.l           (_060ISP_TABLE-0x80,%p    184         pea.l           (_060ISP_TABLE-0x80,%pc,%d0)
185         mov.l           0x4(%sp),%d0              185         mov.l           0x4(%sp),%d0
186         rtd             &0x4                      186         rtd             &0x4
187                                                   187 
188         global          _dmem_write               188         global          _dmem_write
189 _dmem_write:                                      189 _dmem_write:
190         mov.l           %d0,-(%sp)                190         mov.l           %d0,-(%sp)
191         mov.l           (_060ISP_TABLE-0x80+_o    191         mov.l           (_060ISP_TABLE-0x80+_off_dmw,%pc),%d0
192         pea.l           (_060ISP_TABLE-0x80,%p    192         pea.l           (_060ISP_TABLE-0x80,%pc,%d0)
193         mov.l           0x4(%sp),%d0              193         mov.l           0x4(%sp),%d0
194         rtd             &0x4                      194         rtd             &0x4
195                                                   195 
196         global          _imem_read_word           196         global          _imem_read_word
197 _imem_read_word:                                  197 _imem_read_word:
198         mov.l           %d0,-(%sp)                198         mov.l           %d0,-(%sp)
199         mov.l           (_060ISP_TABLE-0x80+_o    199         mov.l           (_060ISP_TABLE-0x80+_off_irw,%pc),%d0
200         pea.l           (_060ISP_TABLE-0x80,%p    200         pea.l           (_060ISP_TABLE-0x80,%pc,%d0)
201         mov.l           0x4(%sp),%d0              201         mov.l           0x4(%sp),%d0
202         rtd             &0x4                      202         rtd             &0x4
203                                                   203 
204         global          _imem_read_long           204         global          _imem_read_long
205 _imem_read_long:                                  205 _imem_read_long:
206         mov.l           %d0,-(%sp)                206         mov.l           %d0,-(%sp)
207         mov.l           (_060ISP_TABLE-0x80+_o    207         mov.l           (_060ISP_TABLE-0x80+_off_irl,%pc),%d0
208         pea.l           (_060ISP_TABLE-0x80,%p    208         pea.l           (_060ISP_TABLE-0x80,%pc,%d0)
209         mov.l           0x4(%sp),%d0              209         mov.l           0x4(%sp),%d0
210         rtd             &0x4                      210         rtd             &0x4
211                                                   211 
212         global          _dmem_read_byte           212         global          _dmem_read_byte
213 _dmem_read_byte:                                  213 _dmem_read_byte:
214         mov.l           %d0,-(%sp)                214         mov.l           %d0,-(%sp)
215         mov.l           (_060ISP_TABLE-0x80+_o    215         mov.l           (_060ISP_TABLE-0x80+_off_drb,%pc),%d0
216         pea.l           (_060ISP_TABLE-0x80,%p    216         pea.l           (_060ISP_TABLE-0x80,%pc,%d0)
217         mov.l           0x4(%sp),%d0              217         mov.l           0x4(%sp),%d0
218         rtd             &0x4                      218         rtd             &0x4
219                                                   219 
220         global          _dmem_read_word           220         global          _dmem_read_word
221 _dmem_read_word:                                  221 _dmem_read_word:
222         mov.l           %d0,-(%sp)                222         mov.l           %d0,-(%sp)
223         mov.l           (_060ISP_TABLE-0x80+_o    223         mov.l           (_060ISP_TABLE-0x80+_off_drw,%pc),%d0
224         pea.l           (_060ISP_TABLE-0x80,%p    224         pea.l           (_060ISP_TABLE-0x80,%pc,%d0)
225         mov.l           0x4(%sp),%d0              225         mov.l           0x4(%sp),%d0
226         rtd             &0x4                      226         rtd             &0x4
227                                                   227 
228         global          _dmem_read_long           228         global          _dmem_read_long
229 _dmem_read_long:                                  229 _dmem_read_long:
230         mov.l           %d0,-(%sp)                230         mov.l           %d0,-(%sp)
231         mov.l           (_060ISP_TABLE-0x80+_o    231         mov.l           (_060ISP_TABLE-0x80+_off_drl,%pc),%d0
232         pea.l           (_060ISP_TABLE-0x80,%p    232         pea.l           (_060ISP_TABLE-0x80,%pc,%d0)
233         mov.l           0x4(%sp),%d0              233         mov.l           0x4(%sp),%d0
234         rtd             &0x4                      234         rtd             &0x4
235                                                   235 
236         global          _dmem_write_byte          236         global          _dmem_write_byte
237 _dmem_write_byte:                                 237 _dmem_write_byte:
238         mov.l           %d0,-(%sp)                238         mov.l           %d0,-(%sp)
239         mov.l           (_060ISP_TABLE-0x80+_o    239         mov.l           (_060ISP_TABLE-0x80+_off_dwb,%pc),%d0
240         pea.l           (_060ISP_TABLE-0x80,%p    240         pea.l           (_060ISP_TABLE-0x80,%pc,%d0)
241         mov.l           0x4(%sp),%d0              241         mov.l           0x4(%sp),%d0
242         rtd             &0x4                      242         rtd             &0x4
243                                                   243 
244         global          _dmem_write_word          244         global          _dmem_write_word
245 _dmem_write_word:                                 245 _dmem_write_word:
246         mov.l           %d0,-(%sp)                246         mov.l           %d0,-(%sp)
247         mov.l           (_060ISP_TABLE-0x80+_o    247         mov.l           (_060ISP_TABLE-0x80+_off_dww,%pc),%d0
248         pea.l           (_060ISP_TABLE-0x80,%p    248         pea.l           (_060ISP_TABLE-0x80,%pc,%d0)
249         mov.l           0x4(%sp),%d0              249         mov.l           0x4(%sp),%d0
250         rtd             &0x4                      250         rtd             &0x4
251                                                   251 
252         global          _dmem_write_long          252         global          _dmem_write_long
253 _dmem_write_long:                                 253 _dmem_write_long:
254         mov.l           %d0,-(%sp)                254         mov.l           %d0,-(%sp)
255         mov.l           (_060ISP_TABLE-0x80+_o    255         mov.l           (_060ISP_TABLE-0x80+_off_dwl,%pc),%d0
256         pea.l           (_060ISP_TABLE-0x80,%p    256         pea.l           (_060ISP_TABLE-0x80,%pc,%d0)
257         mov.l           0x4(%sp),%d0              257         mov.l           0x4(%sp),%d0
258         rtd             &0x4                      258         rtd             &0x4
259                                                   259 
260 #                                                 260 #
261 # This file contains a set of define statement    261 # This file contains a set of define statements for constants
262 # in oreder to promote readability within the     262 # in oreder to promote readability within the core code itself.
263 #                                                 263 #
264                                                   264 
265 set LOCAL_SIZE,         96                        265 set LOCAL_SIZE,         96                      # stack frame size(bytes)
266 set LV,                 -LOCAL_SIZE               266 set LV,                 -LOCAL_SIZE             # stack offset
267                                                   267 
268 set EXC_ISR,            0x4                       268 set EXC_ISR,            0x4                     # stack status register
269 set EXC_IPC,            0x6                       269 set EXC_IPC,            0x6                     # stack pc
270 set EXC_IVOFF,          0xa                       270 set EXC_IVOFF,          0xa                     # stacked vector offset
271                                                   271 
272 set EXC_AREGS,          LV+64                     272 set EXC_AREGS,          LV+64                   # offset of all address regs
273 set EXC_DREGS,          LV+32                     273 set EXC_DREGS,          LV+32                   # offset of all data regs
274                                                   274 
275 set EXC_A7,             EXC_AREGS+(7*4)           275 set EXC_A7,             EXC_AREGS+(7*4)         # offset of a7
276 set EXC_A6,             EXC_AREGS+(6*4)           276 set EXC_A6,             EXC_AREGS+(6*4)         # offset of a6
277 set EXC_A5,             EXC_AREGS+(5*4)           277 set EXC_A5,             EXC_AREGS+(5*4)         # offset of a5
278 set EXC_A4,             EXC_AREGS+(4*4)           278 set EXC_A4,             EXC_AREGS+(4*4)         # offset of a4
279 set EXC_A3,             EXC_AREGS+(3*4)           279 set EXC_A3,             EXC_AREGS+(3*4)         # offset of a3
280 set EXC_A2,             EXC_AREGS+(2*4)           280 set EXC_A2,             EXC_AREGS+(2*4)         # offset of a2
281 set EXC_A1,             EXC_AREGS+(1*4)           281 set EXC_A1,             EXC_AREGS+(1*4)         # offset of a1
282 set EXC_A0,             EXC_AREGS+(0*4)           282 set EXC_A0,             EXC_AREGS+(0*4)         # offset of a0
283 set EXC_D7,             EXC_DREGS+(7*4)           283 set EXC_D7,             EXC_DREGS+(7*4)         # offset of d7
284 set EXC_D6,             EXC_DREGS+(6*4)           284 set EXC_D6,             EXC_DREGS+(6*4)         # offset of d6
285 set EXC_D5,             EXC_DREGS+(5*4)           285 set EXC_D5,             EXC_DREGS+(5*4)         # offset of d5
286 set EXC_D4,             EXC_DREGS+(4*4)           286 set EXC_D4,             EXC_DREGS+(4*4)         # offset of d4
287 set EXC_D3,             EXC_DREGS+(3*4)           287 set EXC_D3,             EXC_DREGS+(3*4)         # offset of d3
288 set EXC_D2,             EXC_DREGS+(2*4)           288 set EXC_D2,             EXC_DREGS+(2*4)         # offset of d2
289 set EXC_D1,             EXC_DREGS+(1*4)           289 set EXC_D1,             EXC_DREGS+(1*4)         # offset of d1
290 set EXC_D0,             EXC_DREGS+(0*4)           290 set EXC_D0,             EXC_DREGS+(0*4)         # offset of d0
291                                                   291 
292 set EXC_TEMP,           LV+16                     292 set EXC_TEMP,           LV+16                   # offset of temp stack space
293                                                   293 
294 set EXC_SAVVAL,         LV+12                     294 set EXC_SAVVAL,         LV+12                   # offset of old areg value
295 set EXC_SAVREG,         LV+11                     295 set EXC_SAVREG,         LV+11                   # offset of old areg index
296                                                   296 
297 set SPCOND_FLG,         LV+10                     297 set SPCOND_FLG,         LV+10                   # offset of spc condition flg
298                                                   298 
299 set EXC_CC,             LV+8                      299 set EXC_CC,             LV+8                    # offset of cc register
300 set EXC_EXTWPTR,        LV+4                      300 set EXC_EXTWPTR,        LV+4                    # offset of current PC
301 set EXC_EXTWORD,        LV+2                      301 set EXC_EXTWORD,        LV+2                    # offset of current ext opword
302 set EXC_OPWORD,         LV+0                      302 set EXC_OPWORD,         LV+0                    # offset of current opword
303                                                   303 
304 ###########################                       304 ###########################
305 # SPecial CONDition FLaGs #                       305 # SPecial CONDition FLaGs #
306 ###########################                       306 ###########################
307 set mia7_flg,           0x04                      307 set mia7_flg,           0x04                    # (a7)+ flag
308 set mda7_flg,           0x08                      308 set mda7_flg,           0x08                    # -(a7) flag
309 set ichk_flg,           0x10                      309 set ichk_flg,           0x10                    # chk exception flag
310 set idbyz_flg,          0x20                      310 set idbyz_flg,          0x20                    # divbyzero flag
311 set restore_flg,        0x40                      311 set restore_flg,        0x40                    # restore -(an)+ flag
312 set immed_flg,          0x80                      312 set immed_flg,          0x80                    # immediate data flag
313                                                   313 
314 set mia7_bit,           0x2                       314 set mia7_bit,           0x2                     # (a7)+ bit
315 set mda7_bit,           0x3                       315 set mda7_bit,           0x3                     # -(a7) bit
316 set ichk_bit,           0x4                       316 set ichk_bit,           0x4                     # chk exception bit
317 set idbyz_bit,          0x5                       317 set idbyz_bit,          0x5                     # divbyzero bit
318 set restore_bit,        0x6                       318 set restore_bit,        0x6                     # restore -(a7)+ bit
319 set immed_bit,          0x7                       319 set immed_bit,          0x7                     # immediate data bit
320                                                   320 
321 #########                                         321 #########
322 # Misc. #                                         322 # Misc. #
323 #########                                         323 #########
324 set BYTE,               1                         324 set BYTE,               1                       # len(byte) == 1 byte
325 set WORD,               2                         325 set WORD,               2                       # len(word) == 2 bytes
326 set LONG,               4                         326 set LONG,               4                       # len(longword) == 4 bytes
327                                                   327 
328 ##############################################    328 #########################################################################
329 # XDEF ***************************************    329 # XDEF **************************************************************** #
330 #       _isp_unimp(): 060ISP entry point for U    330 #       _isp_unimp(): 060ISP entry point for Unimplemented Instruction  #
331 #                                                 331 #                                                                       #
332 #       This handler should be the first code     332 #       This handler should be the first code executed upon taking the  #
333 #       "Unimplemented Integer Instruction" ex    333 #       "Unimplemented Integer Instruction" exception in an operating   #
334 #       system.                                   334 #       system.                                                         #
335 #                                                 335 #                                                                       #
336 # XREF ***************************************    336 # XREF **************************************************************** #
337 #       _imem_read_{word,long}() - read instru    337 #       _imem_read_{word,long}() - read instruction word/longword       #
338 #       _mul64() - emulate 64-bit multiply        338 #       _mul64() - emulate 64-bit multiply                              #
339 #       _div64() - emulate 64-bit divide          339 #       _div64() - emulate 64-bit divide                                #
340 #       _moveperipheral() - emulate "movep"       340 #       _moveperipheral() - emulate "movep"                             #
341 #       _compandset() - emulate misaligned "ca    341 #       _compandset() - emulate misaligned "cas"                        #
342 #       _compandset2() - emulate "cas2"           342 #       _compandset2() - emulate "cas2"                                 #
343 #       _chk2_cmp2() - emulate "cmp2" and "chk    343 #       _chk2_cmp2() - emulate "cmp2" and "chk2"                        #
344 #       _isp_done() - "callout" for normal fin    344 #       _isp_done() - "callout" for normal final exit                   #
345 #       _real_trace() - "callout" for Trace ex    345 #       _real_trace() - "callout" for Trace exception                   #
346 #       _real_chk() - "callout" for Chk except    346 #       _real_chk() - "callout" for Chk exception                       #
347 #       _real_divbyzero() - "callout" for DZ e    347 #       _real_divbyzero() - "callout" for DZ exception                  #
348 #       _real_access() - "callout" for access     348 #       _real_access() - "callout" for access error exception           #
349 #                                                 349 #                                                                       #
350 # INPUT **************************************    350 # INPUT *************************************************************** #
351 #       - The system stack contains the Unimp     351 #       - The system stack contains the Unimp Int Instr stack frame     #
352 #                                                 352 #                                                                       #
353 # OUTPUT *************************************    353 # OUTPUT ************************************************************** #
354 #       If Trace exception:                       354 #       If Trace exception:                                             #
355 #       - The system stack changed to contain     355 #       - The system stack changed to contain Trace exc stack frame     #
356 #       If Chk exception:                         356 #       If Chk exception:                                               #
357 #       - The system stack changed to contain     357 #       - The system stack changed to contain Chk exc stack frame       #
358 #       If DZ exception:                          358 #       If DZ exception:                                                #
359 #       - The system stack changed to contain     359 #       - The system stack changed to contain DZ exc stack frame        #
360 #       If access error exception:                360 #       If access error exception:                                      #
361 #       - The system stack changed to contain     361 #       - The system stack changed to contain access err exc stk frame  #
362 #       Else:                                     362 #       Else:                                                           #
363 #       - Results saved as appropriate            363 #       - Results saved as appropriate                                  #
364 #                                                 364 #                                                                       #
365 # ALGORITHM **********************************    365 # ALGORITHM *********************************************************** #
366 #       This handler fetches the first instruc    366 #       This handler fetches the first instruction longword from        #
367 # memory and decodes it to determine which of     367 # memory and decodes it to determine which of the unimplemented         #
368 # integer instructions caused this exception.     368 # integer instructions caused this exception. This handler then calls   #
369 # one of _mul64(), _div64(), _moveperipheral()    369 # one of _mul64(), _div64(), _moveperipheral(), _compandset(),          #
370 # _compandset2(), or _chk2_cmp2() as appropria    370 # _compandset2(), or _chk2_cmp2() as appropriate.                       #
371 #       Some of these instructions, by their n    371 #       Some of these instructions, by their nature, may produce other  #
372 # types of exceptions. "div" can produce a div    372 # types of exceptions. "div" can produce a divide-by-zero exception,    #
373 # and "chk2" can cause a "Chk" exception. In b    373 # and "chk2" can cause a "Chk" exception. In both cases, the current    #
374 # exception stack frame must be converted to a    374 # exception stack frame must be converted to an exception stack frame   #
375 # of the correct exception type and an exit mu    375 # of the correct exception type and an exit must be made through        #
376 # _real_divbyzero() or _real_chk() as appropri    376 # _real_divbyzero() or _real_chk() as appropriate. In addition, all     #
377 # instructions may be executing while Trace is    377 # instructions may be executing while Trace is enabled. If so, then     #
378 # a Trace exception stack frame must be create    378 # a Trace exception stack frame must be created and an exit made        #
379 # through _real_trace().                          379 # through _real_trace().                                                #
380 #       Meanwhile, if any read or write to mem    380 #       Meanwhile, if any read or write to memory using the             #
381 # _mem_{read,write}() "callout"s returns a fai    381 # _mem_{read,write}() "callout"s returns a failing value, then an       #
382 # access error frame must be created and an ex    382 # access error frame must be created and an exit made through           #
383 # _real_access().                                 383 # _real_access().                                                       #
384 #       If none of these occur, then a normal     384 #       If none of these occur, then a normal exit is made through      #
385 # _isp_done().                                    385 # _isp_done().                                                          #
386 #                                                 386 #                                                                       #
387 #       This handler, upon entry, saves almost    387 #       This handler, upon entry, saves almost all user-visible         #
388 # address and data registers to the stack. Alt    388 # address and data registers to the stack. Although this may seem to    #
389 # cause excess memory traffic, it was found th    389 # cause excess memory traffic, it was found that due to having to       #
390 # access these register files for things like     390 # access these register files for things like data retrieval and <ea>   #
391 # calculations, it was more efficient to have     391 # calculations, it was more efficient to have them on the stack where   #
392 # they could be accessed by indexing rather th    392 # they could be accessed by indexing rather than to make subroutine     #
393 # calls to retrieve a register of a particular    393 # calls to retrieve a register of a particular index.                   #
394 #                                                 394 #                                                                       #
395 ##############################################    395 #########################################################################
396                                                   396 
397         global          _isp_unimp                397         global          _isp_unimp
398 _isp_unimp:                                       398 _isp_unimp:
399         link.w          %a6,&-LOCAL_SIZE          399         link.w          %a6,&-LOCAL_SIZE        # create room for stack frame
400                                                   400 
401         movm.l          &0x3fff,EXC_DREGS(%a6)    401         movm.l          &0x3fff,EXC_DREGS(%a6)  # store d0-d7/a0-a5
402         mov.l           (%a6),EXC_A6(%a6)         402         mov.l           (%a6),EXC_A6(%a6)       # store a6
403                                                   403 
404         btst            &0x5,EXC_ISR(%a6)         404         btst            &0x5,EXC_ISR(%a6)       # from s or u mode?
405         bne.b           uieh_s                    405         bne.b           uieh_s                  # supervisor mode
406 uieh_u:                                           406 uieh_u:
407         mov.l           %usp,%a0                  407         mov.l           %usp,%a0                # fetch user stack pointer
408         mov.l           %a0,EXC_A7(%a6)           408         mov.l           %a0,EXC_A7(%a6)         # store a7
409         bra.b           uieh_cont                 409         bra.b           uieh_cont
410 uieh_s:                                           410 uieh_s:
411         lea             0xc(%a6),%a0              411         lea             0xc(%a6),%a0
412         mov.l           %a0,EXC_A7(%a6)           412         mov.l           %a0,EXC_A7(%a6)         # store corrected sp
413                                                   413 
414 ##############################################    414 ###############################################################################
415                                                   415 
416 uieh_cont:                                        416 uieh_cont:
417         clr.b           SPCOND_FLG(%a6)           417         clr.b           SPCOND_FLG(%a6)         # clear "special case" flag
418                                                   418 
419         mov.w           EXC_ISR(%a6),EXC_CC(%a    419         mov.w           EXC_ISR(%a6),EXC_CC(%a6) # store cc copy on stack
420         mov.l           EXC_IPC(%a6),EXC_EXTWP    420         mov.l           EXC_IPC(%a6),EXC_EXTWPTR(%a6) # store extwptr on stack
421                                                   421 
422 #                                                 422 #
423 # fetch the opword and first extension word po    423 # fetch the opword and first extension word pointed to by the stacked pc
424 # and store them to the stack for now             424 # and store them to the stack for now
425 #                                                 425 #
426         mov.l           EXC_EXTWPTR(%a6),%a0      426         mov.l           EXC_EXTWPTR(%a6),%a0    # fetch instruction addr
427         addq.l          &0x4,EXC_EXTWPTR(%a6)     427         addq.l          &0x4,EXC_EXTWPTR(%a6)   # incr instruction ptr
428         bsr.l           _imem_read_long           428         bsr.l           _imem_read_long         # fetch opword & extword
429         mov.l           %d0,EXC_OPWORD(%a6)       429         mov.l           %d0,EXC_OPWORD(%a6)     # store extword on stack
430                                                   430 
431                                                   431 
432 ##############################################    432 #########################################################################
433 # muls.l        0100 1100 00 |<ea>|     0*** 1    433 # muls.l        0100 1100 00 |<ea>|     0*** 1100 0000 0***             #
434 # mulu.l        0100 1100 00 |<ea>|     0*** 0    434 # mulu.l        0100 1100 00 |<ea>|     0*** 0100 0000 0***             #
435 #                                                 435 #                                                                       #
436 # divs.l        0100 1100 01 |<ea>|     0*** 1    436 # divs.l        0100 1100 01 |<ea>|     0*** 1100 0000 0***             #
437 # divu.l        0100 1100 01 |<ea>|     0*** 0    437 # divu.l        0100 1100 01 |<ea>|     0*** 0100 0000 0***             #
438 #                                                 438 #                                                                       #
439 # movep.w m2r   0000 ***1 00 001***     | <dis    439 # movep.w m2r   0000 ***1 00 001***     | <displacement>  |             #
440 # movep.l m2r   0000 ***1 01 001***     | <dis    440 # movep.l m2r   0000 ***1 01 001***     | <displacement>  |             #
441 # movep.w r2m   0000 ***1 10 001***     | <dis    441 # movep.w r2m   0000 ***1 10 001***     | <displacement>  |             #
442 # movep.l r2m   0000 ***1 11 001***     | <dis    442 # movep.l r2m   0000 ***1 11 001***     | <displacement>  |             #
443 #                                                 443 #                                                                       #
444 # cas.w         0000 1100 11 |<ea>|     0000 0    444 # cas.w         0000 1100 11 |<ea>|     0000 000* **00 0***             #
445 # cas.l         0000 1110 11 |<ea>|     0000 0    445 # cas.l         0000 1110 11 |<ea>|     0000 000* **00 0***             #
446 #                                                 446 #                                                                       #
447 # cas2.w        0000 1100 11 111100     **** 0    447 # cas2.w        0000 1100 11 111100     **** 000* **00 0***             #
448 #                                       **** 0    448 #                                       **** 000* **00 0***             #
449 # cas2.l        0000 1110 11 111100     **** 0    449 # cas2.l        0000 1110 11 111100     **** 000* **00 0***             #
450 #                                       **** 0    450 #                                       **** 000* **00 0***             #
451 #                                                 451 #                                                                       #
452 # chk2.b        0000 0000 11 |<ea>|     **** 1    452 # chk2.b        0000 0000 11 |<ea>|     **** 1000 0000 0000             #
453 # chk2.w        0000 0010 11 |<ea>|     **** 1    453 # chk2.w        0000 0010 11 |<ea>|     **** 1000 0000 0000             #
454 # chk2.l        0000 0100 11 |<ea>|     **** 1    454 # chk2.l        0000 0100 11 |<ea>|     **** 1000 0000 0000             #
455 #                                                 455 #                                                                       #
456 # cmp2.b        0000 0000 11 |<ea>|     **** 0    456 # cmp2.b        0000 0000 11 |<ea>|     **** 0000 0000 0000             #
457 # cmp2.w        0000 0010 11 |<ea>|     **** 0    457 # cmp2.w        0000 0010 11 |<ea>|     **** 0000 0000 0000             #
458 # cmp2.l        0000 0100 11 |<ea>|     **** 0    458 # cmp2.l        0000 0100 11 |<ea>|     **** 0000 0000 0000             #
459 ##############################################    459 #########################################################################
460                                                   460 
461 #                                                 461 #
462 # using bit 14 of the operation word, separate    462 # using bit 14 of the operation word, separate into 2 groups:
463 # (group1) mul64, div64                           463 # (group1) mul64, div64
464 # (group2) movep, chk2, cmp2, cas2, cas           464 # (group2) movep, chk2, cmp2, cas2, cas
465 #                                                 465 #
466         btst            &0x1e,%d0                 466         btst            &0x1e,%d0               # group1 or group2
467         beq.b           uieh_group2               467         beq.b           uieh_group2             # go handle group2
468                                                   468 
469 #                                                 469 #
470 # now, w/ group1, make mul64's decode the fast    470 # now, w/ group1, make mul64's decode the fastest since it will
471 # most likely be used the most.                   471 # most likely be used the most.
472 #                                                 472 #
473 uieh_group1:                                      473 uieh_group1:
474         btst            &0x16,%d0                 474         btst            &0x16,%d0               # test for div64
475         bne.b           uieh_div64                475         bne.b           uieh_div64              # go handle div64
476                                                   476 
477 uieh_mul64:                                       477 uieh_mul64:
478 # mul64() may use ()+ addressing and may, ther    478 # mul64() may use ()+ addressing and may, therefore, alter a7
479                                                   479 
480         bsr.l           _mul64                    480         bsr.l           _mul64                  # _mul64()
481                                                   481 
482         btst            &0x5,EXC_ISR(%a6)         482         btst            &0x5,EXC_ISR(%a6)       # supervisor mode?
483         beq.w           uieh_done                 483         beq.w           uieh_done
484         btst            &mia7_bit,SPCOND_FLG(%    484         btst            &mia7_bit,SPCOND_FLG(%a6) # was a7 changed?
485         beq.w           uieh_done                 485         beq.w           uieh_done               # no
486         btst            &0x7,EXC_ISR(%a6)         486         btst            &0x7,EXC_ISR(%a6)       # is trace enabled?
487         bne.w           uieh_trace_a7             487         bne.w           uieh_trace_a7           # yes
488         bra.w           uieh_a7                   488         bra.w           uieh_a7                 # no
489                                                   489 
490 uieh_div64:                                       490 uieh_div64:
491 # div64() may use ()+ addressing and may, ther    491 # div64() may use ()+ addressing and may, therefore, alter a7.
492 # div64() may take a divide by zero exception.    492 # div64() may take a divide by zero exception.
493                                                   493 
494         bsr.l           _div64                    494         bsr.l           _div64                  # _div64()
495                                                   495 
496 # here, we sort out all of the special cases t    496 # here, we sort out all of the special cases that may have happened.
497         btst            &mia7_bit,SPCOND_FLG(%    497         btst            &mia7_bit,SPCOND_FLG(%a6) # was a7 changed?
498         bne.b           uieh_div64_a7             498         bne.b           uieh_div64_a7           # yes
499 uieh_div64_dbyz:                                  499 uieh_div64_dbyz:
500         btst            &idbyz_bit,SPCOND_FLG(    500         btst            &idbyz_bit,SPCOND_FLG(%a6) # did divide-by-zero occur?
501         bne.w           uieh_divbyzero            501         bne.w           uieh_divbyzero          # yes
502         bra.w           uieh_done                 502         bra.w           uieh_done               # no
503 uieh_div64_a7:                                    503 uieh_div64_a7:
504         btst            &0x5,EXC_ISR(%a6)         504         btst            &0x5,EXC_ISR(%a6)       # supervisor mode?
505         beq.b           uieh_div64_dbyz           505         beq.b           uieh_div64_dbyz         # no
506 # here, a7 has been incremented by 4 bytes in     506 # here, a7 has been incremented by 4 bytes in supervisor mode. we still
507 # may have the following 3 cases:                 507 # may have the following 3 cases:
508 #       (i)     (a7)+                             508 #       (i)     (a7)+
509 #       (ii)    (a7)+; trace                      509 #       (ii)    (a7)+; trace
510 #       (iii)   (a7)+; divide-by-zero             510 #       (iii)   (a7)+; divide-by-zero
511 #                                                 511 #
512         btst            &idbyz_bit,SPCOND_FLG(    512         btst            &idbyz_bit,SPCOND_FLG(%a6) # did divide-by-zero occur?
513         bne.w           uieh_divbyzero_a7         513         bne.w           uieh_divbyzero_a7       # yes
514         tst.b           EXC_ISR(%a6)              514         tst.b           EXC_ISR(%a6)            # no; is trace enabled?
515         bmi.w           uieh_trace_a7             515         bmi.w           uieh_trace_a7           # yes
516         bra.w           uieh_a7                   516         bra.w           uieh_a7                 # no
517                                                   517 
518 #                                                 518 #
519 # now, w/ group2, make movep's decode the fast    519 # now, w/ group2, make movep's decode the fastest since it will
520 # most likely be used the most.                   520 # most likely be used the most.
521 #                                                 521 #
522 uieh_group2:                                      522 uieh_group2:
523         btst            &0x18,%d0                 523         btst            &0x18,%d0               # test for not movep
524         beq.b           uieh_not_movep            524         beq.b           uieh_not_movep
525                                                   525 
526                                                   526 
527         bsr.l           _moveperipheral           527         bsr.l           _moveperipheral         # _movep()
528         bra.w           uieh_done                 528         bra.w           uieh_done
529                                                   529 
530 uieh_not_movep:                                   530 uieh_not_movep:
531         btst            &0x1b,%d0                 531         btst            &0x1b,%d0               # test for chk2,cmp2
532         beq.b           uieh_chk2cmp2             532         beq.b           uieh_chk2cmp2           # go handle chk2,cmp2
533                                                   533 
534         swap            %d0                       534         swap            %d0                     # put opword in lo word
535         cmpi.b          %d0,&0xfc                 535         cmpi.b          %d0,&0xfc               # test for cas2
536         beq.b           uieh_cas2                 536         beq.b           uieh_cas2               # go handle cas2
537                                                   537 
538 uieh_cas:                                         538 uieh_cas:
539                                                   539 
540         bsr.l           _compandset               540         bsr.l           _compandset             # _cas()
541                                                   541 
542 # the cases of "cas Dc,Du,(a7)+" and "cas Dc,D    542 # the cases of "cas Dc,Du,(a7)+" and "cas Dc,Du,-(a7)" used from supervisor
543 # mode are simply not considered valid and the    543 # mode are simply not considered valid and therefore are not handled.
544                                                   544 
545         bra.w           uieh_done                 545         bra.w           uieh_done
546                                                   546 
547 uieh_cas2:                                        547 uieh_cas2:
548                                                   548 
549         mov.l           EXC_EXTWPTR(%a6),%a0      549         mov.l           EXC_EXTWPTR(%a6),%a0    # fetch instruction addr
550         addq.l          &0x2,EXC_EXTWPTR(%a6)     550         addq.l          &0x2,EXC_EXTWPTR(%a6)   # incr instruction ptr
551         bsr.l           _imem_read_word           551         bsr.l           _imem_read_word         # read extension word
552                                                   552 
553         tst.l           %d1                       553         tst.l           %d1                     # ifetch error?
554         bne.w           isp_iacc                  554         bne.w           isp_iacc                # yes
555                                                   555 
556         bsr.l           _compandset2              556         bsr.l           _compandset2            # _cas2()
557         bra.w           uieh_done                 557         bra.w           uieh_done
558                                                   558 
559 uieh_chk2cmp2:                                    559 uieh_chk2cmp2:
560 # chk2 may take a chk exception                   560 # chk2 may take a chk exception
561                                                   561 
562         bsr.l           _chk2_cmp2                562         bsr.l           _chk2_cmp2              # _chk2_cmp2()
563                                                   563 
564 # here we check to see if a chk trap should be    564 # here we check to see if a chk trap should be taken
565         cmpi.b          SPCOND_FLG(%a6),&ichk_    565         cmpi.b          SPCOND_FLG(%a6),&ichk_flg
566         bne.w           uieh_done                 566         bne.w           uieh_done
567         bra.b           uieh_chk_trap             567         bra.b           uieh_chk_trap
568                                                   568 
569 ##############################################    569 ###########################################################################
570                                                   570 
571 #                                                 571 #
572 # the required emulation has been completed. n    572 # the required emulation has been completed. now, clean up the necessary stack
573 # info and prepare for rte                        573 # info and prepare for rte
574 #                                                 574 #
575 uieh_done:                                        575 uieh_done:
576         mov.b           EXC_CC+1(%a6),EXC_ISR+    576         mov.b           EXC_CC+1(%a6),EXC_ISR+1(%a6) # insert new ccodes
577                                                   577 
578 # if exception occurred in user mode, then we     578 # if exception occurred in user mode, then we have to restore a7 in case it
579 # changed. we don't have to update a7  for sup    579 # changed. we don't have to update a7  for supervisor mose because that case
580 # doesn't flow through here                       580 # doesn't flow through here
581         btst            &0x5,EXC_ISR(%a6)         581         btst            &0x5,EXC_ISR(%a6)       # user or supervisor?
582         bne.b           uieh_finish               582         bne.b           uieh_finish             # supervisor
583                                                   583 
584         mov.l           EXC_A7(%a6),%a0           584         mov.l           EXC_A7(%a6),%a0         # fetch user stack pointer
585         mov.l           %a0,%usp                  585         mov.l           %a0,%usp                # restore it
586                                                   586 
587 uieh_finish:                                      587 uieh_finish:
588         movm.l          EXC_DREGS(%a6),&0x3fff    588         movm.l          EXC_DREGS(%a6),&0x3fff  # restore d0-d7/a0-a5
589                                                   589 
590         btst            &0x7,EXC_ISR(%a6)         590         btst            &0x7,EXC_ISR(%a6)       # is trace mode on?
591         bne.b           uieh_trace                591         bne.b           uieh_trace              # yes;go handle trace mode
592                                                   592 
593         mov.l           EXC_EXTWPTR(%a6),EXC_I    593         mov.l           EXC_EXTWPTR(%a6),EXC_IPC(%a6) # new pc on stack frame
594         mov.l           EXC_A6(%a6),(%a6)         594         mov.l           EXC_A6(%a6),(%a6)       # prepare new a6 for unlink
595         unlk            %a6                       595         unlk            %a6                     # unlink stack frame
596         bra.l           _isp_done                 596         bra.l           _isp_done
597                                                   597 
598 #                                                 598 #
599 # The instruction that was just emulated was a    599 # The instruction that was just emulated was also being traced. The trace
600 # trap for this instruction will be lost unles    600 # trap for this instruction will be lost unless we jump to the trace handler.
601 # So, here we create a Trace Exception format     601 # So, here we create a Trace Exception format number two exception stack
602 # frame from the Unimplemented Integer Intruct    602 # frame from the Unimplemented Integer Intruction Exception stack frame
603 # format number zero and jump to the user supp    603 # format number zero and jump to the user supplied hook "_real_trace()".
604 #                                                 604 #
605 #                  UIEH FRAME              TRA    605 #                  UIEH FRAME              TRACE FRAME
606 #               *****************       ******    606 #               *****************       *****************
607 #               * 0x0 *  0x0f4  *       *    C    607 #               * 0x0 *  0x0f4  *       *    Current    *
608 #               *****************       *         608 #               *****************       *      PC       *
609 #               *    Current    *       ******    609 #               *    Current    *       *****************
610 #               *      PC       *       * 0x2     610 #               *      PC       *       * 0x2 *  0x024  *
611 #               *****************       ******    611 #               *****************       *****************
612 #               *      SR       *       *         612 #               *      SR       *       *     Next      *
613 #               *****************       *         613 #               *****************       *      PC       *
614 #             ->*     Old       *       ******    614 #             ->*     Old       *       *****************
615 #  from link -->*      A6       *       *         615 #  from link -->*      A6       *       *      SR       *
616 #               *****************       ******    616 #               *****************       *****************
617 #              /*      A7       *       *         617 #              /*      A7       *       *      New      * <-- for final unlink
618 #             / *               *       *         618 #             / *               *       *      A6       *
619 # link frame <  *****************       ******    619 # link frame <  *****************       *****************
620 #             \ ~               ~       ~         620 #             \ ~               ~       ~               ~
621 #              \*****************       ******    621 #              \*****************       *****************
622 #                                                 622 #
623 uieh_trace:                                       623 uieh_trace:
624         mov.l           EXC_A6(%a6),-0x4(%a6)     624         mov.l           EXC_A6(%a6),-0x4(%a6)
625         mov.w           EXC_ISR(%a6),0x0(%a6)     625         mov.w           EXC_ISR(%a6),0x0(%a6)
626         mov.l           EXC_IPC(%a6),0x8(%a6)     626         mov.l           EXC_IPC(%a6),0x8(%a6)
627         mov.l           EXC_EXTWPTR(%a6),0x2(%    627         mov.l           EXC_EXTWPTR(%a6),0x2(%a6)
628         mov.w           &0x2024,0x6(%a6)          628         mov.w           &0x2024,0x6(%a6)
629         sub.l           &0x4,%a6                  629         sub.l           &0x4,%a6
630         unlk            %a6                       630         unlk            %a6
631         bra.l           _real_trace               631         bra.l           _real_trace
632                                                   632 
633 #                                                 633 #
634 #          UIEH FRAME               CHK FRAME     634 #          UIEH FRAME               CHK FRAME
635 #       *****************       **************    635 #       *****************       *****************
636 #       * 0x0 *  0x0f4  *       *    Current      636 #       * 0x0 *  0x0f4  *       *    Current    *
637 #       *****************       *      PC         637 #       *****************       *      PC       *
638 #       *    Current    *       **************    638 #       *    Current    *       *****************
639 #       *      PC       *       * 0x2 *  0x018    639 #       *      PC       *       * 0x2 *  0x018  *
640 #       *****************       **************    640 #       *****************       *****************
641 #       *      SR       *       *     Next        641 #       *      SR       *       *     Next      *
642 #       *****************       *      PC         642 #       *****************       *      PC       *
643 #           (4 words)           **************    643 #           (4 words)           *****************
644 #                               *      SR         644 #                               *      SR       *
645 #                               **************    645 #                               *****************
646 #                                   (6 words)     646 #                                   (6 words)
647 #                                                 647 #
648 # the chk2 instruction should take a chk trap.    648 # the chk2 instruction should take a chk trap. so, here we must create a
649 # chk stack frame from an unimplemented intege    649 # chk stack frame from an unimplemented integer instruction exception frame
650 # and jump to the user supplied entry point "_    650 # and jump to the user supplied entry point "_real_chk()".
651 #                                                 651 #
652 uieh_chk_trap:                                    652 uieh_chk_trap:
653         mov.b           EXC_CC+1(%a6),EXC_ISR+    653         mov.b           EXC_CC+1(%a6),EXC_ISR+1(%a6) # insert new ccodes
654         movm.l          EXC_DREGS(%a6),&0x3fff    654         movm.l          EXC_DREGS(%a6),&0x3fff  # restore d0-d7/a0-a5
655                                                   655 
656         mov.w           EXC_ISR(%a6),(%a6)        656         mov.w           EXC_ISR(%a6),(%a6)      # put new SR on stack
657         mov.l           EXC_IPC(%a6),0x8(%a6)     657         mov.l           EXC_IPC(%a6),0x8(%a6)   # put "Current PC" on stack
658         mov.l           EXC_EXTWPTR(%a6),0x2(%    658         mov.l           EXC_EXTWPTR(%a6),0x2(%a6) # put "Next PC" on stack
659         mov.w           &0x2018,0x6(%a6)          659         mov.w           &0x2018,0x6(%a6)        # put Vector Offset on stack
660                                                   660 
661         mov.l           EXC_A6(%a6),%a6           661         mov.l           EXC_A6(%a6),%a6         # restore a6
662         add.l           &LOCAL_SIZE,%sp           662         add.l           &LOCAL_SIZE,%sp         # clear stack frame
663                                                   663 
664         bra.l           _real_chk                 664         bra.l           _real_chk
665                                                   665 
666 #                                                 666 #
667 #          UIEH FRAME            DIVBYZERO FRA    667 #          UIEH FRAME            DIVBYZERO FRAME
668 #       *****************       **************    668 #       *****************       *****************
669 #       * 0x0 *  0x0f4  *       *    Current      669 #       * 0x0 *  0x0f4  *       *    Current    *
670 #       *****************       *      PC         670 #       *****************       *      PC       *
671 #       *    Current    *       **************    671 #       *    Current    *       *****************
672 #       *      PC       *       * 0x2 *  0x014    672 #       *      PC       *       * 0x2 *  0x014  *
673 #       *****************       **************    673 #       *****************       *****************
674 #       *      SR       *       *     Next        674 #       *      SR       *       *     Next      *
675 #       *****************       *      PC         675 #       *****************       *      PC       *
676 #           (4 words)           **************    676 #           (4 words)           *****************
677 #                               *      SR         677 #                               *      SR       *
678 #                               **************    678 #                               *****************
679 #                                   (6 words)     679 #                                   (6 words)
680 #                                                 680 #
681 # the divide instruction should take an intege    681 # the divide instruction should take an integer divide by zero trap. so, here
682 # we must create a divbyzero stack frame from     682 # we must create a divbyzero stack frame from an unimplemented integer
683 # instruction exception frame and jump to the     683 # instruction exception frame and jump to the user supplied entry point
684 # "_real_divbyzero()".                            684 # "_real_divbyzero()".
685 #                                                 685 #
686 uieh_divbyzero:                                   686 uieh_divbyzero:
687         mov.b           EXC_CC+1(%a6),EXC_ISR+    687         mov.b           EXC_CC+1(%a6),EXC_ISR+1(%a6) # insert new ccodes
688         movm.l          EXC_DREGS(%a6),&0x3fff    688         movm.l          EXC_DREGS(%a6),&0x3fff  # restore d0-d7/a0-a5
689                                                   689 
690         mov.w           EXC_ISR(%a6),(%a6)        690         mov.w           EXC_ISR(%a6),(%a6)      # put new SR on stack
691         mov.l           EXC_IPC(%a6),0x8(%a6)     691         mov.l           EXC_IPC(%a6),0x8(%a6)   # put "Current PC" on stack
692         mov.l           EXC_EXTWPTR(%a6),0x2(%    692         mov.l           EXC_EXTWPTR(%a6),0x2(%a6) # put "Next PC" on stack
693         mov.w           &0x2014,0x6(%a6)          693         mov.w           &0x2014,0x6(%a6)        # put Vector Offset on stack
694                                                   694 
695         mov.l           EXC_A6(%a6),%a6           695         mov.l           EXC_A6(%a6),%a6         # restore a6
696         add.l           &LOCAL_SIZE,%sp           696         add.l           &LOCAL_SIZE,%sp         # clear stack frame
697                                                   697 
698         bra.l           _real_divbyzero           698         bra.l           _real_divbyzero
699                                                   699 
700 #                                                 700 #
701 #                                DIVBYZERO FRA    701 #                                DIVBYZERO FRAME
702 #                               **************    702 #                               *****************
703 #                               *    Current      703 #                               *    Current    *
704 #          UIEH FRAME           *      PC         704 #          UIEH FRAME           *      PC       *
705 #       *****************       **************    705 #       *****************       *****************
706 #       * 0x0 *  0x0f4  *       * 0x2 * 0x014     706 #       * 0x0 *  0x0f4  *       * 0x2 * 0x014   *
707 #       *****************       **************    707 #       *****************       *****************
708 #       *    Current    *       *     Next        708 #       *    Current    *       *     Next      *
709 #       *      PC       *       *      PC         709 #       *      PC       *       *      PC       *
710 #       *****************       **************    710 #       *****************       *****************
711 #       *      SR       *       *      SR         711 #       *      SR       *       *      SR       *
712 #       *****************       **************    712 #       *****************       *****************
713 #           (4 words)               (6 words)     713 #           (4 words)               (6 words)
714 #                                                 714 #
715 # the divide instruction should take an intege    715 # the divide instruction should take an integer divide by zero trap. so, here
716 # we must create a divbyzero stack frame from     716 # we must create a divbyzero stack frame from an unimplemented integer
717 # instruction exception frame and jump to the     717 # instruction exception frame and jump to the user supplied entry point
718 # "_real_divbyzero()".                            718 # "_real_divbyzero()".
719 #                                                 719 #
720 # However, we must also deal with the fact tha    720 # However, we must also deal with the fact that (a7)+ was used from supervisor
721 # mode, thereby shifting the stack frame up 4     721 # mode, thereby shifting the stack frame up 4 bytes.
722 #                                                 722 #
723 uieh_divbyzero_a7:                                723 uieh_divbyzero_a7:
724         mov.b           EXC_CC+1(%a6),EXC_ISR+    724         mov.b           EXC_CC+1(%a6),EXC_ISR+1(%a6) # insert new ccodes
725         movm.l          EXC_DREGS(%a6),&0x3fff    725         movm.l          EXC_DREGS(%a6),&0x3fff  # restore d0-d7/a0-a5
726                                                   726 
727         mov.l           EXC_IPC(%a6),0xc(%a6)     727         mov.l           EXC_IPC(%a6),0xc(%a6)   # put "Current PC" on stack
728         mov.w           &0x2014,0xa(%a6)          728         mov.w           &0x2014,0xa(%a6)        # put Vector Offset on stack
729         mov.l           EXC_EXTWPTR(%a6),0x6(%    729         mov.l           EXC_EXTWPTR(%a6),0x6(%a6) # put "Next PC" on stack
730                                                   730 
731         mov.l           EXC_A6(%a6),%a6           731         mov.l           EXC_A6(%a6),%a6         # restore a6
732         add.l           &4+LOCAL_SIZE,%sp         732         add.l           &4+LOCAL_SIZE,%sp       # clear stack frame
733                                                   733 
734         bra.l           _real_divbyzero           734         bra.l           _real_divbyzero
735                                                   735 
736 #                                                 736 #
737 #                                  TRACE FRAME    737 #                                  TRACE FRAME
738 #                               **************    738 #                               *****************
739 #                               *    Current      739 #                               *    Current    *
740 #          UIEH FRAME           *      PC         740 #          UIEH FRAME           *      PC       *
741 #       *****************       **************    741 #       *****************       *****************
742 #       * 0x0 *  0x0f4  *       * 0x2 * 0x024     742 #       * 0x0 *  0x0f4  *       * 0x2 * 0x024   *
743 #       *****************       **************    743 #       *****************       *****************
744 #       *    Current    *       *     Next        744 #       *    Current    *       *     Next      *
745 #       *      PC       *       *      PC         745 #       *      PC       *       *      PC       *
746 #       *****************       **************    746 #       *****************       *****************
747 #       *      SR       *       *      SR         747 #       *      SR       *       *      SR       *
748 #       *****************       **************    748 #       *****************       *****************
749 #           (4 words)               (6 words)     749 #           (4 words)               (6 words)
750 #                                                 750 #
751 #                                                 751 #
752 # The instruction that was just emulated was a    752 # The instruction that was just emulated was also being traced. The trace
753 # trap for this instruction will be lost unles    753 # trap for this instruction will be lost unless we jump to the trace handler.
754 # So, here we create a Trace Exception format     754 # So, here we create a Trace Exception format number two exception stack
755 # frame from the Unimplemented Integer Intruct    755 # frame from the Unimplemented Integer Intruction Exception stack frame
756 # format number zero and jump to the user supp    756 # format number zero and jump to the user supplied hook "_real_trace()".
757 #                                                 757 #
758 # However, we must also deal with the fact tha    758 # However, we must also deal with the fact that (a7)+ was used from supervisor
759 # mode, thereby shifting the stack frame up 4     759 # mode, thereby shifting the stack frame up 4 bytes.
760 #                                                 760 #
761 uieh_trace_a7:                                    761 uieh_trace_a7:
762         mov.b           EXC_CC+1(%a6),EXC_ISR+    762         mov.b           EXC_CC+1(%a6),EXC_ISR+1(%a6) # insert new ccodes
763         movm.l          EXC_DREGS(%a6),&0x3fff    763         movm.l          EXC_DREGS(%a6),&0x3fff  # restore d0-d7/a0-a5
764                                                   764 
765         mov.l           EXC_IPC(%a6),0xc(%a6)     765         mov.l           EXC_IPC(%a6),0xc(%a6)   # put "Current PC" on stack
766         mov.w           &0x2024,0xa(%a6)          766         mov.w           &0x2024,0xa(%a6)        # put Vector Offset on stack
767         mov.l           EXC_EXTWPTR(%a6),0x6(%    767         mov.l           EXC_EXTWPTR(%a6),0x6(%a6) # put "Next PC" on stack
768                                                   768 
769         mov.l           EXC_A6(%a6),%a6           769         mov.l           EXC_A6(%a6),%a6         # restore a6
770         add.l           &4+LOCAL_SIZE,%sp         770         add.l           &4+LOCAL_SIZE,%sp       # clear stack frame
771                                                   771 
772         bra.l           _real_trace               772         bra.l           _real_trace
773                                                   773 
774 #                                                 774 #
775 #                                  UIEH FRAME     775 #                                  UIEH FRAME
776 #                               **************    776 #                               *****************
777 #                               * 0x0 * 0x0f4     777 #                               * 0x0 * 0x0f4   *
778 #          UIEH FRAME           **************    778 #          UIEH FRAME           *****************
779 #       *****************       *     Next        779 #       *****************       *     Next      *
780 #       * 0x0 *  0x0f4  *       *      PC         780 #       * 0x0 *  0x0f4  *       *      PC       *
781 #       *****************       **************    781 #       *****************       *****************
782 #       *    Current    *       *      SR         782 #       *    Current    *       *      SR       *
783 #       *      PC       *       **************    783 #       *      PC       *       *****************
784 #       *****************           (4 words)     784 #       *****************           (4 words)
785 #       *      SR       *                         785 #       *      SR       *
786 #       *****************                         786 #       *****************
787 #           (4 words)                             787 #           (4 words)
788 uieh_a7:                                          788 uieh_a7:
789         mov.b           EXC_CC+1(%a6),EXC_ISR+    789         mov.b           EXC_CC+1(%a6),EXC_ISR+1(%a6) # insert new ccodes
790         movm.l          EXC_DREGS(%a6),&0x3fff    790         movm.l          EXC_DREGS(%a6),&0x3fff  # restore d0-d7/a0-a5
791                                                   791 
792         mov.w           &0x00f4,0xe(%a6)          792         mov.w           &0x00f4,0xe(%a6)        # put Vector Offset on stack
793         mov.l           EXC_EXTWPTR(%a6),0xa(%    793         mov.l           EXC_EXTWPTR(%a6),0xa(%a6) # put "Next PC" on stack
794         mov.w           EXC_ISR(%a6),0x8(%a6)     794         mov.w           EXC_ISR(%a6),0x8(%a6)   # put SR on stack
795                                                   795 
796         mov.l           EXC_A6(%a6),%a6           796         mov.l           EXC_A6(%a6),%a6         # restore a6
797         add.l           &8+LOCAL_SIZE,%sp         797         add.l           &8+LOCAL_SIZE,%sp       # clear stack frame
798         bra.l           _isp_done                 798         bra.l           _isp_done
799                                                   799 
800 ##########                                        800 ##########
801                                                   801 
802 # this is the exit point if a data read or wri    802 # this is the exit point if a data read or write fails.
803 # a0 = failing address                            803 # a0 = failing address
804 # d0 = fslw                                       804 # d0 = fslw
805 isp_dacc:                                         805 isp_dacc:
806         mov.l           %a0,(%a6)                 806         mov.l           %a0,(%a6)               # save address
807         mov.l           %d0,-0x4(%a6)             807         mov.l           %d0,-0x4(%a6)           # save partial fslw
808                                                   808 
809         lea             -64(%a6),%sp              809         lea             -64(%a6),%sp
810         movm.l          (%sp)+,&0x7fff            810         movm.l          (%sp)+,&0x7fff          # restore d0-d7/a0-a6
811                                                   811 
812         mov.l           0xc(%sp),-(%sp)           812         mov.l           0xc(%sp),-(%sp)         # move voff,hi(pc)
813         mov.l           0x4(%sp),0x10(%sp)        813         mov.l           0x4(%sp),0x10(%sp)      # store fslw
814         mov.l           0xc(%sp),0x4(%sp)         814         mov.l           0xc(%sp),0x4(%sp)       # store sr,lo(pc)
815         mov.l           0x8(%sp),0xc(%sp)         815         mov.l           0x8(%sp),0xc(%sp)       # store address
816         mov.l           (%sp)+,0x4(%sp)           816         mov.l           (%sp)+,0x4(%sp)         # store voff,hi(pc)
817         mov.w           &0x4008,0x6(%sp)          817         mov.w           &0x4008,0x6(%sp)        # store new voff
818                                                   818 
819         bra.b           isp_acc_exit              819         bra.b           isp_acc_exit
820                                                   820 
821 # this is the exit point if an instruction wor    821 # this is the exit point if an instruction word read fails.
822 # FSLW:                                           822 # FSLW:
823 #       misaligned = true                         823 #       misaligned = true
824 #       read = true                               824 #       read = true
825 #       size = word                               825 #       size = word
826 #       instruction = true                        826 #       instruction = true
827 #       software emulation error = true           827 #       software emulation error = true
828 isp_iacc:                                         828 isp_iacc:
829         movm.l          EXC_DREGS(%a6),&0x3fff    829         movm.l          EXC_DREGS(%a6),&0x3fff  # restore d0-d7/a0-a5
830         unlk            %a6                       830         unlk            %a6                     # unlink frame
831         sub.w           &0x8,%sp                  831         sub.w           &0x8,%sp                # make room for acc frame
832         mov.l           0x8(%sp),(%sp)            832         mov.l           0x8(%sp),(%sp)          # store sr,lo(pc)
833         mov.w           0xc(%sp),0x4(%sp)         833         mov.w           0xc(%sp),0x4(%sp)       # store hi(pc)
834         mov.w           &0x4008,0x6(%sp)          834         mov.w           &0x4008,0x6(%sp)        # store new voff
835         mov.l           0x2(%sp),0x8(%sp)         835         mov.l           0x2(%sp),0x8(%sp)       # store address (=pc)
836         mov.l           &0x09428001,0xc(%sp)      836         mov.l           &0x09428001,0xc(%sp)    # store fslw
837                                                   837 
838 isp_acc_exit:                                     838 isp_acc_exit:
839         btst            &0x5,(%sp)                839         btst            &0x5,(%sp)              # user or supervisor?
840         beq.b           isp_acc_exit2             840         beq.b           isp_acc_exit2           # user
841         bset            &0x2,0xd(%sp)             841         bset            &0x2,0xd(%sp)           # set supervisor TM bit
842 isp_acc_exit2:                                    842 isp_acc_exit2:
843         bra.l           _real_access              843         bra.l           _real_access
844                                                   844 
845 # if the addressing mode was (an)+ or -(an), t    845 # if the addressing mode was (an)+ or -(an), the address register must
846 # be restored to its pre-exception value befor    846 # be restored to its pre-exception value before entering _real_access.
847 isp_restore:                                      847 isp_restore:
848         cmpi.b          SPCOND_FLG(%a6),&resto    848         cmpi.b          SPCOND_FLG(%a6),&restore_flg # do we need a restore?
849         bne.b           isp_restore_done          849         bne.b           isp_restore_done        # no
850         clr.l           %d0                       850         clr.l           %d0
851         mov.b           EXC_SAVREG(%a6),%d0       851         mov.b           EXC_SAVREG(%a6),%d0     # regno to restore
852         mov.l           EXC_SAVVAL(%a6),(EXC_A    852         mov.l           EXC_SAVVAL(%a6),(EXC_AREGS,%a6,%d0.l*4) # restore value
853 isp_restore_done:                                 853 isp_restore_done:
854         rts                                       854         rts
855                                                   855 
856 ##############################################    856 #########################################################################
857 # XDEF ***************************************    857 # XDEF **************************************************************** #
858 #       _calc_ea(): routine to calculate effec    858 #       _calc_ea(): routine to calculate effective address              #
859 #                                                 859 #                                                                       #
860 # XREF ***************************************    860 # XREF **************************************************************** #
861 #       _imem_read_word() - read instruction w    861 #       _imem_read_word() - read instruction word                       #
862 #       _imem_read_long() - read instruction l    862 #       _imem_read_long() - read instruction longword                   #
863 #       _dmem_read_long() - read data longword    863 #       _dmem_read_long() - read data longword (for memory indirect)    #
864 #       isp_iacc() - handle instruction access    864 #       isp_iacc() - handle instruction access error exception          #
865 #       isp_dacc() - handle data access error     865 #       isp_dacc() - handle data access error exception                 #
866 #                                                 866 #                                                                       #
867 # INPUT **************************************    867 # INPUT *************************************************************** #
868 #       d0 = number of bytes related to effect    868 #       d0 = number of bytes related to effective address (w,l)         #
869 #                                                 869 #                                                                       #
870 # OUTPUT *************************************    870 # OUTPUT ************************************************************** #
871 #       If exiting through isp_dacc...            871 #       If exiting through isp_dacc...                                  #
872 #               a0 = failing address              872 #               a0 = failing address                                    #
873 #               d0 = FSLW                         873 #               d0 = FSLW                                               #
874 #       elsif exiting though isp_iacc...          874 #       elsif exiting though isp_iacc...                                #
875 #               none                              875 #               none                                                    #
876 #       else                                      876 #       else                                                            #
877 #               a0 = effective address            877 #               a0 = effective address                                  #
878 #                                                 878 #                                                                       #
879 # ALGORITHM **********************************    879 # ALGORITHM *********************************************************** #
880 #       The effective address type is decoded     880 #       The effective address type is decoded from the opword residing  #
881 # on the stack. A jump table is used to vector    881 # on the stack. A jump table is used to vector to a routine for the     #
882 # appropriate mode. Since none of the emulated    882 # appropriate mode. Since none of the emulated integer instructions     #
883 # uses byte-sized operands, only handle word a    883 # uses byte-sized operands, only handle word and long operations.       #
884 #                                                 884 #                                                                       #
885 #       Dn,An   - shouldn't enter here            885 #       Dn,An   - shouldn't enter here                                  #
886 #       (An)    - fetch An value from stack       886 #       (An)    - fetch An value from stack                             #
887 #       -(An)   - fetch An value from stack; r    887 #       -(An)   - fetch An value from stack; return decr value;         #
888 #                 place decr value on stack; s    888 #                 place decr value on stack; store old value in case of #
889 #                 future access error; if -(a7    889 #                 future access error; if -(a7), set mda7_flg in        #
890 #                 SPCOND_FLG                      890 #                 SPCOND_FLG                                            #
891 #       (An)+   - fetch An value from stack; r    891 #       (An)+   - fetch An value from stack; return value;              #
892 #                 place incr value on stack; s    892 #                 place incr value on stack; store old value in case of #
893 #                 future access error; if (a7)    893 #                 future access error; if (a7)+, set mia7_flg in        #
894 #                 SPCOND_FLG                      894 #                 SPCOND_FLG                                            #
895 #       (d16,An) - fetch An value from stack;     895 #       (d16,An) - fetch An value from stack; read d16 using            #
896 #                 _imem_read_word(); fetch may    896 #                 _imem_read_word(); fetch may fail -> branch to        #
897 #                 isp_iacc()                      897 #                 isp_iacc()                                            #
898 #       (xxx).w,(xxx).l - use _imem_read_{word    898 #       (xxx).w,(xxx).l - use _imem_read_{word,long}() to fetch         #
899 #                 address; fetch may fail         899 #                 address; fetch may fail                               #
900 #       #<data> - return address of immediate     900 #       #<data> - return address of immediate value; set immed_flg      #
901 #                 in SPCOND_FLG                   901 #                 in SPCOND_FLG                                         #
902 #       (d16,PC) - fetch stacked PC value; rea    902 #       (d16,PC) - fetch stacked PC value; read d16 using               #
903 #                 _imem_read_word(); fetch may    903 #                 _imem_read_word(); fetch may fail -> branch to        #
904 #                 isp_iacc()                      904 #                 isp_iacc()                                            #
905 #       everything else - read needed displace    905 #       everything else - read needed displacements as appropriate w/   #
906 #                 _imem_read_{word,long}(); re    906 #                 _imem_read_{word,long}(); read may fail; if memory    #
907 #                 indirect, read indirect addr    907 #                 indirect, read indirect address using                 #
908 #                 _dmem_read_long() which may     908 #                 _dmem_read_long() which may also fail                 #
909 #                                                 909 #                                                                       #
910 ##############################################    910 #########################################################################
911                                                   911 
912         global          _calc_ea                  912         global          _calc_ea
913 _calc_ea:                                         913 _calc_ea:
914         mov.l           %d0,%a0                   914         mov.l           %d0,%a0                 # move # bytes to a0
915                                                   915 
916 # MODE and REG are taken from the EXC_OPWORD.     916 # MODE and REG are taken from the EXC_OPWORD.
917         mov.w           EXC_OPWORD(%a6),%d0       917         mov.w           EXC_OPWORD(%a6),%d0     # fetch opcode word
918         mov.w           %d0,%d1                   918         mov.w           %d0,%d1                 # make a copy
919                                                   919 
920         andi.w          &0x3f,%d0                 920         andi.w          &0x3f,%d0               # extract mode field
921         andi.l          &0x7,%d1                  921         andi.l          &0x7,%d1                # extract reg  field
922                                                   922 
923 # jump to the corresponding function for each     923 # jump to the corresponding function for each {MODE,REG} pair.
924         mov.w           (tbl_ea_mode.b,%pc,%d0    924         mov.w           (tbl_ea_mode.b,%pc,%d0.w*2), %d0 # fetch jmp distance
925         jmp             (tbl_ea_mode.b,%pc,%d0    925         jmp             (tbl_ea_mode.b,%pc,%d0.w*1) # jmp to correct ea mode
926                                                   926 
927         swbeg           &64                       927         swbeg           &64
928 tbl_ea_mode:                                      928 tbl_ea_mode:
929         short           tbl_ea_mode     -         929         short           tbl_ea_mode     -       tbl_ea_mode
930         short           tbl_ea_mode     -         930         short           tbl_ea_mode     -       tbl_ea_mode
931         short           tbl_ea_mode     -         931         short           tbl_ea_mode     -       tbl_ea_mode
932         short           tbl_ea_mode     -         932         short           tbl_ea_mode     -       tbl_ea_mode
933         short           tbl_ea_mode     -         933         short           tbl_ea_mode     -       tbl_ea_mode
934         short           tbl_ea_mode     -         934         short           tbl_ea_mode     -       tbl_ea_mode
935         short           tbl_ea_mode     -         935         short           tbl_ea_mode     -       tbl_ea_mode
936         short           tbl_ea_mode     -         936         short           tbl_ea_mode     -       tbl_ea_mode
937                                                   937 
938         short           tbl_ea_mode     -         938         short           tbl_ea_mode     -       tbl_ea_mode
939         short           tbl_ea_mode     -         939         short           tbl_ea_mode     -       tbl_ea_mode
940         short           tbl_ea_mode     -         940         short           tbl_ea_mode     -       tbl_ea_mode
941         short           tbl_ea_mode     -         941         short           tbl_ea_mode     -       tbl_ea_mode
942         short           tbl_ea_mode     -         942         short           tbl_ea_mode     -       tbl_ea_mode
943         short           tbl_ea_mode     -         943         short           tbl_ea_mode     -       tbl_ea_mode
944         short           tbl_ea_mode     -         944         short           tbl_ea_mode     -       tbl_ea_mode
945         short           tbl_ea_mode     -         945         short           tbl_ea_mode     -       tbl_ea_mode
946                                                   946 
947         short           addr_ind_a0     -         947         short           addr_ind_a0     -       tbl_ea_mode
948         short           addr_ind_a1     -         948         short           addr_ind_a1     -       tbl_ea_mode
949         short           addr_ind_a2     -         949         short           addr_ind_a2     -       tbl_ea_mode
950         short           addr_ind_a3     -         950         short           addr_ind_a3     -       tbl_ea_mode
951         short           addr_ind_a4     -         951         short           addr_ind_a4     -       tbl_ea_mode
952         short           addr_ind_a5     -         952         short           addr_ind_a5     -       tbl_ea_mode
953         short           addr_ind_a6     -         953         short           addr_ind_a6     -       tbl_ea_mode
954         short           addr_ind_a7     -         954         short           addr_ind_a7     -       tbl_ea_mode
955                                                   955 
956         short           addr_ind_p_a0   -         956         short           addr_ind_p_a0   -       tbl_ea_mode
957         short           addr_ind_p_a1   -         957         short           addr_ind_p_a1   -       tbl_ea_mode
958         short           addr_ind_p_a2   -         958         short           addr_ind_p_a2   -       tbl_ea_mode
959         short           addr_ind_p_a3   -         959         short           addr_ind_p_a3   -       tbl_ea_mode
960         short           addr_ind_p_a4   -         960         short           addr_ind_p_a4   -       tbl_ea_mode
961         short           addr_ind_p_a5   -         961         short           addr_ind_p_a5   -       tbl_ea_mode
962         short           addr_ind_p_a6   -         962         short           addr_ind_p_a6   -       tbl_ea_mode
963         short           addr_ind_p_a7   -         963         short           addr_ind_p_a7   -       tbl_ea_mode
964                                                   964 
965         short           addr_ind_m_a0             965         short           addr_ind_m_a0           -       tbl_ea_mode
966         short           addr_ind_m_a1             966         short           addr_ind_m_a1           -       tbl_ea_mode
967         short           addr_ind_m_a2             967         short           addr_ind_m_a2           -       tbl_ea_mode
968         short           addr_ind_m_a3             968         short           addr_ind_m_a3           -       tbl_ea_mode
969         short           addr_ind_m_a4             969         short           addr_ind_m_a4           -       tbl_ea_mode
970         short           addr_ind_m_a5             970         short           addr_ind_m_a5           -       tbl_ea_mode
971         short           addr_ind_m_a6             971         short           addr_ind_m_a6           -       tbl_ea_mode
972         short           addr_ind_m_a7             972         short           addr_ind_m_a7           -       tbl_ea_mode
973                                                   973 
974         short           addr_ind_disp_a0          974         short           addr_ind_disp_a0        -       tbl_ea_mode
975         short           addr_ind_disp_a1          975         short           addr_ind_disp_a1        -       tbl_ea_mode
976         short           addr_ind_disp_a2          976         short           addr_ind_disp_a2        -       tbl_ea_mode
977         short           addr_ind_disp_a3          977         short           addr_ind_disp_a3        -       tbl_ea_mode
978         short           addr_ind_disp_a4          978         short           addr_ind_disp_a4        -       tbl_ea_mode
979         short           addr_ind_disp_a5          979         short           addr_ind_disp_a5        -       tbl_ea_mode
980         short           addr_ind_disp_a6          980         short           addr_ind_disp_a6        -       tbl_ea_mode
981         short           addr_ind_disp_a7          981         short           addr_ind_disp_a7        -       tbl_ea_mode
982                                                   982 
983         short           _addr_ind_ext             983         short           _addr_ind_ext           -       tbl_ea_mode
984         short           _addr_ind_ext             984         short           _addr_ind_ext           -       tbl_ea_mode
985         short           _addr_ind_ext             985         short           _addr_ind_ext           -       tbl_ea_mode
986         short           _addr_ind_ext             986         short           _addr_ind_ext           -       tbl_ea_mode
987         short           _addr_ind_ext             987         short           _addr_ind_ext           -       tbl_ea_mode
988         short           _addr_ind_ext             988         short           _addr_ind_ext           -       tbl_ea_mode
989         short           _addr_ind_ext             989         short           _addr_ind_ext           -       tbl_ea_mode
990         short           _addr_ind_ext             990         short           _addr_ind_ext           -       tbl_ea_mode
991                                                   991 
992         short           abs_short                 992         short           abs_short               -       tbl_ea_mode
993         short           abs_long                  993         short           abs_long                -       tbl_ea_mode
994         short           pc_ind                    994         short           pc_ind                  -       tbl_ea_mode
995         short           pc_ind_ext                995         short           pc_ind_ext              -       tbl_ea_mode
996         short           immediate                 996         short           immediate               -       tbl_ea_mode
997         short           tbl_ea_mode               997         short           tbl_ea_mode             -       tbl_ea_mode
998         short           tbl_ea_mode               998         short           tbl_ea_mode             -       tbl_ea_mode
999         short           tbl_ea_mode               999         short           tbl_ea_mode             -       tbl_ea_mode
1000                                                  1000 
1001 ###################################              1001 ###################################
1002 # Address register indirect: (An) #              1002 # Address register indirect: (An) #
1003 ###################################              1003 ###################################
1004 addr_ind_a0:                                     1004 addr_ind_a0:
1005         mov.l           EXC_A0(%a6),%a0          1005         mov.l           EXC_A0(%a6),%a0         # Get current a0
1006         rts                                      1006         rts
1007                                                  1007 
1008 addr_ind_a1:                                     1008 addr_ind_a1:
1009         mov.l           EXC_A1(%a6),%a0          1009         mov.l           EXC_A1(%a6),%a0         # Get current a1
1010         rts                                      1010         rts
1011                                                  1011 
1012 addr_ind_a2:                                     1012 addr_ind_a2:
1013         mov.l           EXC_A2(%a6),%a0          1013         mov.l           EXC_A2(%a6),%a0         # Get current a2
1014         rts                                      1014         rts
1015                                                  1015 
1016 addr_ind_a3:                                     1016 addr_ind_a3:
1017         mov.l           EXC_A3(%a6),%a0          1017         mov.l           EXC_A3(%a6),%a0         # Get current a3
1018         rts                                      1018         rts
1019                                                  1019 
1020 addr_ind_a4:                                     1020 addr_ind_a4:
1021         mov.l           EXC_A4(%a6),%a0          1021         mov.l           EXC_A4(%a6),%a0         # Get current a4
1022         rts                                      1022         rts
1023                                                  1023 
1024 addr_ind_a5:                                     1024 addr_ind_a5:
1025         mov.l           EXC_A5(%a6),%a0          1025         mov.l           EXC_A5(%a6),%a0         # Get current a5
1026         rts                                      1026         rts
1027                                                  1027 
1028 addr_ind_a6:                                     1028 addr_ind_a6:
1029         mov.l           EXC_A6(%a6),%a0          1029         mov.l           EXC_A6(%a6),%a0         # Get current a6
1030         rts                                      1030         rts
1031                                                  1031 
1032 addr_ind_a7:                                     1032 addr_ind_a7:
1033         mov.l           EXC_A7(%a6),%a0          1033         mov.l           EXC_A7(%a6),%a0         # Get current a7
1034         rts                                      1034         rts
1035                                                  1035 
1036 #############################################    1036 #####################################################
1037 # Address register indirect w/ postincrement:    1037 # Address register indirect w/ postincrement: (An)+ #
1038 #############################################    1038 #####################################################
1039 addr_ind_p_a0:                                   1039 addr_ind_p_a0:
1040         mov.l           %a0,%d0                  1040         mov.l           %a0,%d0                 # copy no. bytes
1041         mov.l           EXC_A0(%a6),%a0          1041         mov.l           EXC_A0(%a6),%a0         # load current value
1042         add.l           %a0,%d0                  1042         add.l           %a0,%d0                 # increment
1043         mov.l           %d0,EXC_A0(%a6)          1043         mov.l           %d0,EXC_A0(%a6)         # save incremented value
1044                                                  1044 
1045         mov.l           %a0,EXC_SAVVAL(%a6)      1045         mov.l           %a0,EXC_SAVVAL(%a6)     # save in case of access error
1046         mov.b           &0x0,EXC_SAVREG(%a6)     1046         mov.b           &0x0,EXC_SAVREG(%a6)    # save regno, too
1047         mov.b           &restore_flg,SPCOND_F    1047         mov.b           &restore_flg,SPCOND_FLG(%a6) # set flag
1048         rts                                      1048         rts
1049                                                  1049 
1050 addr_ind_p_a1:                                   1050 addr_ind_p_a1:
1051         mov.l           %a0,%d0                  1051         mov.l           %a0,%d0                 # copy no. bytes
1052         mov.l           EXC_A1(%a6),%a0          1052         mov.l           EXC_A1(%a6),%a0         # load current value
1053         add.l           %a0,%d0                  1053         add.l           %a0,%d0                 # increment
1054         mov.l           %d0,EXC_A1(%a6)          1054         mov.l           %d0,EXC_A1(%a6)         # save incremented value
1055                                                  1055 
1056         mov.l           %a0,EXC_SAVVAL(%a6)      1056         mov.l           %a0,EXC_SAVVAL(%a6)     # save in case of access error
1057         mov.b           &0x1,EXC_SAVREG(%a6)     1057         mov.b           &0x1,EXC_SAVREG(%a6)    # save regno, too
1058         mov.b           &restore_flg,SPCOND_F    1058         mov.b           &restore_flg,SPCOND_FLG(%a6) # set flag
1059         rts                                      1059         rts
1060                                                  1060 
1061 addr_ind_p_a2:                                   1061 addr_ind_p_a2:
1062         mov.l           %a0,%d0                  1062         mov.l           %a0,%d0                 # copy no. bytes
1063         mov.l           EXC_A2(%a6),%a0          1063         mov.l           EXC_A2(%a6),%a0         # load current value
1064         add.l           %a0,%d0                  1064         add.l           %a0,%d0                 # increment
1065         mov.l           %d0,EXC_A2(%a6)          1065         mov.l           %d0,EXC_A2(%a6)         # save incremented value
1066                                                  1066 
1067         mov.l           %a0,EXC_SAVVAL(%a6)      1067         mov.l           %a0,EXC_SAVVAL(%a6)     # save in case of access error
1068         mov.b           &0x2,EXC_SAVREG(%a6)     1068         mov.b           &0x2,EXC_SAVREG(%a6)    # save regno, too
1069         mov.b           &restore_flg,SPCOND_F    1069         mov.b           &restore_flg,SPCOND_FLG(%a6) # set flag
1070         rts                                      1070         rts
1071                                                  1071 
1072 addr_ind_p_a3:                                   1072 addr_ind_p_a3:
1073         mov.l           %a0,%d0                  1073         mov.l           %a0,%d0                 # copy no. bytes
1074         mov.l           EXC_A3(%a6),%a0          1074         mov.l           EXC_A3(%a6),%a0         # load current value
1075         add.l           %a0,%d0                  1075         add.l           %a0,%d0                 # increment
1076         mov.l           %d0,EXC_A3(%a6)          1076         mov.l           %d0,EXC_A3(%a6)         # save incremented value
1077                                                  1077 
1078         mov.l           %a0,EXC_SAVVAL(%a6)      1078         mov.l           %a0,EXC_SAVVAL(%a6)     # save in case of access error
1079         mov.b           &0x3,EXC_SAVREG(%a6)     1079         mov.b           &0x3,EXC_SAVREG(%a6)    # save regno, too
1080         mov.b           &restore_flg,SPCOND_F    1080         mov.b           &restore_flg,SPCOND_FLG(%a6) # set flag
1081         rts                                      1081         rts
1082                                                  1082 
1083 addr_ind_p_a4:                                   1083 addr_ind_p_a4:
1084         mov.l           %a0,%d0                  1084         mov.l           %a0,%d0                 # copy no. bytes
1085         mov.l           EXC_A4(%a6),%a0          1085         mov.l           EXC_A4(%a6),%a0         # load current value
1086         add.l           %a0,%d0                  1086         add.l           %a0,%d0                 # increment
1087         mov.l           %d0,EXC_A4(%a6)          1087         mov.l           %d0,EXC_A4(%a6)         # save incremented value
1088                                                  1088 
1089         mov.l           %a0,EXC_SAVVAL(%a6)      1089         mov.l           %a0,EXC_SAVVAL(%a6)     # save in case of access error
1090         mov.b           &0x4,EXC_SAVREG(%a6)     1090         mov.b           &0x4,EXC_SAVREG(%a6)    # save regno, too
1091         mov.b           &restore_flg,SPCOND_F    1091         mov.b           &restore_flg,SPCOND_FLG(%a6) # set flag
1092         rts                                      1092         rts
1093                                                  1093 
1094 addr_ind_p_a5:                                   1094 addr_ind_p_a5:
1095         mov.l           %a0,%d0                  1095         mov.l           %a0,%d0                 # copy no. bytes
1096         mov.l           EXC_A5(%a6),%a0          1096         mov.l           EXC_A5(%a6),%a0         # load current value
1097         add.l           %a0,%d0                  1097         add.l           %a0,%d0                 # increment
1098         mov.l           %d0,EXC_A5(%a6)          1098         mov.l           %d0,EXC_A5(%a6)         # save incremented value
1099                                                  1099 
1100         mov.l           %a0,EXC_SAVVAL(%a6)      1100         mov.l           %a0,EXC_SAVVAL(%a6)     # save in case of access error
1101         mov.b           &0x5,EXC_SAVREG(%a6)     1101         mov.b           &0x5,EXC_SAVREG(%a6)    # save regno, too
1102         mov.b           &restore_flg,SPCOND_F    1102         mov.b           &restore_flg,SPCOND_FLG(%a6) # set flag
1103         rts                                      1103         rts
1104                                                  1104 
1105 addr_ind_p_a6:                                   1105 addr_ind_p_a6:
1106         mov.l           %a0,%d0                  1106         mov.l           %a0,%d0                 # copy no. bytes
1107         mov.l           EXC_A6(%a6),%a0          1107         mov.l           EXC_A6(%a6),%a0         # load current value
1108         add.l           %a0,%d0                  1108         add.l           %a0,%d0                 # increment
1109         mov.l           %d0,EXC_A6(%a6)          1109         mov.l           %d0,EXC_A6(%a6)         # save incremented value
1110                                                  1110 
1111         mov.l           %a0,EXC_SAVVAL(%a6)      1111         mov.l           %a0,EXC_SAVVAL(%a6)     # save in case of access error
1112         mov.b           &0x6,EXC_SAVREG(%a6)     1112         mov.b           &0x6,EXC_SAVREG(%a6)    # save regno, too
1113         mov.b           &restore_flg,SPCOND_F    1113         mov.b           &restore_flg,SPCOND_FLG(%a6) # set flag
1114         rts                                      1114         rts
1115                                                  1115 
1116 addr_ind_p_a7:                                   1116 addr_ind_p_a7:
1117         mov.b           &mia7_flg,SPCOND_FLG(    1117         mov.b           &mia7_flg,SPCOND_FLG(%a6) # set "special case" flag
1118                                                  1118 
1119         mov.l           %a0,%d0                  1119         mov.l           %a0,%d0                 # copy no. bytes
1120         mov.l           EXC_A7(%a6),%a0          1120         mov.l           EXC_A7(%a6),%a0         # load current value
1121         add.l           %a0,%d0                  1121         add.l           %a0,%d0                 # increment
1122         mov.l           %d0,EXC_A7(%a6)          1122         mov.l           %d0,EXC_A7(%a6)         # save incremented value
1123         rts                                      1123         rts
1124                                                  1124 
1125 #############################################    1125 ####################################################
1126 # Address register indirect w/ predecrement:     1126 # Address register indirect w/ predecrement: -(An) #
1127 #############################################    1127 ####################################################
1128 addr_ind_m_a0:                                   1128 addr_ind_m_a0:
1129         mov.l           EXC_A0(%a6),%d0          1129         mov.l           EXC_A0(%a6),%d0         # Get current a0
1130         mov.l           %d0,EXC_SAVVAL(%a6)      1130         mov.l           %d0,EXC_SAVVAL(%a6)     # save in case of access error
1131         sub.l           %a0,%d0                  1131         sub.l           %a0,%d0                 # Decrement
1132         mov.l           %d0,EXC_A0(%a6)          1132         mov.l           %d0,EXC_A0(%a6)         # Save decr value
1133         mov.l           %d0,%a0                  1133         mov.l           %d0,%a0
1134                                                  1134 
1135         mov.b           &0x0,EXC_SAVREG(%a6)     1135         mov.b           &0x0,EXC_SAVREG(%a6)    # save regno, too
1136         mov.b           &restore_flg,SPCOND_F    1136         mov.b           &restore_flg,SPCOND_FLG(%a6) # set flag
1137         rts                                      1137         rts
1138                                                  1138 
1139 addr_ind_m_a1:                                   1139 addr_ind_m_a1:
1140         mov.l           EXC_A1(%a6),%d0          1140         mov.l           EXC_A1(%a6),%d0         # Get current a1
1141         mov.l           %d0,EXC_SAVVAL(%a6)      1141         mov.l           %d0,EXC_SAVVAL(%a6)     # save in case of access error
1142         sub.l           %a0,%d0                  1142         sub.l           %a0,%d0                 # Decrement
1143         mov.l           %d0,EXC_A1(%a6)          1143         mov.l           %d0,EXC_A1(%a6)         # Save decr value
1144         mov.l           %d0,%a0                  1144         mov.l           %d0,%a0
1145                                                  1145 
1146         mov.b           &0x1,EXC_SAVREG(%a6)     1146         mov.b           &0x1,EXC_SAVREG(%a6)    # save regno, too
1147         mov.b           &restore_flg,SPCOND_F    1147         mov.b           &restore_flg,SPCOND_FLG(%a6) # set flag
1148         rts                                      1148         rts
1149                                                  1149 
1150 addr_ind_m_a2:                                   1150 addr_ind_m_a2:
1151         mov.l           EXC_A2(%a6),%d0          1151         mov.l           EXC_A2(%a6),%d0         # Get current a2
1152         mov.l           %d0,EXC_SAVVAL(%a6)      1152         mov.l           %d0,EXC_SAVVAL(%a6)     # save in case of access error
1153         sub.l           %a0,%d0                  1153         sub.l           %a0,%d0                 # Decrement
1154         mov.l           %d0,EXC_A2(%a6)          1154         mov.l           %d0,EXC_A2(%a6)         # Save decr value
1155         mov.l           %d0,%a0                  1155         mov.l           %d0,%a0
1156                                                  1156 
1157         mov.b           &0x2,EXC_SAVREG(%a6)     1157         mov.b           &0x2,EXC_SAVREG(%a6)    # save regno, too
1158         mov.b           &restore_flg,SPCOND_F    1158         mov.b           &restore_flg,SPCOND_FLG(%a6) # set flag
1159         rts                                      1159         rts
1160                                                  1160 
1161 addr_ind_m_a3:                                   1161 addr_ind_m_a3:
1162         mov.l           EXC_A3(%a6),%d0          1162         mov.l           EXC_A3(%a6),%d0         # Get current a3
1163         mov.l           %d0,EXC_SAVVAL(%a6)      1163         mov.l           %d0,EXC_SAVVAL(%a6)     # save in case of access error
1164         sub.l           %a0,%d0                  1164         sub.l           %a0,%d0                 # Decrement
1165         mov.l           %d0,EXC_A3(%a6)          1165         mov.l           %d0,EXC_A3(%a6)         # Save decr value
1166         mov.l           %d0,%a0                  1166         mov.l           %d0,%a0
1167                                                  1167 
1168         mov.b           &0x3,EXC_SAVREG(%a6)     1168         mov.b           &0x3,EXC_SAVREG(%a6)    # save regno, too
1169         mov.b           &restore_flg,SPCOND_F    1169         mov.b           &restore_flg,SPCOND_FLG(%a6) # set flag
1170         rts                                      1170         rts
1171                                                  1171 
1172 addr_ind_m_a4:                                   1172 addr_ind_m_a4:
1173         mov.l           EXC_A4(%a6),%d0          1173         mov.l           EXC_A4(%a6),%d0         # Get current a4
1174         mov.l           %d0,EXC_SAVVAL(%a6)      1174         mov.l           %d0,EXC_SAVVAL(%a6)     # save in case of access error
1175         sub.l           %a0,%d0                  1175         sub.l           %a0,%d0                 # Decrement
1176         mov.l           %d0,EXC_A4(%a6)          1176         mov.l           %d0,EXC_A4(%a6)         # Save decr value
1177         mov.l           %d0,%a0                  1177         mov.l           %d0,%a0
1178                                                  1178 
1179         mov.b           &0x4,EXC_SAVREG(%a6)     1179         mov.b           &0x4,EXC_SAVREG(%a6)    # save regno, too
1180         mov.b           &restore_flg,SPCOND_F    1180         mov.b           &restore_flg,SPCOND_FLG(%a6) # set flag
1181         rts                                      1181         rts
1182                                                  1182 
1183 addr_ind_m_a5:                                   1183 addr_ind_m_a5:
1184         mov.l           EXC_A5(%a6),%d0          1184         mov.l           EXC_A5(%a6),%d0         # Get current a5
1185         mov.l           %d0,EXC_SAVVAL(%a6)      1185         mov.l           %d0,EXC_SAVVAL(%a6)     # save in case of access error
1186         sub.l           %a0,%d0                  1186         sub.l           %a0,%d0                 # Decrement
1187         mov.l           %d0,EXC_A5(%a6)          1187         mov.l           %d0,EXC_A5(%a6)         # Save decr value
1188         mov.l           %d0,%a0                  1188         mov.l           %d0,%a0
1189                                                  1189 
1190         mov.b           &0x5,EXC_SAVREG(%a6)     1190         mov.b           &0x5,EXC_SAVREG(%a6)    # save regno, too
1191         mov.b           &restore_flg,SPCOND_F    1191         mov.b           &restore_flg,SPCOND_FLG(%a6) # set flag
1192         rts                                      1192         rts
1193                                                  1193 
1194 addr_ind_m_a6:                                   1194 addr_ind_m_a6:
1195         mov.l           EXC_A6(%a6),%d0          1195         mov.l           EXC_A6(%a6),%d0         # Get current a6
1196         mov.l           %d0,EXC_SAVVAL(%a6)      1196         mov.l           %d0,EXC_SAVVAL(%a6)     # save in case of access error
1197         sub.l           %a0,%d0                  1197         sub.l           %a0,%d0                 # Decrement
1198         mov.l           %d0,EXC_A6(%a6)          1198         mov.l           %d0,EXC_A6(%a6)         # Save decr value
1199         mov.l           %d0,%a0                  1199         mov.l           %d0,%a0
1200                                                  1200 
1201         mov.b           &0x6,EXC_SAVREG(%a6)     1201         mov.b           &0x6,EXC_SAVREG(%a6)    # save regno, too
1202         mov.b           &restore_flg,SPCOND_F    1202         mov.b           &restore_flg,SPCOND_FLG(%a6) # set flag
1203         rts                                      1203         rts
1204                                                  1204 
1205 addr_ind_m_a7:                                   1205 addr_ind_m_a7:
1206         mov.b           &mda7_flg,SPCOND_FLG(    1206         mov.b           &mda7_flg,SPCOND_FLG(%a6) # set "special case" flag
1207                                                  1207 
1208         mov.l           EXC_A7(%a6),%d0          1208         mov.l           EXC_A7(%a6),%d0         # Get current a7
1209         sub.l           %a0,%d0                  1209         sub.l           %a0,%d0                 # Decrement
1210         mov.l           %d0,EXC_A7(%a6)          1210         mov.l           %d0,EXC_A7(%a6)         # Save decr value
1211         mov.l           %d0,%a0                  1211         mov.l           %d0,%a0
1212         rts                                      1212         rts
1213                                                  1213 
1214 #############################################    1214 ########################################################
1215 # Address register indirect w/ displacement:     1215 # Address register indirect w/ displacement: (d16, An) #
1216 #############################################    1216 ########################################################
1217 addr_ind_disp_a0:                                1217 addr_ind_disp_a0:
1218         mov.l           EXC_EXTWPTR(%a6),%a0     1218         mov.l           EXC_EXTWPTR(%a6),%a0    # fetch instruction addr
1219         addq.l          &0x2,EXC_EXTWPTR(%a6)    1219         addq.l          &0x2,EXC_EXTWPTR(%a6)   # incr instruction ptr
1220         bsr.l           _imem_read_word          1220         bsr.l           _imem_read_word
1221                                                  1221 
1222         tst.l           %d1                      1222         tst.l           %d1                     # ifetch error?
1223         bne.l           isp_iacc                 1223         bne.l           isp_iacc                # yes
1224                                                  1224 
1225         mov.w           %d0,%a0                  1225         mov.w           %d0,%a0                 # sign extend displacement
1226         add.l           EXC_A0(%a6),%a0          1226         add.l           EXC_A0(%a6),%a0         # a0 + d16
1227         rts                                      1227         rts
1228                                                  1228 
1229 addr_ind_disp_a1:                                1229 addr_ind_disp_a1:
1230         mov.l           EXC_EXTWPTR(%a6),%a0     1230         mov.l           EXC_EXTWPTR(%a6),%a0    # fetch instruction addr
1231         addq.l          &0x2,EXC_EXTWPTR(%a6)    1231         addq.l          &0x2,EXC_EXTWPTR(%a6)   # incr instruction ptr
1232         bsr.l           _imem_read_word          1232         bsr.l           _imem_read_word
1233                                                  1233 
1234         tst.l           %d1                      1234         tst.l           %d1                     # ifetch error?
1235         bne.l           isp_iacc                 1235         bne.l           isp_iacc                # yes
1236                                                  1236 
1237         mov.w           %d0,%a0                  1237         mov.w           %d0,%a0                 # sign extend displacement
1238         add.l           EXC_A1(%a6),%a0          1238         add.l           EXC_A1(%a6),%a0         # a1 + d16
1239         rts                                      1239         rts
1240                                                  1240 
1241 addr_ind_disp_a2:                                1241 addr_ind_disp_a2:
1242         mov.l           EXC_EXTWPTR(%a6),%a0     1242         mov.l           EXC_EXTWPTR(%a6),%a0    # fetch instruction addr
1243         addq.l          &0x2,EXC_EXTWPTR(%a6)    1243         addq.l          &0x2,EXC_EXTWPTR(%a6)   # incr instruction ptr
1244         bsr.l           _imem_read_word          1244         bsr.l           _imem_read_word
1245                                                  1245 
1246         tst.l           %d1                      1246         tst.l           %d1                     # ifetch error?
1247         bne.l           isp_iacc                 1247         bne.l           isp_iacc                # yes
1248                                                  1248 
1249         mov.w           %d0,%a0                  1249         mov.w           %d0,%a0                 # sign extend displacement
1250         add.l           EXC_A2(%a6),%a0          1250         add.l           EXC_A2(%a6),%a0         # a2 + d16
1251         rts                                      1251         rts
1252                                                  1252 
1253 addr_ind_disp_a3:                                1253 addr_ind_disp_a3:
1254         mov.l           EXC_EXTWPTR(%a6),%a0     1254         mov.l           EXC_EXTWPTR(%a6),%a0    # fetch instruction addr
1255         addq.l          &0x2,EXC_EXTWPTR(%a6)    1255         addq.l          &0x2,EXC_EXTWPTR(%a6)   # incr instruction ptr
1256         bsr.l           _imem_read_word          1256         bsr.l           _imem_read_word
1257                                                  1257 
1258         tst.l           %d1                      1258         tst.l           %d1                     # ifetch error?
1259         bne.l           isp_iacc                 1259         bne.l           isp_iacc                # yes
1260                                                  1260 
1261         mov.w           %d0,%a0                  1261         mov.w           %d0,%a0                 # sign extend displacement
1262         add.l           EXC_A3(%a6),%a0          1262         add.l           EXC_A3(%a6),%a0         # a3 + d16
1263         rts                                      1263         rts
1264                                                  1264 
1265 addr_ind_disp_a4:                                1265 addr_ind_disp_a4:
1266         mov.l           EXC_EXTWPTR(%a6),%a0     1266         mov.l           EXC_EXTWPTR(%a6),%a0    # fetch instruction addr
1267         addq.l          &0x2,EXC_EXTWPTR(%a6)    1267         addq.l          &0x2,EXC_EXTWPTR(%a6)   # incr instruction ptr
1268         bsr.l           _imem_read_word          1268         bsr.l           _imem_read_word
1269                                                  1269 
1270         tst.l           %d1                      1270         tst.l           %d1                     # ifetch error?
1271         bne.l           isp_iacc                 1271         bne.l           isp_iacc                # yes
1272                                                  1272 
1273         mov.w           %d0,%a0                  1273         mov.w           %d0,%a0                 # sign extend displacement
1274         add.l           EXC_A4(%a6),%a0          1274         add.l           EXC_A4(%a6),%a0         # a4 + d16
1275         rts                                      1275         rts
1276                                                  1276 
1277 addr_ind_disp_a5:                                1277 addr_ind_disp_a5:
1278         mov.l           EXC_EXTWPTR(%a6),%a0     1278         mov.l           EXC_EXTWPTR(%a6),%a0    # fetch instruction addr
1279         addq.l          &0x2,EXC_EXTWPTR(%a6)    1279         addq.l          &0x2,EXC_EXTWPTR(%a6)   # incr instruction ptr
1280         bsr.l           _imem_read_word          1280         bsr.l           _imem_read_word
1281                                                  1281 
1282         tst.l           %d1                      1282         tst.l           %d1                     # ifetch error?
1283         bne.l           isp_iacc                 1283         bne.l           isp_iacc                # yes
1284                                                  1284 
1285         mov.w           %d0,%a0                  1285         mov.w           %d0,%a0                 # sign extend displacement
1286         add.l           EXC_A5(%a6),%a0          1286         add.l           EXC_A5(%a6),%a0         # a5 + d16
1287         rts                                      1287         rts
1288                                                  1288 
1289 addr_ind_disp_a6:                                1289 addr_ind_disp_a6:
1290         mov.l           EXC_EXTWPTR(%a6),%a0     1290         mov.l           EXC_EXTWPTR(%a6),%a0    # fetch instruction addr
1291         addq.l          &0x2,EXC_EXTWPTR(%a6)    1291         addq.l          &0x2,EXC_EXTWPTR(%a6)   # incr instruction ptr
1292         bsr.l           _imem_read_word          1292         bsr.l           _imem_read_word
1293                                                  1293 
1294         tst.l           %d1                      1294         tst.l           %d1                     # ifetch error?
1295         bne.l           isp_iacc                 1295         bne.l           isp_iacc                # yes
1296                                                  1296 
1297         mov.w           %d0,%a0                  1297         mov.w           %d0,%a0                 # sign extend displacement
1298         add.l           EXC_A6(%a6),%a0          1298         add.l           EXC_A6(%a6),%a0         # a6 + d16
1299         rts                                      1299         rts
1300                                                  1300 
1301 addr_ind_disp_a7:                                1301 addr_ind_disp_a7:
1302         mov.l           EXC_EXTWPTR(%a6),%a0     1302         mov.l           EXC_EXTWPTR(%a6),%a0    # fetch instruction addr
1303         addq.l          &0x2,EXC_EXTWPTR(%a6)    1303         addq.l          &0x2,EXC_EXTWPTR(%a6)   # incr instruction ptr
1304         bsr.l           _imem_read_word          1304         bsr.l           _imem_read_word
1305                                                  1305 
1306         tst.l           %d1                      1306         tst.l           %d1                     # ifetch error?
1307         bne.l           isp_iacc                 1307         bne.l           isp_iacc                # yes
1308                                                  1308 
1309         mov.w           %d0,%a0                  1309         mov.w           %d0,%a0                 # sign extend displacement
1310         add.l           EXC_A7(%a6),%a0          1310         add.l           EXC_A7(%a6),%a0         # a7 + d16
1311         rts                                      1311         rts
1312                                                  1312 
1313 #############################################    1313 ########################################################################
1314 # Address register indirect w/ index(8-bit di    1314 # Address register indirect w/ index(8-bit displacement): (dn, An, Xn) #
1315 #    "       "         "    w/   "  (base dis    1315 #    "       "         "    w/   "  (base displacement): (bd, An, Xn)  #
1316 # Memory indirect postindexed: ([bd, An], Xn,    1316 # Memory indirect postindexed: ([bd, An], Xn, od)                      #
1317 # Memory indirect preindexed: ([bd, An, Xn],     1317 # Memory indirect preindexed: ([bd, An, Xn], od)                       #
1318 #############################################    1318 ########################################################################
1319 _addr_ind_ext:                                   1319 _addr_ind_ext:
1320         mov.l           %d1,-(%sp)               1320         mov.l           %d1,-(%sp)
1321                                                  1321 
1322         mov.l           EXC_EXTWPTR(%a6),%a0     1322         mov.l           EXC_EXTWPTR(%a6),%a0    # fetch instruction addr
1323         addq.l          &0x2,EXC_EXTWPTR(%a6)    1323         addq.l          &0x2,EXC_EXTWPTR(%a6)   # incr instruction ptr
1324         bsr.l           _imem_read_word          1324         bsr.l           _imem_read_word         # fetch extword in d0
1325                                                  1325 
1326         tst.l           %d1                      1326         tst.l           %d1                     # ifetch error?
1327         bne.l           isp_iacc                 1327         bne.l           isp_iacc                # yes
1328                                                  1328 
1329         mov.l           (%sp)+,%d1               1329         mov.l           (%sp)+,%d1
1330                                                  1330 
1331         mov.l           (EXC_AREGS,%a6,%d1.w*    1331         mov.l           (EXC_AREGS,%a6,%d1.w*4),%a0 # put base in a0
1332                                                  1332 
1333         btst            &0x8,%d0                 1333         btst            &0x8,%d0
1334         beq.b           addr_ind_index_8bit      1334         beq.b           addr_ind_index_8bit     # for ext word or not?
1335                                                  1335 
1336         movm.l          &0x3c00,-(%sp)           1336         movm.l          &0x3c00,-(%sp)          # save d2-d5
1337                                                  1337 
1338         mov.l           %d0,%d5                  1338         mov.l           %d0,%d5                 # put extword in d5
1339         mov.l           %a0,%d3                  1339         mov.l           %a0,%d3                 # put base in d3
1340                                                  1340 
1341         bra.l           calc_mem_ind             1341         bra.l           calc_mem_ind            # calc memory indirect
1342                                                  1342 
1343 addr_ind_index_8bit:                             1343 addr_ind_index_8bit:
1344         mov.l           %d2,-(%sp)               1344         mov.l           %d2,-(%sp)              # save old d2
1345                                                  1345 
1346         mov.l           %d0,%d1                  1346         mov.l           %d0,%d1
1347         rol.w           &0x4,%d1                 1347         rol.w           &0x4,%d1
1348         andi.w          &0xf,%d1                 1348         andi.w          &0xf,%d1                # extract index regno
1349                                                  1349 
1350         mov.l           (EXC_DREGS,%a6,%d1.w*    1350         mov.l           (EXC_DREGS,%a6,%d1.w*4),%d1 # fetch index reg value
1351                                                  1351 
1352         btst            &0xb,%d0                 1352         btst            &0xb,%d0                # is it word or long?
1353         bne.b           aii8_long                1353         bne.b           aii8_long
1354         ext.l           %d1                      1354         ext.l           %d1                     # sign extend word index
1355 aii8_long:                                       1355 aii8_long:
1356         mov.l           %d0,%d2                  1356         mov.l           %d0,%d2
1357         rol.w           &0x7,%d2                 1357         rol.w           &0x7,%d2
1358         andi.l          &0x3,%d2                 1358         andi.l          &0x3,%d2                # extract scale value
1359                                                  1359 
1360         lsl.l           %d2,%d1                  1360         lsl.l           %d2,%d1                 # shift index by scale
1361                                                  1361 
1362         extb.l          %d0                      1362         extb.l          %d0                     # sign extend displacement
1363         add.l           %d1,%d0                  1363         add.l           %d1,%d0                 # index + disp
1364         add.l           %d0,%a0                  1364         add.l           %d0,%a0                 # An + (index + disp)
1365                                                  1365 
1366         mov.l           (%sp)+,%d2               1366         mov.l           (%sp)+,%d2              # restore old d2
1367         rts                                      1367         rts
1368                                                  1368 
1369 ######################                           1369 ######################
1370 # Immediate: #<data> #                           1370 # Immediate: #<data> #
1371 #############################################    1371 #########################################################################
1372 # word, long: <ea> of the data is the current    1372 # word, long: <ea> of the data is the current extension word            #
1373 #       pointer value. new extension word poi    1373 #       pointer value. new extension word pointer is simply the old     #
1374 #       plus the number of bytes in the data     1374 #       plus the number of bytes in the data type(2 or 4).              #
1375 #############################################    1375 #########################################################################
1376 immediate:                                       1376 immediate:
1377         mov.b           &immed_flg,SPCOND_FLG    1377         mov.b           &immed_flg,SPCOND_FLG(%a6) # set immediate flag
1378                                                  1378 
1379         mov.l           EXC_EXTWPTR(%a6),%a0     1379         mov.l           EXC_EXTWPTR(%a6),%a0    # fetch extension word ptr
1380         rts                                      1380         rts
1381                                                  1381 
1382 ###########################                      1382 ###########################
1383 # Absolute short: (XXX).W #                      1383 # Absolute short: (XXX).W #
1384 ###########################                      1384 ###########################
1385 abs_short:                                       1385 abs_short:
1386         mov.l           EXC_EXTWPTR(%a6),%a0     1386         mov.l           EXC_EXTWPTR(%a6),%a0    # fetch instruction addr
1387         addq.l          &0x2,EXC_EXTWPTR(%a6)    1387         addq.l          &0x2,EXC_EXTWPTR(%a6)   # incr instruction ptr
1388         bsr.l           _imem_read_word          1388         bsr.l           _imem_read_word         # fetch short address
1389                                                  1389 
1390         tst.l           %d1                      1390         tst.l           %d1                     # ifetch error?
1391         bne.l           isp_iacc                 1391         bne.l           isp_iacc                # yes
1392                                                  1392 
1393         mov.w           %d0,%a0                  1393         mov.w           %d0,%a0                 # return <ea> in a0
1394         rts                                      1394         rts
1395                                                  1395 
1396 ##########################                       1396 ##########################
1397 # Absolute long: (XXX).L #                       1397 # Absolute long: (XXX).L #
1398 ##########################                       1398 ##########################
1399 abs_long:                                        1399 abs_long:
1400         mov.l           EXC_EXTWPTR(%a6),%a0     1400         mov.l           EXC_EXTWPTR(%a6),%a0    # fetch instruction addr
1401         addq.l          &0x4,EXC_EXTWPTR(%a6)    1401         addq.l          &0x4,EXC_EXTWPTR(%a6)   # incr instruction ptr
1402         bsr.l           _imem_read_long          1402         bsr.l           _imem_read_long         # fetch long address
1403                                                  1403 
1404         tst.l           %d1                      1404         tst.l           %d1                     # ifetch error?
1405         bne.l           isp_iacc                 1405         bne.l           isp_iacc                # yes
1406                                                  1406 
1407         mov.l           %d0,%a0                  1407         mov.l           %d0,%a0                 # return <ea> in a0
1408         rts                                      1408         rts
1409                                                  1409 
1410 #############################################    1410 #######################################################
1411 # Program counter indirect w/ displacement: (    1411 # Program counter indirect w/ displacement: (d16, PC) #
1412 #############################################    1412 #######################################################
1413 pc_ind:                                          1413 pc_ind:
1414         mov.l           EXC_EXTWPTR(%a6),%a0     1414         mov.l           EXC_EXTWPTR(%a6),%a0    # fetch instruction addr
1415         addq.l          &0x2,EXC_EXTWPTR(%a6)    1415         addq.l          &0x2,EXC_EXTWPTR(%a6)   # incr instruction ptr
1416         bsr.l           _imem_read_word          1416         bsr.l           _imem_read_word         # fetch word displacement
1417                                                  1417 
1418         tst.l           %d1                      1418         tst.l           %d1                     # ifetch error?
1419         bne.l           isp_iacc                 1419         bne.l           isp_iacc                # yes
1420                                                  1420 
1421         mov.w           %d0,%a0                  1421         mov.w           %d0,%a0                 # sign extend displacement
1422                                                  1422 
1423         add.l           EXC_EXTWPTR(%a6),%a0     1423         add.l           EXC_EXTWPTR(%a6),%a0    # pc + d16
1424                                                  1424 
1425 # _imem_read_word() increased the extwptr by     1425 # _imem_read_word() increased the extwptr by 2. need to adjust here.
1426         subq.l          &0x2,%a0                 1426         subq.l          &0x2,%a0                # adjust <ea>
1427                                                  1427 
1428         rts                                      1428         rts
1429                                                  1429 
1430 #############################################    1430 ##########################################################
1431 # PC indirect w/ index(8-bit displacement): (    1431 # PC indirect w/ index(8-bit displacement): (d8, PC, An) #
1432 # "     "     w/   "  (base displacement): (b    1432 # "     "     w/   "  (base displacement): (bd, PC, An)  #
1433 # PC memory indirect postindexed: ([bd, PC],     1433 # PC memory indirect postindexed: ([bd, PC], Xn, od)     #
1434 # PC memory indirect preindexed: ([bd, PC, Xn    1434 # PC memory indirect preindexed: ([bd, PC, Xn], od)      #
1435 #############################################    1435 ##########################################################
1436 pc_ind_ext:                                      1436 pc_ind_ext:
1437         mov.l           EXC_EXTWPTR(%a6),%a0     1437         mov.l           EXC_EXTWPTR(%a6),%a0    # fetch instruction addr
1438         addq.l          &0x2,EXC_EXTWPTR(%a6)    1438         addq.l          &0x2,EXC_EXTWPTR(%a6)   # incr instruction ptr
1439         bsr.l           _imem_read_word          1439         bsr.l           _imem_read_word         # fetch ext word
1440                                                  1440 
1441         tst.l           %d1                      1441         tst.l           %d1                     # ifetch error?
1442         bne.l           isp_iacc                 1442         bne.l           isp_iacc                # yes
1443                                                  1443 
1444         mov.l           EXC_EXTWPTR(%a6),%a0     1444         mov.l           EXC_EXTWPTR(%a6),%a0    # put base in a0
1445         subq.l          &0x2,%a0                 1445         subq.l          &0x2,%a0                # adjust base
1446                                                  1446 
1447         btst            &0x8,%d0                 1447         btst            &0x8,%d0                # is disp only 8 bits?
1448         beq.b           pc_ind_index_8bit        1448         beq.b           pc_ind_index_8bit       # yes
1449                                                  1449 
1450 # the indexed addressing mode uses a base dis    1450 # the indexed addressing mode uses a base displacement of size
1451 # word or long                                   1451 # word or long
1452         movm.l          &0x3c00,-(%sp)           1452         movm.l          &0x3c00,-(%sp)          # save d2-d5
1453                                                  1453 
1454         mov.l           %d0,%d5                  1454         mov.l           %d0,%d5                 # put extword in d5
1455         mov.l           %a0,%d3                  1455         mov.l           %a0,%d3                 # put base in d3
1456                                                  1456 
1457         bra.l           calc_mem_ind             1457         bra.l           calc_mem_ind            # calc memory indirect
1458                                                  1458 
1459 pc_ind_index_8bit:                               1459 pc_ind_index_8bit:
1460         mov.l           %d2,-(%sp)               1460         mov.l           %d2,-(%sp)              # create a temp register
1461                                                  1461 
1462         mov.l           %d0,%d1                  1462         mov.l           %d0,%d1                 # make extword copy
1463         rol.w           &0x4,%d1                 1463         rol.w           &0x4,%d1                # rotate reg num into place
1464         andi.w          &0xf,%d1                 1464         andi.w          &0xf,%d1                # extract register number
1465                                                  1465 
1466         mov.l           (EXC_DREGS,%a6,%d1.w*    1466         mov.l           (EXC_DREGS,%a6,%d1.w*4),%d1 # fetch index reg value
1467                                                  1467 
1468         btst            &0xb,%d0                 1468         btst            &0xb,%d0                # is index word or long?
1469         bne.b           pii8_long                1469         bne.b           pii8_long               # long
1470         ext.l           %d1                      1470         ext.l           %d1                     # sign extend word index
1471 pii8_long:                                       1471 pii8_long:
1472         mov.l           %d0,%d2                  1472         mov.l           %d0,%d2                 # make extword copy
1473         rol.w           &0x7,%d2                 1473         rol.w           &0x7,%d2                # rotate scale value into place
1474         andi.l          &0x3,%d2                 1474         andi.l          &0x3,%d2                # extract scale value
1475                                                  1475 
1476         lsl.l           %d2,%d1                  1476         lsl.l           %d2,%d1                 # shift index by scale
1477                                                  1477 
1478         extb.l          %d0                      1478         extb.l          %d0                     # sign extend displacement
1479         add.l           %d1,%d0                  1479         add.l           %d1,%d0                 # index + disp
1480         add.l           %d0,%a0                  1480         add.l           %d0,%a0                 # An + (index + disp)
1481                                                  1481 
1482         mov.l           (%sp)+,%d2               1482         mov.l           (%sp)+,%d2              # restore temp register
1483                                                  1483 
1484         rts                                      1484         rts
1485                                                  1485 
1486 # a5 = exc_extwptr      (global to uaeh)         1486 # a5 = exc_extwptr      (global to uaeh)
1487 # a4 = exc_opword       (global to uaeh)         1487 # a4 = exc_opword       (global to uaeh)
1488 # a3 = exc_dregs        (global to uaeh)         1488 # a3 = exc_dregs        (global to uaeh)
1489                                                  1489 
1490 # d2 = index            (internal "     "        1490 # d2 = index            (internal "     "    )
1491 # d3 = base             (internal "     "        1491 # d3 = base             (internal "     "    )
1492 # d4 = od               (internal "     "        1492 # d4 = od               (internal "     "    )
1493 # d5 = extword          (internal "     "        1493 # d5 = extword          (internal "     "    )
1494 calc_mem_ind:                                    1494 calc_mem_ind:
1495         btst            &0x6,%d5                 1495         btst            &0x6,%d5                # is the index suppressed?
1496         beq.b           calc_index               1496         beq.b           calc_index
1497         clr.l           %d2                      1497         clr.l           %d2                     # yes, so index = 0
1498         bra.b           base_supp_ck             1498         bra.b           base_supp_ck
1499 calc_index:                                      1499 calc_index:
1500         bfextu          %d5{&16:&4},%d2          1500         bfextu          %d5{&16:&4},%d2
1501         mov.l           (EXC_DREGS,%a6,%d2.w*    1501         mov.l           (EXC_DREGS,%a6,%d2.w*4),%d2
1502         btst            &0xb,%d5                 1502         btst            &0xb,%d5                # is index word or long?
1503         bne.b           no_ext                   1503         bne.b           no_ext
1504         ext.l           %d2                      1504         ext.l           %d2
1505 no_ext:                                          1505 no_ext:
1506         bfextu          %d5{&21:&2},%d0          1506         bfextu          %d5{&21:&2},%d0
1507         lsl.l           %d0,%d2                  1507         lsl.l           %d0,%d2
1508 base_supp_ck:                                    1508 base_supp_ck:
1509         btst            &0x7,%d5                 1509         btst            &0x7,%d5                # is the bd suppressed?
1510         beq.b           no_base_sup              1510         beq.b           no_base_sup
1511         clr.l           %d3                      1511         clr.l           %d3
1512 no_base_sup:                                     1512 no_base_sup:
1513         bfextu          %d5{&26:&2},%d0 # get    1513         bfextu          %d5{&26:&2},%d0 # get bd size
1514 #       beq.l           _error                   1514 #       beq.l           _error                  # if (size == 0) it's reserved
1515         cmpi.b          %d0,&2                   1515         cmpi.b          %d0,&2
1516         blt.b           no_bd                    1516         blt.b           no_bd
1517         beq.b           get_word_bd              1517         beq.b           get_word_bd
1518                                                  1518 
1519         mov.l           EXC_EXTWPTR(%a6),%a0     1519         mov.l           EXC_EXTWPTR(%a6),%a0    # fetch instruction addr
1520         addq.l          &0x4,EXC_EXTWPTR(%a6)    1520         addq.l          &0x4,EXC_EXTWPTR(%a6)   # incr instruction ptr
1521         bsr.l           _imem_read_long          1521         bsr.l           _imem_read_long
1522                                                  1522 
1523         tst.l           %d1                      1523         tst.l           %d1                     # ifetch error?
1524         bne.l           isp_iacc                 1524         bne.l           isp_iacc                # yes
1525                                                  1525 
1526         bra.b           chk_ind                  1526         bra.b           chk_ind
1527 get_word_bd:                                     1527 get_word_bd:
1528         mov.l           EXC_EXTWPTR(%a6),%a0     1528         mov.l           EXC_EXTWPTR(%a6),%a0    # fetch instruction addr
1529         addq.l          &0x2,EXC_EXTWPTR(%a6)    1529         addq.l          &0x2,EXC_EXTWPTR(%a6)   # incr instruction ptr
1530         bsr.l           _imem_read_word          1530         bsr.l           _imem_read_word
1531                                                  1531 
1532         tst.l           %d1                      1532         tst.l           %d1                     # ifetch error?
1533         bne.l           isp_iacc                 1533         bne.l           isp_iacc                # yes
1534                                                  1534 
1535         ext.l           %d0                      1535         ext.l           %d0                     # sign extend bd
1536                                                  1536 
1537 chk_ind:                                         1537 chk_ind:
1538         add.l           %d0,%d3                  1538         add.l           %d0,%d3                 # base += bd
1539 no_bd:                                           1539 no_bd:
1540         bfextu          %d5{&30:&2},%d0          1540         bfextu          %d5{&30:&2},%d0         # is od suppressed?
1541         beq.w           aii_bd                   1541         beq.w           aii_bd
1542         cmpi.b          %d0,&0x2                 1542         cmpi.b          %d0,&0x2
1543         blt.b           null_od                  1543         blt.b           null_od
1544         beq.b           word_od                  1544         beq.b           word_od
1545                                                  1545 
1546         mov.l           EXC_EXTWPTR(%a6),%a0     1546         mov.l           EXC_EXTWPTR(%a6),%a0    # fetch instruction addr
1547         addq.l          &0x4,EXC_EXTWPTR(%a6)    1547         addq.l          &0x4,EXC_EXTWPTR(%a6)   # incr instruction ptr
1548         bsr.l           _imem_read_long          1548         bsr.l           _imem_read_long
1549                                                  1549 
1550         tst.l           %d1                      1550         tst.l           %d1                     # ifetch error?
1551         bne.l           isp_iacc                 1551         bne.l           isp_iacc                # yes
1552                                                  1552 
1553         bra.b           add_them                 1553         bra.b           add_them
1554                                                  1554 
1555 word_od:                                         1555 word_od:
1556         mov.l           EXC_EXTWPTR(%a6),%a0     1556         mov.l           EXC_EXTWPTR(%a6),%a0    # fetch instruction addr
1557         addq.l          &0x2,EXC_EXTWPTR(%a6)    1557         addq.l          &0x2,EXC_EXTWPTR(%a6)   # incr instruction ptr
1558         bsr.l           _imem_read_word          1558         bsr.l           _imem_read_word
1559                                                  1559 
1560         tst.l           %d1                      1560         tst.l           %d1                     # ifetch error?
1561         bne.l           isp_iacc                 1561         bne.l           isp_iacc                # yes
1562                                                  1562 
1563         ext.l           %d0                      1563         ext.l           %d0                     # sign extend od
1564         bra.b           add_them                 1564         bra.b           add_them
1565                                                  1565 
1566 null_od:                                         1566 null_od:
1567         clr.l           %d0                      1567         clr.l           %d0
1568 add_them:                                        1568 add_them:
1569         mov.l           %d0,%d4                  1569         mov.l           %d0,%d4
1570         btst            &0x2,%d5                 1570         btst            &0x2,%d5                # pre or post indexing?
1571         beq.b           pre_indexed              1571         beq.b           pre_indexed
1572                                                  1572 
1573         mov.l           %d3,%a0                  1573         mov.l           %d3,%a0
1574         bsr.l           _dmem_read_long          1574         bsr.l           _dmem_read_long
1575                                                  1575 
1576         tst.l           %d1                      1576         tst.l           %d1                     # dfetch error?
1577         bne.b           calc_ea_err              1577         bne.b           calc_ea_err             # yes
1578                                                  1578 
1579         add.l           %d2,%d0                  1579         add.l           %d2,%d0                 # <ea> += index
1580         add.l           %d4,%d0                  1580         add.l           %d4,%d0                 # <ea> += od
1581         bra.b           done_ea                  1581         bra.b           done_ea
1582                                                  1582 
1583 pre_indexed:                                     1583 pre_indexed:
1584         add.l           %d2,%d3                  1584         add.l           %d2,%d3                 # preindexing
1585         mov.l           %d3,%a0                  1585         mov.l           %d3,%a0
1586         bsr.l           _dmem_read_long          1586         bsr.l           _dmem_read_long
1587                                                  1587 
1588         tst.l           %d1                      1588         tst.l           %d1                     # ifetch error?
1589         bne.b           calc_ea_err              1589         bne.b           calc_ea_err             # yes
1590                                                  1590 
1591         add.l           %d4,%d0                  1591         add.l           %d4,%d0                 # ea += od
1592         bra.b           done_ea                  1592         bra.b           done_ea
1593                                                  1593 
1594 aii_bd:                                          1594 aii_bd:
1595         add.l           %d2,%d3                  1595         add.l           %d2,%d3                 # ea = (base + bd) + index
1596         mov.l           %d3,%d0                  1596         mov.l           %d3,%d0
1597 done_ea:                                         1597 done_ea:
1598         mov.l           %d0,%a0                  1598         mov.l           %d0,%a0
1599                                                  1599 
1600         movm.l          (%sp)+,&0x003c           1600         movm.l          (%sp)+,&0x003c          # restore d2-d5
1601         rts                                      1601         rts
1602                                                  1602 
1603 # if dmem_read_long() returns a fail message     1603 # if dmem_read_long() returns a fail message in d1, the package
1604 # must create an access error frame. here, we    1604 # must create an access error frame. here, we pass a skeleton fslw
1605 # and the failing address to the routine that    1605 # and the failing address to the routine that creates the new frame.
1606 # FSLW:                                          1606 # FSLW:
1607 #       read = true                              1607 #       read = true
1608 #       size = longword                          1608 #       size = longword
1609 #       TM = data                                1609 #       TM = data
1610 #       software emulation error = true          1610 #       software emulation error = true
1611 calc_ea_err:                                     1611 calc_ea_err:
1612         mov.l           %d3,%a0                  1612         mov.l           %d3,%a0                 # pass failing address
1613         mov.l           &0x01010001,%d0          1613         mov.l           &0x01010001,%d0         # pass fslw
1614         bra.l           isp_dacc                 1614         bra.l           isp_dacc
1615                                                  1615 
1616 #############################################    1616 #########################################################################
1617 # XDEF **************************************    1617 # XDEF **************************************************************** #
1618 #       _moveperipheral(): routine to emulate    1618 #       _moveperipheral(): routine to emulate movep instruction         #
1619 #                                                1619 #                                                                       #
1620 # XREF **************************************    1620 # XREF **************************************************************** #
1621 #       _dmem_read_byte() - read byte from me    1621 #       _dmem_read_byte() - read byte from memory                       #
1622 #       _dmem_write_byte() - write byte to me    1622 #       _dmem_write_byte() - write byte to memory                       #
1623 #       isp_dacc() - handle data access error    1623 #       isp_dacc() - handle data access error exception                 #
1624 #                                                1624 #                                                                       #
1625 # INPUT *************************************    1625 # INPUT *************************************************************** #
1626 #       none                                     1626 #       none                                                            #
1627 #                                                1627 #                                                                       #
1628 # OUTPUT ************************************    1628 # OUTPUT ************************************************************** #
1629 #       If exiting through isp_dacc...           1629 #       If exiting through isp_dacc...                                  #
1630 #               a0 = failing address             1630 #               a0 = failing address                                    #
1631 #               d0 = FSLW                        1631 #               d0 = FSLW                                               #
1632 #       else                                     1632 #       else                                                            #
1633 #               none                             1633 #               none                                                    #
1634 #                                                1634 #                                                                       #
1635 # ALGORITHM *********************************    1635 # ALGORITHM *********************************************************** #
1636 #       Decode the movep instruction words st    1636 #       Decode the movep instruction words stored at EXC_OPWORD and     #
1637 # either read or write the required bytes fro    1637 # either read or write the required bytes from/to memory. Use the       #
1638 # _dmem_{read,write}_byte() routines. If one     1638 # _dmem_{read,write}_byte() routines. If one of the memory routines     #
1639 # returns a failing value, we must pass the f    1639 # returns a failing value, we must pass the failing address and a FSLW  #
1640 # to the _isp_dacc() routine.                    1640 # to the _isp_dacc() routine.                                           #
1641 #       Since this instruction is used to acc    1641 #       Since this instruction is used to access peripherals, make sure #
1642 # to only access the required bytes.             1642 # to only access the required bytes.                                    #
1643 #                                                1643 #                                                                       #
1644 #############################################    1644 #########################################################################
1645                                                  1645 
1646 ###########################                      1646 ###########################
1647 # movep.(w,l)   Dx,(d,Ay) #                      1647 # movep.(w,l)   Dx,(d,Ay) #
1648 # movep.(w,l)   (d,Ay),Dx #                      1648 # movep.(w,l)   (d,Ay),Dx #
1649 ###########################                      1649 ###########################
1650         global          _moveperipheral          1650         global          _moveperipheral
1651 _moveperipheral:                                 1651 _moveperipheral:
1652         mov.w           EXC_OPWORD(%a6),%d1      1652         mov.w           EXC_OPWORD(%a6),%d1     # fetch the opcode word
1653                                                  1653 
1654         mov.b           %d1,%d0                  1654         mov.b           %d1,%d0
1655         and.w           &0x7,%d0                 1655         and.w           &0x7,%d0                # extract Ay from opcode word
1656                                                  1656 
1657         mov.l           (EXC_AREGS,%a6,%d0.w*    1657         mov.l           (EXC_AREGS,%a6,%d0.w*4),%a0 # fetch ay
1658                                                  1658 
1659         add.w           EXC_EXTWORD(%a6),%a0     1659         add.w           EXC_EXTWORD(%a6),%a0    # add: an + sgn_ext(disp)
1660                                                  1660 
1661         btst            &0x7,%d1                 1661         btst            &0x7,%d1                # (reg 2 mem) or (mem 2 reg)
1662         beq.w           mem2reg                  1662         beq.w           mem2reg
1663                                                  1663 
1664 # reg2mem: fetch dx, then write it to memory     1664 # reg2mem: fetch dx, then write it to memory
1665 reg2mem:                                         1665 reg2mem:
1666         mov.w           %d1,%d0                  1666         mov.w           %d1,%d0
1667         rol.w           &0x7,%d0                 1667         rol.w           &0x7,%d0
1668         and.w           &0x7,%d0                 1668         and.w           &0x7,%d0                # extract Dx from opcode word
1669                                                  1669 
1670         mov.l           (EXC_DREGS,%a6,%d0.w*    1670         mov.l           (EXC_DREGS,%a6,%d0.w*4), %d0 # fetch dx
1671                                                  1671 
1672         btst            &0x6,%d1                 1672         btst            &0x6,%d1                # word or long operation?
1673         beq.b           r2mwtrans                1673         beq.b           r2mwtrans
1674                                                  1674 
1675 # a0 = dst addr                                  1675 # a0 = dst addr
1676 # d0 = Dx                                        1676 # d0 = Dx
1677 r2mltrans:                                       1677 r2mltrans:
1678         mov.l           %d0,%d2                  1678         mov.l           %d0,%d2                 # store data
1679         mov.l           %a0,%a2                  1679         mov.l           %a0,%a2                 # store addr
1680         rol.l           &0x8,%d2                 1680         rol.l           &0x8,%d2
1681         mov.l           %d2,%d0                  1681         mov.l           %d2,%d0
1682                                                  1682 
1683         bsr.l           _dmem_write_byte         1683         bsr.l           _dmem_write_byte        # os  : write hi
1684                                                  1684 
1685         tst.l           %d1                      1685         tst.l           %d1                     # dfetch error?
1686         bne.w           movp_write_err           1686         bne.w           movp_write_err          # yes
1687                                                  1687 
1688         add.w           &0x2,%a2                 1688         add.w           &0x2,%a2                # incr addr
1689         mov.l           %a2,%a0                  1689         mov.l           %a2,%a0
1690         rol.l           &0x8,%d2                 1690         rol.l           &0x8,%d2
1691         mov.l           %d2,%d0                  1691         mov.l           %d2,%d0
1692                                                  1692 
1693         bsr.l           _dmem_write_byte         1693         bsr.l           _dmem_write_byte        # os  : write lo
1694                                                  1694 
1695         tst.l           %d1                      1695         tst.l           %d1                     # dfetch error?
1696         bne.w           movp_write_err           1696         bne.w           movp_write_err          # yes
1697                                                  1697 
1698         add.w           &0x2,%a2                 1698         add.w           &0x2,%a2                # incr addr
1699         mov.l           %a2,%a0                  1699         mov.l           %a2,%a0
1700         rol.l           &0x8,%d2                 1700         rol.l           &0x8,%d2
1701         mov.l           %d2,%d0                  1701         mov.l           %d2,%d0
1702                                                  1702 
1703         bsr.l           _dmem_write_byte         1703         bsr.l           _dmem_write_byte        # os  : write lo
1704                                                  1704 
1705         tst.l           %d1                      1705         tst.l           %d1                     # dfetch error?
1706         bne.w           movp_write_err           1706         bne.w           movp_write_err          # yes
1707                                                  1707 
1708         add.w           &0x2,%a2                 1708         add.w           &0x2,%a2                # incr addr
1709         mov.l           %a2,%a0                  1709         mov.l           %a2,%a0
1710         rol.l           &0x8,%d2                 1710         rol.l           &0x8,%d2
1711         mov.l           %d2,%d0                  1711         mov.l           %d2,%d0
1712                                                  1712 
1713         bsr.l           _dmem_write_byte         1713         bsr.l           _dmem_write_byte        # os  : write lo
1714                                                  1714 
1715         tst.l           %d1                      1715         tst.l           %d1                     # dfetch error?
1716         bne.w           movp_write_err           1716         bne.w           movp_write_err          # yes
1717                                                  1717 
1718         rts                                      1718         rts
1719                                                  1719 
1720 # a0 = dst addr                                  1720 # a0 = dst addr
1721 # d0 = Dx                                        1721 # d0 = Dx
1722 r2mwtrans:                                       1722 r2mwtrans:
1723         mov.l           %d0,%d2                  1723         mov.l           %d0,%d2                 # store data
1724         mov.l           %a0,%a2                  1724         mov.l           %a0,%a2                 # store addr
1725         lsr.w           &0x8,%d0                 1725         lsr.w           &0x8,%d0
1726                                                  1726 
1727         bsr.l           _dmem_write_byte         1727         bsr.l           _dmem_write_byte        # os  : write hi
1728                                                  1728 
1729         tst.l           %d1                      1729         tst.l           %d1                     # dfetch error?
1730         bne.w           movp_write_err           1730         bne.w           movp_write_err          # yes
1731                                                  1731 
1732         add.w           &0x2,%a2                 1732         add.w           &0x2,%a2
1733         mov.l           %a2,%a0                  1733         mov.l           %a2,%a0
1734         mov.l           %d2,%d0                  1734         mov.l           %d2,%d0
1735                                                  1735 
1736         bsr.l           _dmem_write_byte         1736         bsr.l           _dmem_write_byte        # os  : write lo
1737                                                  1737 
1738         tst.l           %d1                      1738         tst.l           %d1                     # dfetch error?
1739         bne.w           movp_write_err           1739         bne.w           movp_write_err          # yes
1740                                                  1740 
1741         rts                                      1741         rts
1742                                                  1742 
1743 # mem2reg: read bytes from memory.               1743 # mem2reg: read bytes from memory.
1744 # determines the dest register, and then writ    1744 # determines the dest register, and then writes the bytes into it.
1745 mem2reg:                                         1745 mem2reg:
1746         btst            &0x6,%d1                 1746         btst            &0x6,%d1                # word or long operation?
1747         beq.b           m2rwtrans                1747         beq.b           m2rwtrans
1748                                                  1748 
1749 # a0 = dst addr                                  1749 # a0 = dst addr
1750 m2rltrans:                                       1750 m2rltrans:
1751         mov.l           %a0,%a2                  1751         mov.l           %a0,%a2                 # store addr
1752                                                  1752 
1753         bsr.l           _dmem_read_byte          1753         bsr.l           _dmem_read_byte         # read first byte
1754                                                  1754 
1755         tst.l           %d1                      1755         tst.l           %d1                     # dfetch error?
1756         bne.w           movp_read_err            1756         bne.w           movp_read_err           # yes
1757                                                  1757 
1758         mov.l           %d0,%d2                  1758         mov.l           %d0,%d2
1759                                                  1759 
1760         add.w           &0x2,%a2                 1760         add.w           &0x2,%a2                # incr addr by 2 bytes
1761         mov.l           %a2,%a0                  1761         mov.l           %a2,%a0
1762                                                  1762 
1763         bsr.l           _dmem_read_byte          1763         bsr.l           _dmem_read_byte         # read second byte
1764                                                  1764 
1765         tst.l           %d1                      1765         tst.l           %d1                     # dfetch error?
1766         bne.w           movp_read_err            1766         bne.w           movp_read_err           # yes
1767                                                  1767 
1768         lsl.w           &0x8,%d2                 1768         lsl.w           &0x8,%d2
1769         mov.b           %d0,%d2                  1769         mov.b           %d0,%d2                 # append bytes
1770                                                  1770 
1771         add.w           &0x2,%a2                 1771         add.w           &0x2,%a2                # incr addr by 2 bytes
1772         mov.l           %a2,%a0                  1772         mov.l           %a2,%a0
1773                                                  1773 
1774         bsr.l           _dmem_read_byte          1774         bsr.l           _dmem_read_byte         # read second byte
1775                                                  1775 
1776         tst.l           %d1                      1776         tst.l           %d1                     # dfetch error?
1777         bne.w           movp_read_err            1777         bne.w           movp_read_err           # yes
1778                                                  1778 
1779         lsl.l           &0x8,%d2                 1779         lsl.l           &0x8,%d2
1780         mov.b           %d0,%d2                  1780         mov.b           %d0,%d2                 # append bytes
1781                                                  1781 
1782         add.w           &0x2,%a2                 1782         add.w           &0x2,%a2                # incr addr by 2 bytes
1783         mov.l           %a2,%a0                  1783         mov.l           %a2,%a0
1784                                                  1784 
1785         bsr.l           _dmem_read_byte          1785         bsr.l           _dmem_read_byte         # read second byte
1786                                                  1786 
1787         tst.l           %d1                      1787         tst.l           %d1                     # dfetch error?
1788         bne.w           movp_read_err            1788         bne.w           movp_read_err           # yes
1789                                                  1789 
1790         lsl.l           &0x8,%d2                 1790         lsl.l           &0x8,%d2
1791         mov.b           %d0,%d2                  1791         mov.b           %d0,%d2                 # append bytes
1792                                                  1792 
1793         mov.b           EXC_OPWORD(%a6),%d1      1793         mov.b           EXC_OPWORD(%a6),%d1
1794         lsr.b           &0x1,%d1                 1794         lsr.b           &0x1,%d1
1795         and.w           &0x7,%d1                 1795         and.w           &0x7,%d1                # extract Dx from opcode word
1796                                                  1796 
1797         mov.l           %d2,(EXC_DREGS,%a6,%d    1797         mov.l           %d2,(EXC_DREGS,%a6,%d1.w*4) # store dx
1798                                                  1798 
1799         rts                                      1799         rts
1800                                                  1800 
1801 # a0 = dst addr                                  1801 # a0 = dst addr
1802 m2rwtrans:                                       1802 m2rwtrans:
1803         mov.l           %a0,%a2                  1803         mov.l           %a0,%a2                 # store addr
1804                                                  1804 
1805         bsr.l           _dmem_read_byte          1805         bsr.l           _dmem_read_byte         # read first byte
1806                                                  1806 
1807         tst.l           %d1                      1807         tst.l           %d1                     # dfetch error?
1808         bne.w           movp_read_err            1808         bne.w           movp_read_err           # yes
1809                                                  1809 
1810         mov.l           %d0,%d2                  1810         mov.l           %d0,%d2
1811                                                  1811 
1812         add.w           &0x2,%a2                 1812         add.w           &0x2,%a2                # incr addr by 2 bytes
1813         mov.l           %a2,%a0                  1813         mov.l           %a2,%a0
1814                                                  1814 
1815         bsr.l           _dmem_read_byte          1815         bsr.l           _dmem_read_byte         # read second byte
1816                                                  1816 
1817         tst.l           %d1                      1817         tst.l           %d1                     # dfetch error?
1818         bne.w           movp_read_err            1818         bne.w           movp_read_err           # yes
1819                                                  1819 
1820         lsl.w           &0x8,%d2                 1820         lsl.w           &0x8,%d2
1821         mov.b           %d0,%d2                  1821         mov.b           %d0,%d2                 # append bytes
1822                                                  1822 
1823         mov.b           EXC_OPWORD(%a6),%d1      1823         mov.b           EXC_OPWORD(%a6),%d1
1824         lsr.b           &0x1,%d1                 1824         lsr.b           &0x1,%d1
1825         and.w           &0x7,%d1                 1825         and.w           &0x7,%d1                # extract Dx from opcode word
1826                                                  1826 
1827         mov.w           %d2,(EXC_DREGS+2,%a6,    1827         mov.w           %d2,(EXC_DREGS+2,%a6,%d1.w*4) # store dx
1828                                                  1828 
1829         rts                                      1829         rts
1830                                                  1830 
1831 # if dmem_{read,write}_byte() returns a fail     1831 # if dmem_{read,write}_byte() returns a fail message in d1, the package
1832 # must create an access error frame. here, we    1832 # must create an access error frame. here, we pass a skeleton fslw
1833 # and the failing address to the routine that    1833 # and the failing address to the routine that creates the new frame.
1834 # FSLW:                                          1834 # FSLW:
1835 #       write = true                             1835 #       write = true
1836 #       size = byte                              1836 #       size = byte
1837 #       TM = data                                1837 #       TM = data
1838 #       software emulation error = true          1838 #       software emulation error = true
1839 movp_write_err:                                  1839 movp_write_err:
1840         mov.l           %a2,%a0                  1840         mov.l           %a2,%a0                 # pass failing address
1841         mov.l           &0x00a10001,%d0          1841         mov.l           &0x00a10001,%d0         # pass fslw
1842         bra.l           isp_dacc                 1842         bra.l           isp_dacc
1843                                                  1843 
1844 # FSLW:                                          1844 # FSLW:
1845 #       read = true                              1845 #       read = true
1846 #       size = byte                              1846 #       size = byte
1847 #       TM = data                                1847 #       TM = data
1848 #       software emulation error = true          1848 #       software emulation error = true
1849 movp_read_err:                                   1849 movp_read_err:
1850         mov.l           %a2,%a0                  1850         mov.l           %a2,%a0                 # pass failing address
1851         mov.l           &0x01210001,%d0          1851         mov.l           &0x01210001,%d0         # pass fslw
1852         bra.l           isp_dacc                 1852         bra.l           isp_dacc
1853                                                  1853 
1854 #############################################    1854 #########################################################################
1855 # XDEF **************************************    1855 # XDEF **************************************************************** #
1856 #       _chk2_cmp2(): routine to emulate chk2    1856 #       _chk2_cmp2(): routine to emulate chk2/cmp2 instructions         #
1857 #                                                1857 #                                                                       #
1858 # XREF **************************************    1858 # XREF **************************************************************** #
1859 #       _calc_ea(): calculate effective addre    1859 #       _calc_ea(): calculate effective address                         #
1860 #       _dmem_read_long(): read operands         1860 #       _dmem_read_long(): read operands                                #
1861 #       _dmem_read_word(): read operands         1861 #       _dmem_read_word(): read operands                                #
1862 #       isp_dacc(): handle data access error     1862 #       isp_dacc(): handle data access error exception                  #
1863 #                                                1863 #                                                                       #
1864 # INPUT *************************************    1864 # INPUT *************************************************************** #
1865 #       none                                     1865 #       none                                                            #
1866 #                                                1866 #                                                                       #
1867 # OUTPUT ************************************    1867 # OUTPUT ************************************************************** #
1868 #       If exiting through isp_dacc...           1868 #       If exiting through isp_dacc...                                  #
1869 #               a0 = failing address             1869 #               a0 = failing address                                    #
1870 #               d0 = FSLW                        1870 #               d0 = FSLW                                               #
1871 #       else                                     1871 #       else                                                            #
1872 #               none                             1872 #               none                                                    #
1873 #                                                1873 #                                                                       #
1874 # ALGORITHM *********************************    1874 # ALGORITHM *********************************************************** #
1875 #       First, calculate the effective addres    1875 #       First, calculate the effective address, then fetch the byte,    #
1876 # word, or longword sized operands. Then, in     1876 # word, or longword sized operands. Then, in the interest of            #
1877 # simplicity, all operands are converted to l    1877 # simplicity, all operands are converted to longword size whether the   #
1878 # operation is byte, word, or long. The bound    1878 # operation is byte, word, or long. The bounds are sign extended        #
1879 # accordingly. If Rn is a data register, Rn i    1879 # accordingly. If Rn is a data register, Rn is also sign extended. If   #
1880 # Rn is an address register, it need not be s    1880 # Rn is an address register, it need not be sign extended since the     #
1881 # full register is always used.                  1881 # full register is always used.                                         #
1882 #       The comparisons are made and the cond    1882 #       The comparisons are made and the condition codes calculated.    #
1883 # If the instruction is chk2 and the Rn value    1883 # If the instruction is chk2 and the Rn value is out-of-bounds, set     #
1884 # the ichk_flg in SPCOND_FLG.                    1884 # the ichk_flg in SPCOND_FLG.                                           #
1885 #       If the memory fetch returns a failing    1885 #       If the memory fetch returns a failing value, pass the failing   #
1886 # address and FSLW to the isp_dacc() routine.    1886 # address and FSLW to the isp_dacc() routine.                           #
1887 #                                                1887 #                                                                       #
1888 #############################################    1888 #########################################################################
1889                                                  1889 
1890         global          _chk2_cmp2               1890         global          _chk2_cmp2
1891 _chk2_cmp2:                                      1891 _chk2_cmp2:
1892                                                  1892 
1893 # passing size parameter doesn't matter since    1893 # passing size parameter doesn't matter since chk2 & cmp2 can't do
1894 # either predecrement, postincrement, or imme    1894 # either predecrement, postincrement, or immediate.
1895         bsr.l           _calc_ea                 1895         bsr.l           _calc_ea                # calculate <ea>
1896                                                  1896 
1897         mov.b           EXC_EXTWORD(%a6), %d0    1897         mov.b           EXC_EXTWORD(%a6), %d0   # fetch hi extension word
1898         rol.b           &0x4, %d0                1898         rol.b           &0x4, %d0               # rotate reg bits into lo
1899         and.w           &0xf, %d0                1899         and.w           &0xf, %d0               # extract reg bits
1900                                                  1900 
1901         mov.l           (EXC_DREGS,%a6,%d0.w*    1901         mov.l           (EXC_DREGS,%a6,%d0.w*4), %d2 # get regval
1902                                                  1902 
1903         cmpi.b          EXC_OPWORD(%a6), &0x2    1903         cmpi.b          EXC_OPWORD(%a6), &0x2   # what size is operation?
1904         blt.b           chk2_cmp2_byte           1904         blt.b           chk2_cmp2_byte          # size == byte
1905         beq.b           chk2_cmp2_word           1905         beq.b           chk2_cmp2_word          # size == word
1906                                                  1906 
1907 # the bounds are longword size. call routine     1907 # the bounds are longword size. call routine to read the lower
1908 # bound into d0 and the higher bound into d1.    1908 # bound into d0 and the higher bound into d1.
1909 chk2_cmp2_long:                                  1909 chk2_cmp2_long:
1910         mov.l           %a0,%a2                  1910         mov.l           %a0,%a2                 # save copy of <ea>
1911         bsr.l           _dmem_read_long          1911         bsr.l           _dmem_read_long         # fetch long lower bound
1912                                                  1912 
1913         tst.l           %d1                      1913         tst.l           %d1                     # dfetch error?
1914         bne.w           chk2_cmp2_err_l          1914         bne.w           chk2_cmp2_err_l         # yes
1915                                                  1915 
1916         mov.l           %d0,%d3                  1916         mov.l           %d0,%d3                 # save long lower bound
1917         addq.l          &0x4,%a2                 1917         addq.l          &0x4,%a2
1918         mov.l           %a2,%a0                  1918         mov.l           %a2,%a0                 # pass <ea> of long upper bound
1919         bsr.l           _dmem_read_long          1919         bsr.l           _dmem_read_long         # fetch long upper bound
1920                                                  1920 
1921         tst.l           %d1                      1921         tst.l           %d1                     # dfetch error?
1922         bne.w           chk2_cmp2_err_l          1922         bne.w           chk2_cmp2_err_l         # yes
1923                                                  1923 
1924         mov.l           %d0,%d1                  1924         mov.l           %d0,%d1                 # long upper bound in d1
1925         mov.l           %d3,%d0                  1925         mov.l           %d3,%d0                 # long lower bound in d0
1926         bra.w           chk2_cmp2_compare        1926         bra.w           chk2_cmp2_compare       # go do the compare emulation
1927                                                  1927 
1928 # the bounds are word size. fetch them in one    1928 # the bounds are word size. fetch them in one subroutine call by
1929 # reading a longword. sign extend both. if it    1929 # reading a longword. sign extend both. if it's a data operation,
1930 # sign extend Rn to long, also.                  1930 # sign extend Rn to long, also.
1931 chk2_cmp2_word:                                  1931 chk2_cmp2_word:
1932         mov.l           %a0,%a2                  1932         mov.l           %a0,%a2
1933         bsr.l           _dmem_read_long          1933         bsr.l           _dmem_read_long         # fetch 2 word bounds
1934                                                  1934 
1935         tst.l           %d1                      1935         tst.l           %d1                     # dfetch error?
1936         bne.w           chk2_cmp2_err_l          1936         bne.w           chk2_cmp2_err_l         # yes
1937                                                  1937 
1938         mov.w           %d0, %d1                 1938         mov.w           %d0, %d1                # place hi in %d1
1939         swap            %d0                      1939         swap            %d0                     # place lo in %d0
1940                                                  1940 
1941         ext.l           %d0                      1941         ext.l           %d0                     # sign extend lo bnd
1942         ext.l           %d1                      1942         ext.l           %d1                     # sign extend hi bnd
1943                                                  1943 
1944         btst            &0x7, EXC_EXTWORD(%a6    1944         btst            &0x7, EXC_EXTWORD(%a6)  # address compare?
1945         bne.w           chk2_cmp2_compare        1945         bne.w           chk2_cmp2_compare       # yes; don't sign extend
1946                                                  1946 
1947 # operation is a data register compare.          1947 # operation is a data register compare.
1948 # sign extend word to long so we can do simpl    1948 # sign extend word to long so we can do simple longword compares.
1949         ext.l           %d2                      1949         ext.l           %d2                     # sign extend data word
1950         bra.w           chk2_cmp2_compare        1950         bra.w           chk2_cmp2_compare       # go emulate compare
1951                                                  1951 
1952 # the bounds are byte size. fetch them in one    1952 # the bounds are byte size. fetch them in one subroutine call by
1953 # reading a word. sign extend both. if it's a    1953 # reading a word. sign extend both. if it's a data operation,
1954 # sign extend Rn to long, also.                  1954 # sign extend Rn to long, also.
1955 chk2_cmp2_byte:                                  1955 chk2_cmp2_byte:
1956         mov.l           %a0,%a2                  1956         mov.l           %a0,%a2
1957         bsr.l           _dmem_read_word          1957         bsr.l           _dmem_read_word         # fetch 2 byte bounds
1958                                                  1958 
1959         tst.l           %d1                      1959         tst.l           %d1                     # dfetch error?
1960         bne.w           chk2_cmp2_err_w          1960         bne.w           chk2_cmp2_err_w         # yes
1961                                                  1961 
1962         mov.b           %d0, %d1                 1962         mov.b           %d0, %d1                # place hi in %d1
1963         lsr.w           &0x8, %d0                1963         lsr.w           &0x8, %d0               # place lo in %d0
1964                                                  1964 
1965         extb.l          %d0                      1965         extb.l          %d0                     # sign extend lo bnd
1966         extb.l          %d1                      1966         extb.l          %d1                     # sign extend hi bnd
1967                                                  1967 
1968         btst            &0x7, EXC_EXTWORD(%a6    1968         btst            &0x7, EXC_EXTWORD(%a6)  # address compare?
1969         bne.b           chk2_cmp2_compare        1969         bne.b           chk2_cmp2_compare       # yes; don't sign extend
1970                                                  1970 
1971 # operation is a data register compare.          1971 # operation is a data register compare.
1972 # sign extend byte to long so we can do simpl    1972 # sign extend byte to long so we can do simple longword compares.
1973         extb.l          %d2                      1973         extb.l          %d2                     # sign extend data byte
1974                                                  1974 
1975 #                                                1975 #
1976 # To set the ccodes correctly:                   1976 # To set the ccodes correctly:
1977 #       (1) save 'Z' bit from (Rn - lo)          1977 #       (1) save 'Z' bit from (Rn - lo)
1978 #       (2) save 'Z' and 'N' bits from ((hi -    1978 #       (2) save 'Z' and 'N' bits from ((hi - lo) - (Rn - hi))
1979 #       (3) keep 'X', 'N', and 'V' from befor    1979 #       (3) keep 'X', 'N', and 'V' from before instruction
1980 #       (4) combine ccodes                       1980 #       (4) combine ccodes
1981 #                                                1981 #
1982 chk2_cmp2_compare:                               1982 chk2_cmp2_compare:
1983         sub.l           %d0, %d2                 1983         sub.l           %d0, %d2                # (Rn - lo)
1984         mov.w           %cc, %d3                 1984         mov.w           %cc, %d3                # fetch resulting ccodes
1985         andi.b          &0x4, %d3                1985         andi.b          &0x4, %d3               # keep 'Z' bit
1986         sub.l           %d0, %d1                 1986         sub.l           %d0, %d1                # (hi - lo)
1987         cmp.l           %d1,%d2                  1987         cmp.l           %d1,%d2                 # ((hi - lo) - (Rn - hi))
1988                                                  1988 
1989         mov.w           %cc, %d4                 1989         mov.w           %cc, %d4                # fetch resulting ccodes
1990         or.b            %d4, %d3                 1990         or.b            %d4, %d3                # combine w/ earlier ccodes
1991         andi.b          &0x5, %d3                1991         andi.b          &0x5, %d3               # keep 'Z' and 'N'
1992                                                  1992 
1993         mov.w           EXC_CC(%a6), %d4         1993         mov.w           EXC_CC(%a6), %d4        # fetch old ccodes
1994         andi.b          &0x1a, %d4               1994         andi.b          &0x1a, %d4              # keep 'X','N','V' bits
1995         or.b            %d3, %d4                 1995         or.b            %d3, %d4                # insert new ccodes
1996         mov.w           %d4, EXC_CC(%a6)         1996         mov.w           %d4, EXC_CC(%a6)        # save new ccodes
1997                                                  1997 
1998         btst            &0x3, EXC_EXTWORD(%a6    1998         btst            &0x3, EXC_EXTWORD(%a6)  # separate chk2,cmp2
1999         bne.b           chk2_finish              1999         bne.b           chk2_finish             # it's a chk2
2000                                                  2000 
2001         rts                                      2001         rts
2002                                                  2002 
2003 # this code handles the only difference betwe    2003 # this code handles the only difference between chk2 and cmp2. chk2 would
2004 # have trapped out if the value was out of bo    2004 # have trapped out if the value was out of bounds. we check this by seeing
2005 # if the 'N' bit was set by the operation.       2005 # if the 'N' bit was set by the operation.
2006 chk2_finish:                                     2006 chk2_finish:
2007         btst            &0x0, %d4                2007         btst            &0x0, %d4               # is 'N' bit set?
2008         bne.b           chk2_trap                2008         bne.b           chk2_trap               # yes;chk2 should trap
2009         rts                                      2009         rts
2010 chk2_trap:                                       2010 chk2_trap:
2011         mov.b           &ichk_flg,SPCOND_FLG(    2011         mov.b           &ichk_flg,SPCOND_FLG(%a6) # set "special case" flag
2012         rts                                      2012         rts
2013                                                  2013 
2014 # if dmem_read_{long,word}() returns a fail m    2014 # if dmem_read_{long,word}() returns a fail message in d1, the package
2015 # must create an access error frame. here, we    2015 # must create an access error frame. here, we pass a skeleton fslw
2016 # and the failing address to the routine that    2016 # and the failing address to the routine that creates the new frame.
2017 # FSLW:                                          2017 # FSLW:
2018 #       read = true                              2018 #       read = true
2019 #       size = longword                          2019 #       size = longword
2020 #       TM = data                                2020 #       TM = data
2021 #       software emulation error = true          2021 #       software emulation error = true
2022 chk2_cmp2_err_l:                                 2022 chk2_cmp2_err_l:
2023         mov.l           %a2,%a0                  2023         mov.l           %a2,%a0                 # pass failing address
2024         mov.l           &0x01010001,%d0          2024         mov.l           &0x01010001,%d0         # pass fslw
2025         bra.l           isp_dacc                 2025         bra.l           isp_dacc
2026                                                  2026 
2027 # FSLW:                                          2027 # FSLW:
2028 #       read = true                              2028 #       read = true
2029 #       size = word                              2029 #       size = word
2030 #       TM = data                                2030 #       TM = data
2031 #       software emulation error = true          2031 #       software emulation error = true
2032 chk2_cmp2_err_w:                                 2032 chk2_cmp2_err_w:
2033         mov.l           %a2,%a0                  2033         mov.l           %a2,%a0                 # pass failing address
2034         mov.l           &0x01410001,%d0          2034         mov.l           &0x01410001,%d0         # pass fslw
2035         bra.l           isp_dacc                 2035         bra.l           isp_dacc
2036                                                  2036 
2037 #############################################    2037 #########################################################################
2038 # XDEF **************************************    2038 # XDEF **************************************************************** #
2039 #       _div64(): routine to emulate div{u,s}    2039 #       _div64(): routine to emulate div{u,s}.l <ea>,Dr:Dq              #
2040 #                                                2040 #                                                       64/32->32r:32q  #
2041 #                                                2041 #                                                                       #
2042 # XREF **************************************    2042 # XREF **************************************************************** #
2043 #       _calc_ea() - calculate effective addr    2043 #       _calc_ea() - calculate effective address                        #
2044 #       isp_iacc() - handle instruction acces    2044 #       isp_iacc() - handle instruction access error exception          #
2045 #       isp_dacc() - handle data access error    2045 #       isp_dacc() - handle data access error exception                 #
2046 #       isp_restore() - restore An on access     2046 #       isp_restore() - restore An on access error w/ -() or ()+        #
2047 #                                                2047 #                                                                       #
2048 # INPUT *************************************    2048 # INPUT *************************************************************** #
2049 #       none                                     2049 #       none                                                            #
2050 #                                                2050 #                                                                       #
2051 # OUTPUT ************************************    2051 # OUTPUT ************************************************************** #
2052 #       If exiting through isp_dacc...           2052 #       If exiting through isp_dacc...                                  #
2053 #               a0 = failing address             2053 #               a0 = failing address                                    #
2054 #               d0 = FSLW                        2054 #               d0 = FSLW                                               #
2055 #       else                                     2055 #       else                                                            #
2056 #               none                             2056 #               none                                                    #
2057 #                                                2057 #                                                                       #
2058 # ALGORITHM *********************************    2058 # ALGORITHM *********************************************************** #
2059 #       First, decode the operand location. I    2059 #       First, decode the operand location. If it's in Dn, fetch from   #
2060 # the stack. If it's in memory, use _calc_ea(    2060 # the stack. If it's in memory, use _calc_ea() to calculate the         #
2061 # effective address. Use _dmem_read_long() to    2061 # effective address. Use _dmem_read_long() to fetch at that address.    #
2062 # Unless the operand is immediate data. Then     2062 # Unless the operand is immediate data. Then use _imem_read_long().     #
2063 # Send failures to isp_dacc() or isp_iacc() a    2063 # Send failures to isp_dacc() or isp_iacc() as appropriate.             #
2064 #       If the operands are signed, make them    2064 #       If the operands are signed, make them unsigned and save the     #
2065 # sign info for later. Separate out special c    2065 # sign info for later. Separate out special cases like divide-by-zero   #
2066 # or 32-bit divides if possible. Else, use a     2066 # or 32-bit divides if possible. Else, use a special math algorithm     #
2067 # to calculate the result.                       2067 # to calculate the result.                                              #
2068 #       Restore sign info if signed instructi    2068 #       Restore sign info if signed instruction. Set the condition      #
2069 # codes. Set idbyz_flg in SPCOND_FLG if divis    2069 # codes. Set idbyz_flg in SPCOND_FLG if divisor was zero. Store the     #
2070 # quotient and remainder in the appropriate d    2070 # quotient and remainder in the appropriate data registers on the stack.#
2071 #                                                2071 #                                                                       #
2072 #############################################    2072 #########################################################################
2073                                                  2073 
2074 set     NDIVISOR,       EXC_TEMP+0x0             2074 set     NDIVISOR,       EXC_TEMP+0x0
2075 set     NDIVIDEND,      EXC_TEMP+0x1             2075 set     NDIVIDEND,      EXC_TEMP+0x1
2076 set     NDRSAVE,        EXC_TEMP+0x2             2076 set     NDRSAVE,        EXC_TEMP+0x2
2077 set     NDQSAVE,        EXC_TEMP+0x4             2077 set     NDQSAVE,        EXC_TEMP+0x4
2078 set     DDSECOND,       EXC_TEMP+0x6             2078 set     DDSECOND,       EXC_TEMP+0x6
2079 set     DDQUOTIENT,     EXC_TEMP+0x8             2079 set     DDQUOTIENT,     EXC_TEMP+0x8
2080 set     DDNORMAL,       EXC_TEMP+0xc             2080 set     DDNORMAL,       EXC_TEMP+0xc
2081                                                  2081 
2082         global          _div64                   2082         global          _div64
2083 #############                                    2083 #############
2084 # div(u,s)l #                                    2084 # div(u,s)l #
2085 #############                                    2085 #############
2086 _div64:                                          2086 _div64:
2087         mov.b           EXC_OPWORD+1(%a6), %d    2087         mov.b           EXC_OPWORD+1(%a6), %d0
2088         andi.b          &0x38, %d0               2088         andi.b          &0x38, %d0              # extract src mode
2089                                                  2089 
2090         bne.w           dcontrolmodel_s          2090         bne.w           dcontrolmodel_s         # %dn dest or control mode?
2091                                                  2091 
2092         mov.b           EXC_OPWORD+1(%a6), %d    2092         mov.b           EXC_OPWORD+1(%a6), %d0  # extract Dn from opcode
2093         andi.w          &0x7, %d0                2093         andi.w          &0x7, %d0
2094         mov.l           (EXC_DREGS,%a6,%d0.w*    2094         mov.l           (EXC_DREGS,%a6,%d0.w*4), %d7 # fetch divisor from register
2095                                                  2095 
2096 dgotsrcl:                                        2096 dgotsrcl:
2097         beq.w           div64eq0                 2097         beq.w           div64eq0                # divisor is = 0!!!
2098                                                  2098 
2099         mov.b           EXC_EXTWORD+1(%a6), %    2099         mov.b           EXC_EXTWORD+1(%a6), %d0 # extract Dr from extword
2100         mov.b           EXC_EXTWORD(%a6), %d1    2100         mov.b           EXC_EXTWORD(%a6), %d1   # extract Dq from extword
2101         and.w           &0x7, %d0                2101         and.w           &0x7, %d0
2102         lsr.b           &0x4, %d1                2102         lsr.b           &0x4, %d1
2103         and.w           &0x7, %d1                2103         and.w           &0x7, %d1
2104         mov.w           %d0, NDRSAVE(%a6)        2104         mov.w           %d0, NDRSAVE(%a6)       # save Dr for later
2105         mov.w           %d1, NDQSAVE(%a6)        2105         mov.w           %d1, NDQSAVE(%a6)       # save Dq for later
2106                                                  2106 
2107 # fetch %dr and %dq directly off stack since     2107 # fetch %dr and %dq directly off stack since all regs are saved there
2108         mov.l           (EXC_DREGS,%a6,%d0.w*    2108         mov.l           (EXC_DREGS,%a6,%d0.w*4), %d5 # get dividend hi
2109         mov.l           (EXC_DREGS,%a6,%d1.w*    2109         mov.l           (EXC_DREGS,%a6,%d1.w*4), %d6 # get dividend lo
2110                                                  2110 
2111 # separate signed and unsigned divide            2111 # separate signed and unsigned divide
2112         btst            &0x3, EXC_EXTWORD(%a6    2112         btst            &0x3, EXC_EXTWORD(%a6)  # signed or unsigned?
2113         beq.b           dspecialcases            2113         beq.b           dspecialcases           # use positive divide
2114                                                  2114 
2115 # save the sign of the divisor                   2115 # save the sign of the divisor
2116 # make divisor unsigned if it's negative         2116 # make divisor unsigned if it's negative
2117         tst.l           %d7                      2117         tst.l           %d7                     # chk sign of divisor
2118         slt             NDIVISOR(%a6)            2118         slt             NDIVISOR(%a6)           # save sign of divisor
2119         bpl.b           dsgndividend             2119         bpl.b           dsgndividend
2120         neg.l           %d7                      2120         neg.l           %d7                     # complement negative divisor
2121                                                  2121 
2122 # save the sign of the dividend                  2122 # save the sign of the dividend
2123 # make dividend unsigned if it's negative        2123 # make dividend unsigned if it's negative
2124 dsgndividend:                                    2124 dsgndividend:
2125         tst.l           %d5                      2125         tst.l           %d5                     # chk sign of hi(dividend)
2126         slt             NDIVIDEND(%a6)           2126         slt             NDIVIDEND(%a6)          # save sign of dividend
2127         bpl.b           dspecialcases            2127         bpl.b           dspecialcases
2128                                                  2128 
2129         mov.w           &0x0, %cc                2129         mov.w           &0x0, %cc               # clear 'X' cc bit
2130         negx.l          %d6                      2130         negx.l          %d6                     # complement signed dividend
2131         negx.l          %d5                      2131         negx.l          %d5
2132                                                  2132 
2133 # extract some special cases:                    2133 # extract some special cases:
2134 #       - is (dividend == 0) ?                   2134 #       - is (dividend == 0) ?
2135 #       - is (hi(dividend) == 0 && (divisor <    2135 #       - is (hi(dividend) == 0 && (divisor <= lo(dividend))) ? (32-bit div)
2136 dspecialcases:                                   2136 dspecialcases:
2137         tst.l           %d5                      2137         tst.l           %d5                     # is (hi(dividend) == 0)
2138         bne.b           dnormaldivide            2138         bne.b           dnormaldivide           # no, so try it the long way
2139                                                  2139 
2140         tst.l           %d6                      2140         tst.l           %d6                     # is (lo(dividend) == 0), too
2141         beq.w           ddone                    2141         beq.w           ddone                   # yes, so (dividend == 0)
2142                                                  2142 
2143         cmp.l           %d7,%d6                  2143         cmp.l           %d7,%d6                 # is (divisor <= lo(dividend))
2144         bls.b           d32bitdivide             2144         bls.b           d32bitdivide            # yes, so use 32 bit divide
2145                                                  2145 
2146         exg             %d5,%d6                  2146         exg             %d5,%d6                 # q = 0, r = dividend
2147         bra.w           divfinish                2147         bra.w           divfinish               # can't divide, we're done.
2148                                                  2148 
2149 d32bitdivide:                                    2149 d32bitdivide:
2150         tdivu.l         %d7, %d5:%d6             2150         tdivu.l         %d7, %d5:%d6            # it's only a 32/32 bit div!
2151                                                  2151 
2152         bra.b           divfinish                2152         bra.b           divfinish
2153                                                  2153 
2154 dnormaldivide:                                   2154 dnormaldivide:
2155 # last special case:                             2155 # last special case:
2156 #       - is hi(dividend) >= divisor ? if yes    2156 #       - is hi(dividend) >= divisor ? if yes, then overflow
2157         cmp.l           %d7,%d5                  2157         cmp.l           %d7,%d5
2158         bls.b           ddovf                    2158         bls.b           ddovf                   # answer won't fit in 32 bits
2159                                                  2159 
2160 # perform the divide algorithm:                  2160 # perform the divide algorithm:
2161         bsr.l           dclassical               2161         bsr.l           dclassical              # do int divide
2162                                                  2162 
2163 # separate into signed and unsigned finishes.    2163 # separate into signed and unsigned finishes.
2164 divfinish:                                       2164 divfinish:
2165         btst            &0x3, EXC_EXTWORD(%a6    2165         btst            &0x3, EXC_EXTWORD(%a6)  # do divs, divu separately
2166         beq.b           ddone                    2166         beq.b           ddone                   # divu has no processing!!!
2167                                                  2167 
2168 # it was a divs.l, so ccode setting is a litt    2168 # it was a divs.l, so ccode setting is a little more complicated...
2169         tst.b           NDIVIDEND(%a6)           2169         tst.b           NDIVIDEND(%a6)          # remainder has same sign
2170         beq.b           dcc                      2170         beq.b           dcc                     # as dividend.
2171         neg.l           %d5                      2171         neg.l           %d5                     # sgn(rem) = sgn(dividend)
2172 dcc:                                             2172 dcc:
2173         mov.b           NDIVISOR(%a6), %d0       2173         mov.b           NDIVISOR(%a6), %d0
2174         eor.b           %d0, NDIVIDEND(%a6)      2174         eor.b           %d0, NDIVIDEND(%a6)     # chk if quotient is negative
2175         beq.b           dqpos                    2175         beq.b           dqpos                   # branch to quot positive
2176                                                  2176 
2177 # 0x80000000 is the largest number representa    2177 # 0x80000000 is the largest number representable as a 32-bit negative
2178 # number. the negative of 0x80000000 is 0x800    2178 # number. the negative of 0x80000000 is 0x80000000.
2179         cmpi.l          %d6, &0x80000000         2179         cmpi.l          %d6, &0x80000000        # will (-quot) fit in 32 bits?
2180         bhi.b           ddovf                    2180         bhi.b           ddovf
2181                                                  2181 
2182         neg.l           %d6                      2182         neg.l           %d6                     # make (-quot) 2's comp
2183                                                  2183 
2184         bra.b           ddone                    2184         bra.b           ddone
2185                                                  2185 
2186 dqpos:                                           2186 dqpos:
2187         btst            &0x1f, %d6               2187         btst            &0x1f, %d6              # will (+quot) fit in 32 bits?
2188         bne.b           ddovf                    2188         bne.b           ddovf
2189                                                  2189 
2190 ddone:                                           2190 ddone:
2191 # at this point, result is normal so ccodes a    2191 # at this point, result is normal so ccodes are set based on result.
2192         mov.w           EXC_CC(%a6), %cc         2192         mov.w           EXC_CC(%a6), %cc
2193         tst.l           %d6                      2193         tst.l           %d6                     # set %ccode bits
2194         mov.w           %cc, EXC_CC(%a6)         2194         mov.w           %cc, EXC_CC(%a6)
2195                                                  2195 
2196         mov.w           NDRSAVE(%a6), %d0        2196         mov.w           NDRSAVE(%a6), %d0       # get Dr off stack
2197         mov.w           NDQSAVE(%a6), %d1        2197         mov.w           NDQSAVE(%a6), %d1       # get Dq off stack
2198                                                  2198 
2199 # if the register numbers are the same, only     2199 # if the register numbers are the same, only the quotient gets saved.
2200 # so, if we always save the quotient second,     2200 # so, if we always save the quotient second, we save ourselves a cmp&beq
2201         mov.l           %d5, (EXC_DREGS,%a6,%    2201         mov.l           %d5, (EXC_DREGS,%a6,%d0.w*4) # save remainder
2202         mov.l           %d6, (EXC_DREGS,%a6,%    2202         mov.l           %d6, (EXC_DREGS,%a6,%d1.w*4) # save quotient
2203                                                  2203 
2204         rts                                      2204         rts
2205                                                  2205 
2206 ddovf:                                           2206 ddovf:
2207         bset            &0x1, EXC_CC+1(%a6)      2207         bset            &0x1, EXC_CC+1(%a6)     # 'V' set on overflow
2208         bclr            &0x0, EXC_CC+1(%a6)      2208         bclr            &0x0, EXC_CC+1(%a6)     # 'C' cleared on overflow
2209                                                  2209 
2210         rts                                      2210         rts
2211                                                  2211 
2212 div64eq0:                                        2212 div64eq0:
2213         andi.b          &0x1e, EXC_CC+1(%a6)     2213         andi.b          &0x1e, EXC_CC+1(%a6)    # clear 'C' bit on divbyzero
2214         ori.b           &idbyz_flg,SPCOND_FLG    2214         ori.b           &idbyz_flg,SPCOND_FLG(%a6) # set "special case" flag
2215         rts                                      2215         rts
2216                                                  2216 
2217 #############################################    2217 ###########################################################################
2218 #############################################    2218 #########################################################################
2219 # This routine uses the 'classical' Algorithm    2219 # This routine uses the 'classical' Algorithm D from Donald Knuth's     #
2220 # Art of Computer Programming, vol II, Seminu    2220 # Art of Computer Programming, vol II, Seminumerical Algorithms.        #
2221 # For this implementation b=2**16, and the ta    2221 # For this implementation b=2**16, and the target is U1U2U3U4/V1V2,     #
2222 # where U,V are words of the quadword dividen    2222 # where U,V are words of the quadword dividend and longword divisor,    #
2223 # and U1, V1 are the most significant words.     2223 # and U1, V1 are the most significant words.                            #
2224 #                                                2224 #                                                                       #
2225 # The most sig. longword of the 64 bit divide    2225 # The most sig. longword of the 64 bit dividend must be in %d5, least   #
2226 # in %d6. The divisor must be in the variable    2226 # in %d6. The divisor must be in the variable ddivisor, and the         #
2227 # signed/unsigned flag ddusign must be set (0    2227 # signed/unsigned flag ddusign must be set (0=unsigned,1=signed).       #
2228 # The quotient is returned in %d6, remainder     2228 # The quotient is returned in %d6, remainder in %d5, unless the         #
2229 # v (overflow) bit is set in the saved %ccr.     2229 # v (overflow) bit is set in the saved %ccr. If overflow, the dividend  #
2230 # is unchanged.                                  2230 # is unchanged.                                                         #
2231 #############################################    2231 #########################################################################
2232 dclassical:                                      2232 dclassical:
2233 # if the divisor msw is 0, use simpler algori    2233 # if the divisor msw is 0, use simpler algorithm then the full blown
2234 # one at ddknuth:                                2234 # one at ddknuth:
2235                                                  2235 
2236         cmpi.l          %d7, &0xffff             2236         cmpi.l          %d7, &0xffff
2237         bhi.b           ddknuth                  2237         bhi.b           ddknuth                 # go use D. Knuth algorithm
2238                                                  2238 
2239 # Since the divisor is only a word (and large    2239 # Since the divisor is only a word (and larger than the mslw of the dividend),
2240 # a simpler algorithm may be used :              2240 # a simpler algorithm may be used :
2241 # In the general case, four quotient words wo    2241 # In the general case, four quotient words would be created by
2242 # dividing the divisor word into each dividen    2242 # dividing the divisor word into each dividend word. In this case,
2243 # the first two quotient words must be zero,     2243 # the first two quotient words must be zero, or overflow would occur.
2244 # Since we already checked this case above, w    2244 # Since we already checked this case above, we can treat the most significant
2245 # longword of the dividend as (0) remainder (    2245 # longword of the dividend as (0) remainder (see Knuth) and merely complete
2246 # the last two divisions to get a quotient lo    2246 # the last two divisions to get a quotient longword and word remainder:
2247                                                  2247 
2248         clr.l           %d1                      2248         clr.l           %d1
2249         swap            %d5                      2249         swap            %d5                     # same as r*b if previous step rqd
2250         swap            %d6                      2250         swap            %d6                     # get u3 to lsw position
2251         mov.w           %d6, %d5                 2251         mov.w           %d6, %d5                # rb + u3
2252                                                  2252 
2253         divu.w          %d7, %d5                 2253         divu.w          %d7, %d5
2254                                                  2254 
2255         mov.w           %d5, %d1                 2255         mov.w           %d5, %d1                # first quotient word
2256         swap            %d6                      2256         swap            %d6                     # get u4
2257         mov.w           %d6, %d5                 2257         mov.w           %d6, %d5                # rb + u4
2258                                                  2258 
2259         divu.w          %d7, %d5                 2259         divu.w          %d7, %d5
2260                                                  2260 
2261         swap            %d1                      2261         swap            %d1
2262         mov.w           %d5, %d1                 2262         mov.w           %d5, %d1                # 2nd quotient 'digit'
2263         clr.w           %d5                      2263         clr.w           %d5
2264         swap            %d5                      2264         swap            %d5                     # now remainder
2265         mov.l           %d1, %d6                 2265         mov.l           %d1, %d6                # and quotient
2266                                                  2266 
2267         rts                                      2267         rts
2268                                                  2268 
2269 ddknuth:                                         2269 ddknuth:
2270 # In this algorithm, the divisor is treated a    2270 # In this algorithm, the divisor is treated as a 2 digit (word) number
2271 # which is divided into a 3 digit (word) divi    2271 # which is divided into a 3 digit (word) dividend to get one quotient
2272 # digit (word). After subtraction, the divide    2272 # digit (word). After subtraction, the dividend is shifted and the
2273 # process repeated. Before beginning, the div    2273 # process repeated. Before beginning, the divisor and quotient are
2274 # 'normalized' so that the process of estimat    2274 # 'normalized' so that the process of estimating the quotient digit
2275 # will yield verifiably correct results..        2275 # will yield verifiably correct results..
2276                                                  2276 
2277         clr.l           DDNORMAL(%a6)            2277         clr.l           DDNORMAL(%a6)           # count of shifts for normalization
2278         clr.b           DDSECOND(%a6)            2278         clr.b           DDSECOND(%a6)           # clear flag for quotient digits
2279         clr.l           %d1                      2279         clr.l           %d1                     # %d1 will hold trial quotient
2280 ddnchk:                                          2280 ddnchk:
2281         btst            &31, %d7                 2281         btst            &31, %d7                # must we normalize? first word of
2282         bne.b           ddnormalized             2282         bne.b           ddnormalized            # divisor (V1) must be >= 65536/2
2283         addq.l          &0x1, DDNORMAL(%a6)      2283         addq.l          &0x1, DDNORMAL(%a6)     # count normalization shifts
2284         lsl.l           &0x1, %d7                2284         lsl.l           &0x1, %d7               # shift the divisor
2285         lsl.l           &0x1, %d6                2285         lsl.l           &0x1, %d6               # shift u4,u3 with overflow to u2
2286         roxl.l          &0x1, %d5                2286         roxl.l          &0x1, %d5               # shift u1,u2
2287         bra.w           ddnchk                   2287         bra.w           ddnchk
2288 ddnormalized:                                    2288 ddnormalized:
2289                                                  2289 
2290 # Now calculate an estimate of the quotient w    2290 # Now calculate an estimate of the quotient words (msw first, then lsw).
2291 # The comments use subscripts for the first q    2291 # The comments use subscripts for the first quotient digit determination.
2292         mov.l           %d7, %d3                 2292         mov.l           %d7, %d3                # divisor
2293         mov.l           %d5, %d2                 2293         mov.l           %d5, %d2                # dividend mslw
2294         swap            %d2                      2294         swap            %d2
2295         swap            %d3                      2295         swap            %d3
2296         cmp.w           %d2, %d3                 2296         cmp.w           %d2, %d3                # V1 = U1 ?
2297         bne.b           ddqcalc1                 2297         bne.b           ddqcalc1
2298         mov.w           &0xffff, %d1             2298         mov.w           &0xffff, %d1            # use max trial quotient word
2299         bra.b           ddadj0                   2299         bra.b           ddadj0
2300 ddqcalc1:                                        2300 ddqcalc1:
2301         mov.l           %d5, %d1                 2301         mov.l           %d5, %d1
2302                                                  2302 
2303         divu.w          %d3, %d1                 2303         divu.w          %d3, %d1                # use quotient of mslw/msw
2304                                                  2304 
2305         andi.l          &0x0000ffff, %d1         2305         andi.l          &0x0000ffff, %d1        # zero any remainder
2306 ddadj0:                                          2306 ddadj0:
2307                                                  2307 
2308 # now test the trial quotient and adjust. Thi    2308 # now test the trial quotient and adjust. This step plus the
2309 # normalization assures (according to Knuth)     2309 # normalization assures (according to Knuth) that the trial
2310 # quotient will be at worst 1 too large.         2310 # quotient will be at worst 1 too large.
2311         mov.l           %d6, -(%sp)              2311         mov.l           %d6, -(%sp)
2312         clr.w           %d6                      2312         clr.w           %d6                     # word u3 left
2313         swap            %d6                      2313         swap            %d6                     # in lsw position
2314 ddadj1: mov.l           %d7, %d3                 2314 ddadj1: mov.l           %d7, %d3
2315         mov.l           %d1, %d2                 2315         mov.l           %d1, %d2
2316         mulu.w          %d7, %d2                 2316         mulu.w          %d7, %d2                # V2q
2317         swap            %d3                      2317         swap            %d3
2318         mulu.w          %d1, %d3                 2318         mulu.w          %d1, %d3                # V1q
2319         mov.l           %d5, %d4                 2319         mov.l           %d5, %d4                # U1U2
2320         sub.l           %d3, %d4                 2320         sub.l           %d3, %d4                # U1U2 - V1q
2321                                                  2321 
2322         swap            %d4                      2322         swap            %d4
2323                                                  2323 
2324         mov.w           %d4,%d0                  2324         mov.w           %d4,%d0
2325         mov.w           %d6,%d4                  2325         mov.w           %d6,%d4                 # insert lower word (U3)
2326                                                  2326 
2327         tst.w           %d0                      2327         tst.w           %d0                     # is upper word set?
2328         bne.w           ddadjd1                  2328         bne.w           ddadjd1
2329                                                  2329 
2330 #       add.l           %d6, %d4                 2330 #       add.l           %d6, %d4                # (U1U2 - V1q) + U3
2331                                                  2331 
2332         cmp.l           %d2, %d4                 2332         cmp.l           %d2, %d4
2333         bls.b           ddadjd1                  2333         bls.b           ddadjd1                 # is V2q > (U1U2-V1q) + U3 ?
2334         subq.l          &0x1, %d1                2334         subq.l          &0x1, %d1               # yes, decrement and recheck
2335         bra.b           ddadj1                   2335         bra.b           ddadj1
2336 ddadjd1:                                         2336 ddadjd1:
2337 # now test the word by multiplying it by the     2337 # now test the word by multiplying it by the divisor (V1V2) and comparing
2338 # the 3 digit (word) result with the current     2338 # the 3 digit (word) result with the current dividend words
2339         mov.l           %d5, -(%sp)              2339         mov.l           %d5, -(%sp)             # save %d5 (%d6 already saved)
2340         mov.l           %d1, %d6                 2340         mov.l           %d1, %d6
2341         swap            %d6                      2341         swap            %d6                     # shift answer to ms 3 words
2342         mov.l           %d7, %d5                 2342         mov.l           %d7, %d5
2343         bsr.l           dmm2                     2343         bsr.l           dmm2
2344         mov.l           %d5, %d2                 2344         mov.l           %d5, %d2                # now %d2,%d3 are trial*divisor
2345         mov.l           %d6, %d3                 2345         mov.l           %d6, %d3
2346         mov.l           (%sp)+, %d5              2346         mov.l           (%sp)+, %d5             # restore dividend
2347         mov.l           (%sp)+, %d6              2347         mov.l           (%sp)+, %d6
2348         sub.l           %d3, %d6                 2348         sub.l           %d3, %d6
2349         subx.l          %d2, %d5                 2349         subx.l          %d2, %d5                # subtract double precision
2350         bcc             dd2nd                    2350         bcc             dd2nd                   # no carry, do next quotient digit
2351         subq.l          &0x1, %d1                2351         subq.l          &0x1, %d1               # q is one too large
2352 # need to add back divisor longword to curren    2352 # need to add back divisor longword to current ms 3 digits of dividend
2353 # - according to Knuth, this is done only 2 o    2353 # - according to Knuth, this is done only 2 out of 65536 times for random
2354 # divisor, dividend selection.                   2354 # divisor, dividend selection.
2355         clr.l           %d2                      2355         clr.l           %d2
2356         mov.l           %d7, %d3                 2356         mov.l           %d7, %d3
2357         swap            %d3                      2357         swap            %d3
2358         clr.w           %d3                      2358         clr.w           %d3                     # %d3 now ls word of divisor
2359         add.l           %d3, %d6                 2359         add.l           %d3, %d6                # aligned with 3rd word of dividend
2360         addx.l          %d2, %d5                 2360         addx.l          %d2, %d5
2361         mov.l           %d7, %d3                 2361         mov.l           %d7, %d3
2362         clr.w           %d3                      2362         clr.w           %d3                     # %d3 now ms word of divisor
2363         swap            %d3                      2363         swap            %d3                     # aligned with 2nd word of dividend
2364         add.l           %d3, %d5                 2364         add.l           %d3, %d5
2365 dd2nd:                                           2365 dd2nd:
2366         tst.b           DDSECOND(%a6)            2366         tst.b           DDSECOND(%a6)           # both q words done?
2367         bne.b           ddremain                 2367         bne.b           ddremain
2368 # first quotient digit now correct. store dig    2368 # first quotient digit now correct. store digit and shift the
2369 # (subtracted) dividend                          2369 # (subtracted) dividend
2370         mov.w           %d1, DDQUOTIENT(%a6)     2370         mov.w           %d1, DDQUOTIENT(%a6)
2371         clr.l           %d1                      2371         clr.l           %d1
2372         swap            %d5                      2372         swap            %d5
2373         swap            %d6                      2373         swap            %d6
2374         mov.w           %d6, %d5                 2374         mov.w           %d6, %d5
2375         clr.w           %d6                      2375         clr.w           %d6
2376         st              DDSECOND(%a6)            2376         st              DDSECOND(%a6)           # second digit
2377         bra.w           ddnormalized             2377         bra.w           ddnormalized
2378 ddremain:                                        2378 ddremain:
2379 # add 2nd word to quotient, get the remainder    2379 # add 2nd word to quotient, get the remainder.
2380         mov.w           %d1, DDQUOTIENT+2(%a6    2380         mov.w           %d1, DDQUOTIENT+2(%a6)
2381 # shift down one word/digit to renormalize re    2381 # shift down one word/digit to renormalize remainder.
2382         mov.w           %d5, %d6                 2382         mov.w           %d5, %d6
2383         swap            %d6                      2383         swap            %d6
2384         swap            %d5                      2384         swap            %d5
2385         mov.l           DDNORMAL(%a6), %d7       2385         mov.l           DDNORMAL(%a6), %d7      # get norm shift count
2386         beq.b           ddrn                     2386         beq.b           ddrn
2387         subq.l          &0x1, %d7                2387         subq.l          &0x1, %d7               # set for loop count
2388 ddnlp:                                           2388 ddnlp:
2389         lsr.l           &0x1, %d5                2389         lsr.l           &0x1, %d5               # shift into %d6
2390         roxr.l          &0x1, %d6                2390         roxr.l          &0x1, %d6
2391         dbf             %d7, ddnlp               2391         dbf             %d7, ddnlp
2392 ddrn:                                            2392 ddrn:
2393         mov.l           %d6, %d5                 2393         mov.l           %d6, %d5                # remainder
2394         mov.l           DDQUOTIENT(%a6), %d6     2394         mov.l           DDQUOTIENT(%a6), %d6    # quotient
2395                                                  2395 
2396         rts                                      2396         rts
2397 dmm2:                                            2397 dmm2:
2398 # factors for the 32X32->64 multiplication ar    2398 # factors for the 32X32->64 multiplication are in %d5 and %d6.
2399 # returns 64 bit result in %d5 (hi) %d6(lo).     2399 # returns 64 bit result in %d5 (hi) %d6(lo).
2400 # destroys %d2,%d3,%d4.                          2400 # destroys %d2,%d3,%d4.
2401                                                  2401 
2402 # multiply hi,lo words of each factor to get     2402 # multiply hi,lo words of each factor to get 4 intermediate products
2403         mov.l           %d6, %d2                 2403         mov.l           %d6, %d2
2404         mov.l           %d6, %d3                 2404         mov.l           %d6, %d3
2405         mov.l           %d5, %d4                 2405         mov.l           %d5, %d4
2406         swap            %d3                      2406         swap            %d3
2407         swap            %d4                      2407         swap            %d4
2408         mulu.w          %d5, %d6                 2408         mulu.w          %d5, %d6                # %d6 <- lsw*lsw
2409         mulu.w          %d3, %d5                 2409         mulu.w          %d3, %d5                # %d5 <- msw-dest*lsw-source
2410         mulu.w          %d4, %d2                 2410         mulu.w          %d4, %d2                # %d2 <- msw-source*lsw-dest
2411         mulu.w          %d4, %d3                 2411         mulu.w          %d4, %d3                # %d3 <- msw*msw
2412 # now use swap and addx to consolidate to two    2412 # now use swap and addx to consolidate to two longwords
2413         clr.l           %d4                      2413         clr.l           %d4
2414         swap            %d6                      2414         swap            %d6
2415         add.w           %d5, %d6                 2415         add.w           %d5, %d6                # add msw of l*l to lsw of m*l product
2416         addx.w          %d4, %d3                 2416         addx.w          %d4, %d3                # add any carry to m*m product
2417         add.w           %d2, %d6                 2417         add.w           %d2, %d6                # add in lsw of other m*l product
2418         addx.w          %d4, %d3                 2418         addx.w          %d4, %d3                # add any carry to m*m product
2419         swap            %d6                      2419         swap            %d6                     # %d6 is low 32 bits of final product
2420         clr.w           %d5                      2420         clr.w           %d5
2421         clr.w           %d2                      2421         clr.w           %d2                     # lsw of two mixed products used,
2422         swap            %d5                      2422         swap            %d5                     # now use msws of longwords
2423         swap            %d2                      2423         swap            %d2
2424         add.l           %d2, %d5                 2424         add.l           %d2, %d5
2425         add.l           %d3, %d5                 2425         add.l           %d3, %d5                # %d5 now ms 32 bits of final product
2426         rts                                      2426         rts
2427                                                  2427 
2428 ##########                                       2428 ##########
2429 dcontrolmodel_s:                                 2429 dcontrolmodel_s:
2430         movq.l          &LONG,%d0                2430         movq.l          &LONG,%d0
2431         bsr.l           _calc_ea                 2431         bsr.l           _calc_ea                # calc <ea>
2432                                                  2432 
2433         cmpi.b          SPCOND_FLG(%a6),&imme    2433         cmpi.b          SPCOND_FLG(%a6),&immed_flg # immediate addressing mode?
2434         beq.b           dimmed                   2434         beq.b           dimmed                  # yes
2435                                                  2435 
2436         mov.l           %a0,%a2                  2436         mov.l           %a0,%a2
2437         bsr.l           _dmem_read_long          2437         bsr.l           _dmem_read_long         # fetch divisor from <ea>
2438                                                  2438 
2439         tst.l           %d1                      2439         tst.l           %d1                     # dfetch error?
2440         bne.b           div64_err                2440         bne.b           div64_err               # yes
2441                                                  2441 
2442         mov.l           %d0, %d7                 2442         mov.l           %d0, %d7
2443         bra.w           dgotsrcl                 2443         bra.w           dgotsrcl
2444                                                  2444 
2445 # we have to split out immediate data here be    2445 # we have to split out immediate data here because it must be read using
2446 # imem_read() instead of dmem_read(). this be    2446 # imem_read() instead of dmem_read(). this becomes especially important
2447 # if the fetch runs into some deadly fault.      2447 # if the fetch runs into some deadly fault.
2448 dimmed:                                          2448 dimmed:
2449         addq.l          &0x4,EXC_EXTWPTR(%a6)    2449         addq.l          &0x4,EXC_EXTWPTR(%a6)
2450         bsr.l           _imem_read_long          2450         bsr.l           _imem_read_long         # read immediate value
2451                                                  2451 
2452         tst.l           %d1                      2452         tst.l           %d1                     # ifetch error?
2453         bne.l           isp_iacc                 2453         bne.l           isp_iacc                # yes
2454                                                  2454 
2455         mov.l           %d0,%d7                  2455         mov.l           %d0,%d7
2456         bra.w           dgotsrcl                 2456         bra.w           dgotsrcl
2457                                                  2457 
2458 ##########                                       2458 ##########
2459                                                  2459 
2460 # if dmem_read_long() returns a fail message     2460 # if dmem_read_long() returns a fail message in d1, the package
2461 # must create an access error frame. here, we    2461 # must create an access error frame. here, we pass a skeleton fslw
2462 # and the failing address to the routine that    2462 # and the failing address to the routine that creates the new frame.
2463 # also, we call isp_restore in case the effec    2463 # also, we call isp_restore in case the effective addressing mode was
2464 # (an)+ or -(an) in which case the previous "    2464 # (an)+ or -(an) in which case the previous "an" value must be restored.
2465 # FSLW:                                          2465 # FSLW:
2466 #       read = true                              2466 #       read = true
2467 #       size = longword                          2467 #       size = longword
2468 #       TM = data                                2468 #       TM = data
2469 #       software emulation error = true          2469 #       software emulation error = true
2470 div64_err:                                       2470 div64_err:
2471         bsr.l           isp_restore              2471         bsr.l           isp_restore             # restore addr reg
2472         mov.l           %a2,%a0                  2472         mov.l           %a2,%a0                 # pass failing address
2473         mov.l           &0x01010001,%d0          2473         mov.l           &0x01010001,%d0         # pass fslw
2474         bra.l           isp_dacc                 2474         bra.l           isp_dacc
2475                                                  2475 
2476 #############################################    2476 #########################################################################
2477 # XDEF **************************************    2477 # XDEF **************************************************************** #
2478 #       _mul64(): routine to emulate mul{u,s}    2478 #       _mul64(): routine to emulate mul{u,s}.l <ea>,Dh:Dl 32x32->64    #
2479 #                                                2479 #                                                                       #
2480 # XREF **************************************    2480 # XREF **************************************************************** #
2481 #       _calc_ea() - calculate effective addr    2481 #       _calc_ea() - calculate effective address                        #
2482 #       isp_iacc() - handle instruction acces    2482 #       isp_iacc() - handle instruction access error exception          #
2483 #       isp_dacc() - handle data access error    2483 #       isp_dacc() - handle data access error exception                 #
2484 #       isp_restore() - restore An on access     2484 #       isp_restore() - restore An on access error w/ -() or ()+        #
2485 #                                                2485 #                                                                       #
2486 # INPUT *************************************    2486 # INPUT *************************************************************** #
2487 #       none                                     2487 #       none                                                            #
2488 #                                                2488 #                                                                       #
2489 # OUTPUT ************************************    2489 # OUTPUT ************************************************************** #
2490 #       If exiting through isp_dacc...           2490 #       If exiting through isp_dacc...                                  #
2491 #               a0 = failing address             2491 #               a0 = failing address                                    #
2492 #               d0 = FSLW                        2492 #               d0 = FSLW                                               #
2493 #       else                                     2493 #       else                                                            #
2494 #               none                             2494 #               none                                                    #
2495 #                                                2495 #                                                                       #
2496 # ALGORITHM *********************************    2496 # ALGORITHM *********************************************************** #
2497 #       First, decode the operand location. I    2497 #       First, decode the operand location. If it's in Dn, fetch from   #
2498 # the stack. If it's in memory, use _calc_ea(    2498 # the stack. If it's in memory, use _calc_ea() to calculate the         #
2499 # effective address. Use _dmem_read_long() to    2499 # effective address. Use _dmem_read_long() to fetch at that address.    #
2500 # Unless the operand is immediate data. Then     2500 # Unless the operand is immediate data. Then use _imem_read_long().     #
2501 # Send failures to isp_dacc() or isp_iacc() a    2501 # Send failures to isp_dacc() or isp_iacc() as appropriate.             #
2502 #       If the operands are signed, make them    2502 #       If the operands are signed, make them unsigned and save the     #
2503 # sign info for later. Perform the multiplica    2503 # sign info for later. Perform the multiplication using 16x16->32       #
2504 # unsigned multiplies and "add" instructions.    2504 # unsigned multiplies and "add" instructions. Store the high and low    #
2505 # portions of the result in the appropriate d    2505 # portions of the result in the appropriate data registers on the       #
2506 # stack. Calculate the condition codes, also.    2506 # stack. Calculate the condition codes, also.                           #
2507 #                                                2507 #                                                                       #
2508 #############################################    2508 #########################################################################
2509                                                  2509 
2510 #############                                    2510 #############
2511 # mul(u,s)l #                                    2511 # mul(u,s)l #
2512 #############                                    2512 #############
2513         global          _mul64                   2513         global          _mul64
2514 _mul64:                                          2514 _mul64:
2515         mov.b           EXC_OPWORD+1(%a6), %d    2515         mov.b           EXC_OPWORD+1(%a6), %d0  # extract src {mode,reg}
2516         cmpi.b          %d0, &0x7                2516         cmpi.b          %d0, &0x7               # is src mode Dn or other?
2517         bgt.w           mul64_memop              2517         bgt.w           mul64_memop             # src is in memory
2518                                                  2518 
2519 # multiplier operand in the data register fil    2519 # multiplier operand in the data register file.
2520 # must extract the register number and fetch     2520 # must extract the register number and fetch the operand from the stack.
2521 mul64_regop:                                     2521 mul64_regop:
2522         andi.w          &0x7, %d0                2522         andi.w          &0x7, %d0               # extract Dn
2523         mov.l           (EXC_DREGS,%a6,%d0.w*    2523         mov.l           (EXC_DREGS,%a6,%d0.w*4), %d3 # fetch multiplier
2524                                                  2524 
2525 # multiplier is in %d3. now, extract Dl and D    2525 # multiplier is in %d3. now, extract Dl and Dh fields and fetch the
2526 # multiplicand from the data register specifi    2526 # multiplicand from the data register specified by Dl.
2527 mul64_multiplicand:                              2527 mul64_multiplicand:
2528         mov.w           EXC_EXTWORD(%a6), %d2    2528         mov.w           EXC_EXTWORD(%a6), %d2   # fetch ext word
2529         clr.w           %d1                      2529         clr.w           %d1                     # clear Dh reg
2530         mov.b           %d2, %d1                 2530         mov.b           %d2, %d1                # grab Dh
2531         rol.w           &0x4, %d2                2531         rol.w           &0x4, %d2               # align Dl byte
2532         andi.w          &0x7, %d2                2532         andi.w          &0x7, %d2               # extract Dl
2533                                                  2533 
2534         mov.l           (EXC_DREGS,%a6,%d2.w*    2534         mov.l           (EXC_DREGS,%a6,%d2.w*4), %d4 # get multiplicand
2535                                                  2535 
2536 # check for the case of "zero" result early      2536 # check for the case of "zero" result early
2537         tst.l           %d4                      2537         tst.l           %d4                     # test multiplicand
2538         beq.w           mul64_zero               2538         beq.w           mul64_zero              # handle zero separately
2539         tst.l           %d3                      2539         tst.l           %d3                     # test multiplier
2540         beq.w           mul64_zero               2540         beq.w           mul64_zero              # handle zero separately
2541                                                  2541 
2542 # multiplier is in %d3 and multiplicand is in    2542 # multiplier is in %d3 and multiplicand is in %d4.
2543 # if the operation is to be signed, then the     2543 # if the operation is to be signed, then the operands are converted
2544 # to unsigned and the result sign is saved fo    2544 # to unsigned and the result sign is saved for the end.
2545         clr.b           EXC_TEMP(%a6)            2545         clr.b           EXC_TEMP(%a6)           # clear temp space
2546         btst            &0x3, EXC_EXTWORD(%a6    2546         btst            &0x3, EXC_EXTWORD(%a6)  # signed or unsigned?
2547         beq.b           mul64_alg                2547         beq.b           mul64_alg               # unsigned; skip sgn calc
2548                                                  2548 
2549         tst.l           %d3                      2549         tst.l           %d3                     # is multiplier negative?
2550         bge.b           mul64_chk_md_sgn         2550         bge.b           mul64_chk_md_sgn        # no
2551         neg.l           %d3                      2551         neg.l           %d3                     # make multiplier positive
2552         ori.b           &0x1, EXC_TEMP(%a6)      2552         ori.b           &0x1, EXC_TEMP(%a6)     # save multiplier sgn
2553                                                  2553 
2554 # the result sign is the exclusive or of the     2554 # the result sign is the exclusive or of the operand sign bits.
2555 mul64_chk_md_sgn:                                2555 mul64_chk_md_sgn:
2556         tst.l           %d4                      2556         tst.l           %d4                     # is multiplicand negative?
2557         bge.b           mul64_alg                2557         bge.b           mul64_alg               # no
2558         neg.l           %d4                      2558         neg.l           %d4                     # make multiplicand positive
2559         eori.b          &0x1, EXC_TEMP(%a6)      2559         eori.b          &0x1, EXC_TEMP(%a6)     # calculate correct sign
2560                                                  2560 
2561 #############################################    2561 #########################################################################
2562 #       63                         32            2562 #       63                         32                           0       #
2563 #       ----------------------------             2563 #       ----------------------------                                    #
2564 #       | hi(mplier) * hi(mplicand)|             2564 #       | hi(mplier) * hi(mplicand)|                                    #
2565 #       ----------------------------             2565 #       ----------------------------                                    #
2566 #                    ------------------------    2566 #                    -----------------------------                      #
2567 #                    | hi(mplier) * lo(mplica    2567 #                    | hi(mplier) * lo(mplicand) |                      #
2568 #                    ------------------------    2568 #                    -----------------------------                      #
2569 #                    ------------------------    2569 #                    -----------------------------                      #
2570 #                    | lo(mplier) * hi(mplica    2570 #                    | lo(mplier) * hi(mplicand) |                      #
2571 #                    ------------------------    2571 #                    -----------------------------                      #
2572 #         |                        ----------    2572 #         |                        -----------------------------        #
2573 #       --|--                      | lo(mplie    2573 #       --|--                      | lo(mplier) * lo(mplicand) |        #
2574 #         |                        ----------    2574 #         |                        -----------------------------        #
2575 #       =====================================    2575 #       ========================================================        #
2576 #       -------------------------------------    2576 #       --------------------------------------------------------        #
2577 #       |       hi(result)         |        l    2577 #       |       hi(result)         |        lo(result)         |        #
2578 #       -------------------------------------    2578 #       --------------------------------------------------------        #
2579 #############################################    2579 #########################################################################
2580 mul64_alg:                                       2580 mul64_alg:
2581 # load temp registers with operands              2581 # load temp registers with operands
2582         mov.l           %d3, %d5                 2582         mov.l           %d3, %d5                # mr in %d5
2583         mov.l           %d3, %d6                 2583         mov.l           %d3, %d6                # mr in %d6
2584         mov.l           %d4, %d7                 2584         mov.l           %d4, %d7                # md in %d7
2585         swap            %d6                      2585         swap            %d6                     # hi(mr) in lo %d6
2586         swap            %d7                      2586         swap            %d7                     # hi(md) in lo %d7
2587                                                  2587 
2588 # complete necessary multiplies:                 2588 # complete necessary multiplies:
2589         mulu.w          %d4, %d3                 2589         mulu.w          %d4, %d3                # [1] lo(mr) * lo(md)
2590         mulu.w          %d6, %d4                 2590         mulu.w          %d6, %d4                # [2] hi(mr) * lo(md)
2591         mulu.w          %d7, %d5                 2591         mulu.w          %d7, %d5                # [3] lo(mr) * hi(md)
2592         mulu.w          %d7, %d6                 2592         mulu.w          %d7, %d6                # [4] hi(mr) * hi(md)
2593                                                  2593 
2594 # add lo portions of [2],[3] to hi portion of    2594 # add lo portions of [2],[3] to hi portion of [1].
2595 # add carries produced from these adds to [4]    2595 # add carries produced from these adds to [4].
2596 # lo([1]) is the final lo 16 bits of the resu    2596 # lo([1]) is the final lo 16 bits of the result.
2597         clr.l           %d7                      2597         clr.l           %d7                     # load %d7 w/ zero value
2598         swap            %d3                      2598         swap            %d3                     # hi([1]) <==> lo([1])
2599         add.w           %d4, %d3                 2599         add.w           %d4, %d3                # hi([1]) + lo([2])
2600         addx.l          %d7, %d6                 2600         addx.l          %d7, %d6                #    [4]  + carry
2601         add.w           %d5, %d3                 2601         add.w           %d5, %d3                # hi([1]) + lo([3])
2602         addx.l          %d7, %d6                 2602         addx.l          %d7, %d6                #    [4]  + carry
2603         swap            %d3                      2603         swap            %d3                     # lo([1]) <==> hi([1])
2604                                                  2604 
2605 # lo portions of [2],[3] have been added in t    2605 # lo portions of [2],[3] have been added in to final result.
2606 # now, clear lo, put hi in lo reg, and add to    2606 # now, clear lo, put hi in lo reg, and add to [4]
2607         clr.w           %d4                      2607         clr.w           %d4                     # clear lo([2])
2608         clr.w           %d5                      2608         clr.w           %d5                     # clear hi([3])
2609         swap            %d4                      2609         swap            %d4                     # hi([2]) in lo %d4
2610         swap            %d5                      2610         swap            %d5                     # hi([3]) in lo %d5
2611         add.l           %d5, %d4                 2611         add.l           %d5, %d4                #    [4]  + hi([2])
2612         add.l           %d6, %d4                 2612         add.l           %d6, %d4                #    [4]  + hi([3])
2613                                                  2613 
2614 # unsigned result is now in {%d4,%d3}            2614 # unsigned result is now in {%d4,%d3}
2615         tst.b           EXC_TEMP(%a6)            2615         tst.b           EXC_TEMP(%a6)           # should result be signed?
2616         beq.b           mul64_done               2616         beq.b           mul64_done              # no
2617                                                  2617 
2618 # result should be a signed negative number.     2618 # result should be a signed negative number.
2619 # compute 2's complement of the unsigned numb    2619 # compute 2's complement of the unsigned number:
2620 #   -negate all bits and add 1                   2620 #   -negate all bits and add 1
2621 mul64_neg:                                       2621 mul64_neg:
2622         not.l           %d3                      2622         not.l           %d3                     # negate lo(result) bits
2623         not.l           %d4                      2623         not.l           %d4                     # negate hi(result) bits
2624         addq.l          &1, %d3                  2624         addq.l          &1, %d3                 # add 1 to lo(result)
2625         addx.l          %d7, %d4                 2625         addx.l          %d7, %d4                # add carry to hi(result)
2626                                                  2626 
2627 # the result is saved to the register file.      2627 # the result is saved to the register file.
2628 # for '040 compatibility, if Dl == Dh then on    2628 # for '040 compatibility, if Dl == Dh then only the hi(result) is
2629 # saved. so, saving hi after lo accomplishes     2629 # saved. so, saving hi after lo accomplishes this without need to
2630 # check Dl,Dh equality.                          2630 # check Dl,Dh equality.
2631 mul64_done:                                      2631 mul64_done:
2632         mov.l           %d3, (EXC_DREGS,%a6,%    2632         mov.l           %d3, (EXC_DREGS,%a6,%d2.w*4) # save lo(result)
2633         mov.w           &0x0, %cc                2633         mov.w           &0x0, %cc
2634         mov.l           %d4, (EXC_DREGS,%a6,%    2634         mov.l           %d4, (EXC_DREGS,%a6,%d1.w*4) # save hi(result)
2635                                                  2635 
2636 # now, grab the condition codes. only one tha    2636 # now, grab the condition codes. only one that can be set is 'N'.
2637 # 'N' CAN be set if the operation is unsigned    2637 # 'N' CAN be set if the operation is unsigned if bit 63 is set.
2638         mov.w           %cc, %d7                 2638         mov.w           %cc, %d7                # fetch %ccr to see if 'N' set
2639         andi.b          &0x8, %d7                2639         andi.b          &0x8, %d7               # extract 'N' bit
2640                                                  2640 
2641 mul64_ccode_set:                                 2641 mul64_ccode_set:
2642         mov.b           EXC_CC+1(%a6), %d6       2642         mov.b           EXC_CC+1(%a6), %d6      # fetch previous %ccr
2643         andi.b          &0x10, %d6               2643         andi.b          &0x10, %d6              # all but 'X' bit changes
2644                                                  2644 
2645         or.b            %d7, %d6                 2645         or.b            %d7, %d6                # group 'X' and 'N'
2646         mov.b           %d6, EXC_CC+1(%a6)       2646         mov.b           %d6, EXC_CC+1(%a6)      # save new %ccr
2647                                                  2647 
2648         rts                                      2648         rts
2649                                                  2649 
2650 # one or both of the operands is zero so the     2650 # one or both of the operands is zero so the result is also zero.
2651 # save the zero result to the register file a    2651 # save the zero result to the register file and set the 'Z' ccode bit.
2652 mul64_zero:                                      2652 mul64_zero:
2653         clr.l           (EXC_DREGS,%a6,%d2.w*    2653         clr.l           (EXC_DREGS,%a6,%d2.w*4) # save lo(result)
2654         clr.l           (EXC_DREGS,%a6,%d1.w*    2654         clr.l           (EXC_DREGS,%a6,%d1.w*4) # save hi(result)
2655                                                  2655 
2656         movq.l          &0x4, %d7                2656         movq.l          &0x4, %d7               # set 'Z' ccode bit
2657         bra.b           mul64_ccode_set          2657         bra.b           mul64_ccode_set         # finish ccode set
2658                                                  2658 
2659 ##########                                       2659 ##########
2660                                                  2660 
2661 # multiplier operand is in memory at the effe    2661 # multiplier operand is in memory at the effective address.
2662 # must calculate the <ea> and go fetch the 32    2662 # must calculate the <ea> and go fetch the 32-bit operand.
2663 mul64_memop:                                     2663 mul64_memop:
2664         movq.l          &LONG, %d0               2664         movq.l          &LONG, %d0              # pass # of bytes
2665         bsr.l           _calc_ea                 2665         bsr.l           _calc_ea                # calculate <ea>
2666                                                  2666 
2667         cmpi.b          SPCOND_FLG(%a6),&imme    2667         cmpi.b          SPCOND_FLG(%a6),&immed_flg # immediate addressing mode?
2668         beq.b           mul64_immed              2668         beq.b           mul64_immed             # yes
2669                                                  2669 
2670         mov.l           %a0,%a2                  2670         mov.l           %a0,%a2
2671         bsr.l           _dmem_read_long          2671         bsr.l           _dmem_read_long         # fetch src from addr (%a0)
2672                                                  2672 
2673         tst.l           %d1                      2673         tst.l           %d1                     # dfetch error?
2674         bne.w           mul64_err                2674         bne.w           mul64_err               # yes
2675                                                  2675 
2676         mov.l           %d0, %d3                 2676         mov.l           %d0, %d3                # store multiplier in %d3
2677                                                  2677 
2678         bra.w           mul64_multiplicand       2678         bra.w           mul64_multiplicand
2679                                                  2679 
2680 # we have to split out immediate data here be    2680 # we have to split out immediate data here because it must be read using
2681 # imem_read() instead of dmem_read(). this be    2681 # imem_read() instead of dmem_read(). this becomes especially important
2682 # if the fetch runs into some deadly fault.      2682 # if the fetch runs into some deadly fault.
2683 mul64_immed:                                     2683 mul64_immed:
2684         addq.l          &0x4,EXC_EXTWPTR(%a6)    2684         addq.l          &0x4,EXC_EXTWPTR(%a6)
2685         bsr.l           _imem_read_long          2685         bsr.l           _imem_read_long         # read immediate value
2686                                                  2686 
2687         tst.l           %d1                      2687         tst.l           %d1                     # ifetch error?
2688         bne.l           isp_iacc                 2688         bne.l           isp_iacc                # yes
2689                                                  2689 
2690         mov.l           %d0,%d3                  2690         mov.l           %d0,%d3
2691         bra.w           mul64_multiplicand       2691         bra.w           mul64_multiplicand
2692                                                  2692 
2693 ##########                                       2693 ##########
2694                                                  2694 
2695 # if dmem_read_long() returns a fail message     2695 # if dmem_read_long() returns a fail message in d1, the package
2696 # must create an access error frame. here, we    2696 # must create an access error frame. here, we pass a skeleton fslw
2697 # and the failing address to the routine that    2697 # and the failing address to the routine that creates the new frame.
2698 # also, we call isp_restore in case the effec    2698 # also, we call isp_restore in case the effective addressing mode was
2699 # (an)+ or -(an) in which case the previous "    2699 # (an)+ or -(an) in which case the previous "an" value must be restored.
2700 # FSLW:                                          2700 # FSLW:
2701 #       read = true                              2701 #       read = true
2702 #       size = longword                          2702 #       size = longword
2703 #       TM = data                                2703 #       TM = data
2704 #       software emulation error = true          2704 #       software emulation error = true
2705 mul64_err:                                       2705 mul64_err:
2706         bsr.l           isp_restore              2706         bsr.l           isp_restore             # restore addr reg
2707         mov.l           %a2,%a0                  2707         mov.l           %a2,%a0                 # pass failing address
2708         mov.l           &0x01010001,%d0          2708         mov.l           &0x01010001,%d0         # pass fslw
2709         bra.l           isp_dacc                 2709         bra.l           isp_dacc
2710                                                  2710 
2711 #############################################    2711 #########################################################################
2712 # XDEF **************************************    2712 # XDEF **************************************************************** #
2713 #       _compandset2(): routine to emulate ca    2713 #       _compandset2(): routine to emulate cas2()                       #
2714 #                       (internal to package)    2714 #                       (internal to package)                           #
2715 #                                                2715 #                                                                       #
2716 #       _isp_cas2_finish(): store ccodes, sto    2716 #       _isp_cas2_finish(): store ccodes, store compare regs            #
2717 #                           (external to pack    2717 #                           (external to package)                       #
2718 #                                                2718 #                                                                       #
2719 # XREF **************************************    2719 # XREF **************************************************************** #
2720 #       _real_lock_page() - "callout" to lock    2720 #       _real_lock_page() - "callout" to lock op's page from page-outs  #
2721 #       _cas_terminate2() - access error exit    2721 #       _cas_terminate2() - access error exit                           #
2722 #       _real_cas2() - "callout" to core cas2    2722 #       _real_cas2() - "callout" to core cas2 emulation code            #
2723 #       _real_unlock_page() - "callout" to un    2723 #       _real_unlock_page() - "callout" to unlock page                  #
2724 #                                                2724 #                                                                       #
2725 # INPUT *************************************    2725 # INPUT *************************************************************** #
2726 # _compandset2():                                2726 # _compandset2():                                                       #
2727 #       d0 = instruction extension word          2727 #       d0 = instruction extension word                                 #
2728 #                                                2728 #                                                                       #
2729 # _isp_cas2_finish():                            2729 # _isp_cas2_finish():                                                   #
2730 #       see cas2 core emulation code             2730 #       see cas2 core emulation code                                    #
2731 #                                                2731 #                                                                       #
2732 # OUTPUT ************************************    2732 # OUTPUT ************************************************************** #
2733 # _compandset2():                                2733 # _compandset2():                                                       #
2734 #       see cas2 core emulation code             2734 #       see cas2 core emulation code                                    #
2735 #                                                2735 #                                                                       #
2736 # _isp_cas_finish():                             2736 # _isp_cas_finish():                                                    #
2737 #       None (register file or memroy changed    2737 #       None (register file or memroy changed as appropriate)           #
2738 #                                                2738 #                                                                       #
2739 # ALGORITHM *********************************    2739 # ALGORITHM *********************************************************** #
2740 # compandset2():                                 2740 # compandset2():                                                        #
2741 #       Decode the instruction and fetch the     2741 #       Decode the instruction and fetch the appropriate Update and     #
2742 # Compare operands. Then call the "callout" _    2742 # Compare operands. Then call the "callout" _real_lock_page() for each  #
2743 # memory operand address so that the operatin    2743 # memory operand address so that the operating system can keep these    #
2744 # pages from being paged out. If either _real    2744 # pages from being paged out. If either _real_lock_page() fails, exit   #
2745 # through _cas_terminate2(). Don't forget to     2745 # through _cas_terminate2(). Don't forget to unlock the 1st locked page #
2746 # using _real_unlock_paged() if the 2nd lock-    2746 # using _real_unlock_paged() if the 2nd lock-page fails.                #
2747 # Finally, branch to the core cas2 emulation     2747 # Finally, branch to the core cas2 emulation code by calling the        #
2748 # "callout" _real_cas2().                        2748 # "callout" _real_cas2().                                               #
2749 #                                                2749 #                                                                       #
2750 # _isp_cas2_finish():                            2750 # _isp_cas2_finish():                                                   #
2751 #       Re-perform the comparison so we can d    2751 #       Re-perform the comparison so we can determine the condition     #
2752 # codes which were too much trouble to keep a    2752 # codes which were too much trouble to keep around during the locked    #
2753 # emulation. Then unlock each operands page b    2753 # emulation. Then unlock each operands page by calling the "callout"    #
2754 # _real_unlock_page().                           2754 # _real_unlock_page().                                                  #
2755 #                                                2755 #                                                                       #
2756 #############################################    2756 #########################################################################
2757                                                  2757 
2758 set ADDR1,      EXC_TEMP+0xc                     2758 set ADDR1,      EXC_TEMP+0xc
2759 set ADDR2,      EXC_TEMP+0x0                     2759 set ADDR2,      EXC_TEMP+0x0
2760 set DC2,        EXC_TEMP+0xa                     2760 set DC2,        EXC_TEMP+0xa
2761 set DC1,        EXC_TEMP+0x8                     2761 set DC1,        EXC_TEMP+0x8
2762                                                  2762 
2763         global          _compandset2             2763         global          _compandset2
2764 _compandset2:                                    2764 _compandset2:
2765         mov.l           %d0,EXC_TEMP+0x4(%a6)    2765         mov.l           %d0,EXC_TEMP+0x4(%a6)           # store for possible restart
2766         mov.l           %d0,%d1                  2766         mov.l           %d0,%d1                 # extension word in d0
2767                                                  2767 
2768         rol.w           &0x4,%d0                 2768         rol.w           &0x4,%d0
2769         andi.w          &0xf,%d0                 2769         andi.w          &0xf,%d0                # extract Rn2
2770         mov.l           (EXC_DREGS,%a6,%d0.w*    2770         mov.l           (EXC_DREGS,%a6,%d0.w*4),%a1 # fetch ADDR2
2771         mov.l           %a1,ADDR2(%a6)           2771         mov.l           %a1,ADDR2(%a6)
2772                                                  2772 
2773         mov.l           %d1,%d0                  2773         mov.l           %d1,%d0
2774                                                  2774 
2775         lsr.w           &0x6,%d1                 2775         lsr.w           &0x6,%d1
2776         andi.w          &0x7,%d1                 2776         andi.w          &0x7,%d1                # extract Du2
2777         mov.l           (EXC_DREGS,%a6,%d1.w*    2777         mov.l           (EXC_DREGS,%a6,%d1.w*4),%d5 # fetch Update2 Op
2778                                                  2778 
2779         andi.w          &0x7,%d0                 2779         andi.w          &0x7,%d0                # extract Dc2
2780         mov.l           (EXC_DREGS,%a6,%d0.w*    2780         mov.l           (EXC_DREGS,%a6,%d0.w*4),%d3 # fetch Compare2 Op
2781         mov.w           %d0,DC2(%a6)             2781         mov.w           %d0,DC2(%a6)
2782                                                  2782 
2783         mov.w           EXC_EXTWORD(%a6),%d0     2783         mov.w           EXC_EXTWORD(%a6),%d0
2784         mov.l           %d0,%d1                  2784         mov.l           %d0,%d1
2785                                                  2785 
2786         rol.w           &0x4,%d0                 2786         rol.w           &0x4,%d0
2787         andi.w          &0xf,%d0                 2787         andi.w          &0xf,%d0                # extract Rn1
2788         mov.l           (EXC_DREGS,%a6,%d0.w*    2788         mov.l           (EXC_DREGS,%a6,%d0.w*4),%a0 # fetch ADDR1
2789         mov.l           %a0,ADDR1(%a6)           2789         mov.l           %a0,ADDR1(%a6)
2790                                                  2790 
2791         mov.l           %d1,%d0                  2791         mov.l           %d1,%d0
2792                                                  2792 
2793         lsr.w           &0x6,%d1                 2793         lsr.w           &0x6,%d1
2794         andi.w          &0x7,%d1                 2794         andi.w          &0x7,%d1                # extract Du1
2795         mov.l           (EXC_DREGS,%a6,%d1.w*    2795         mov.l           (EXC_DREGS,%a6,%d1.w*4),%d4 # fetch Update1 Op
2796                                                  2796 
2797         andi.w          &0x7,%d0                 2797         andi.w          &0x7,%d0                # extract Dc1
2798         mov.l           (EXC_DREGS,%a6,%d0.w*    2798         mov.l           (EXC_DREGS,%a6,%d0.w*4),%d2 # fetch Compare1 Op
2799         mov.w           %d0,DC1(%a6)             2799         mov.w           %d0,DC1(%a6)
2800                                                  2800 
2801         btst            &0x1,EXC_OPWORD(%a6)     2801         btst            &0x1,EXC_OPWORD(%a6)    # word or long?
2802         sne             %d7                      2802         sne             %d7
2803                                                  2803 
2804         btst            &0x5,EXC_ISR(%a6)        2804         btst            &0x5,EXC_ISR(%a6)       # user or supervisor?
2805         sne             %d6                      2805         sne             %d6
2806                                                  2806 
2807         mov.l           %a0,%a2                  2807         mov.l           %a0,%a2
2808         mov.l           %a1,%a3                  2808         mov.l           %a1,%a3
2809                                                  2809 
2810         mov.l           %d7,%d1                  2810         mov.l           %d7,%d1                 # pass size
2811         mov.l           %d6,%d0                  2811         mov.l           %d6,%d0                 # pass mode
2812         bsr.l           _real_lock_page          2812         bsr.l           _real_lock_page         # lock page
2813         mov.l           %a2,%a0                  2813         mov.l           %a2,%a0
2814         tst.l           %d0                      2814         tst.l           %d0                     # error?
2815         bne.l           _cas_terminate2          2815         bne.l           _cas_terminate2         # yes
2816                                                  2816 
2817         mov.l           %d7,%d1                  2817         mov.l           %d7,%d1                 # pass size
2818         mov.l           %d6,%d0                  2818         mov.l           %d6,%d0                 # pass mode
2819         mov.l           %a3,%a0                  2819         mov.l           %a3,%a0                 # pass addr
2820         bsr.l           _real_lock_page          2820         bsr.l           _real_lock_page         # lock page
2821         mov.l           %a3,%a0                  2821         mov.l           %a3,%a0
2822         tst.l           %d0                      2822         tst.l           %d0                     # error?
2823         bne.b           cas_preterm              2823         bne.b           cas_preterm             # yes
2824                                                  2824 
2825         mov.l           %a2,%a0                  2825         mov.l           %a2,%a0
2826         mov.l           %a3,%a1                  2826         mov.l           %a3,%a1
2827                                                  2827 
2828         bra.l           _real_cas2               2828         bra.l           _real_cas2
2829                                                  2829 
2830 # if the 2nd lock attempt fails, then we must    2830 # if the 2nd lock attempt fails, then we must still unlock the
2831 # first page(s).                                 2831 # first page(s).
2832 cas_preterm:                                     2832 cas_preterm:
2833         mov.l           %d0,-(%sp)               2833         mov.l           %d0,-(%sp)              # save FSLW
2834         mov.l           %d7,%d1                  2834         mov.l           %d7,%d1                 # pass size
2835         mov.l           %d6,%d0                  2835         mov.l           %d6,%d0                 # pass mode
2836         mov.l           %a2,%a0                  2836         mov.l           %a2,%a0                 # pass ADDR1
2837         bsr.l           _real_unlock_page        2837         bsr.l           _real_unlock_page       # unlock first page(s)
2838         mov.l           (%sp)+,%d0               2838         mov.l           (%sp)+,%d0              # restore FSLW
2839         mov.l           %a3,%a0                  2839         mov.l           %a3,%a0                 # pass failing addr
2840         bra.l           _cas_terminate2          2840         bra.l           _cas_terminate2
2841                                                  2841 
2842 #############################################    2842 #############################################################
2843                                                  2843 
2844         global          _isp_cas2_finish         2844         global          _isp_cas2_finish
2845 _isp_cas2_finish:                                2845 _isp_cas2_finish:
2846         btst            &0x1,EXC_OPWORD(%a6)     2846         btst            &0x1,EXC_OPWORD(%a6)
2847         bne.b           cas2_finish_l            2847         bne.b           cas2_finish_l
2848                                                  2848 
2849         mov.w           EXC_CC(%a6),%cc          2849         mov.w           EXC_CC(%a6),%cc         # load old ccodes
2850         cmp.w           %d0,%d2                  2850         cmp.w           %d0,%d2
2851         bne.b           cas2_finish_w_save       2851         bne.b           cas2_finish_w_save
2852         cmp.w           %d1,%d3                  2852         cmp.w           %d1,%d3
2853 cas2_finish_w_save:                              2853 cas2_finish_w_save:
2854         mov.w           %cc,EXC_CC(%a6)          2854         mov.w           %cc,EXC_CC(%a6)         # save new ccodes
2855                                                  2855 
2856         tst.b           %d4                      2856         tst.b           %d4                     # update compare reg?
2857         bne.b           cas2_finish_w_done       2857         bne.b           cas2_finish_w_done      # no
2858                                                  2858 
2859         mov.w           DC2(%a6),%d3             2859         mov.w           DC2(%a6),%d3            # fetch Dc2
2860         mov.w           %d1,(2+EXC_DREGS,%a6,    2860         mov.w           %d1,(2+EXC_DREGS,%a6,%d3.w*4) # store new Compare2 Op
2861                                                  2861 
2862         mov.w           DC1(%a6),%d2             2862         mov.w           DC1(%a6),%d2            # fetch Dc1
2863         mov.w           %d0,(2+EXC_DREGS,%a6,    2863         mov.w           %d0,(2+EXC_DREGS,%a6,%d2.w*4) # store new Compare1 Op
2864                                                  2864 
2865 cas2_finish_w_done:                              2865 cas2_finish_w_done:
2866         btst            &0x5,EXC_ISR(%a6)        2866         btst            &0x5,EXC_ISR(%a6)
2867         sne             %d2                      2867         sne             %d2
2868         mov.l           %d2,%d0                  2868         mov.l           %d2,%d0                 # pass mode
2869         sf              %d1                      2869         sf              %d1                     # pass size
2870         mov.l           ADDR1(%a6),%a0           2870         mov.l           ADDR1(%a6),%a0          # pass ADDR1
2871         bsr.l           _real_unlock_page        2871         bsr.l           _real_unlock_page       # unlock page
2872                                                  2872 
2873         mov.l           %d2,%d0                  2873         mov.l           %d2,%d0                 # pass mode
2874         sf              %d1                      2874         sf              %d1                     # pass size
2875         mov.l           ADDR2(%a6),%a0           2875         mov.l           ADDR2(%a6),%a0          # pass ADDR2
2876         bsr.l           _real_unlock_page        2876         bsr.l           _real_unlock_page       # unlock page
2877         rts                                      2877         rts
2878                                                  2878 
2879 cas2_finish_l:                                   2879 cas2_finish_l:
2880         mov.w           EXC_CC(%a6),%cc          2880         mov.w           EXC_CC(%a6),%cc         # load old ccodes
2881         cmp.l           %d0,%d2                  2881         cmp.l           %d0,%d2
2882         bne.b           cas2_finish_l_save       2882         bne.b           cas2_finish_l_save
2883         cmp.l           %d1,%d3                  2883         cmp.l           %d1,%d3
2884 cas2_finish_l_save:                              2884 cas2_finish_l_save:
2885         mov.w           %cc,EXC_CC(%a6)          2885         mov.w           %cc,EXC_CC(%a6)         # save new ccodes
2886                                                  2886 
2887         tst.b           %d4                      2887         tst.b           %d4                     # update compare reg?
2888         bne.b           cas2_finish_l_done       2888         bne.b           cas2_finish_l_done      # no
2889                                                  2889 
2890         mov.w           DC2(%a6),%d3             2890         mov.w           DC2(%a6),%d3            # fetch Dc2
2891         mov.l           %d1,(EXC_DREGS,%a6,%d    2891         mov.l           %d1,(EXC_DREGS,%a6,%d3.w*4) # store new Compare2 Op
2892                                                  2892 
2893         mov.w           DC1(%a6),%d2             2893         mov.w           DC1(%a6),%d2            # fetch Dc1
2894         mov.l           %d0,(EXC_DREGS,%a6,%d    2894         mov.l           %d0,(EXC_DREGS,%a6,%d2.w*4) # store new Compare1 Op
2895                                                  2895 
2896 cas2_finish_l_done:                              2896 cas2_finish_l_done:
2897         btst            &0x5,EXC_ISR(%a6)        2897         btst            &0x5,EXC_ISR(%a6)
2898         sne             %d2                      2898         sne             %d2
2899         mov.l           %d2,%d0                  2899         mov.l           %d2,%d0                 # pass mode
2900         st              %d1                      2900         st              %d1                     # pass size
2901         mov.l           ADDR1(%a6),%a0           2901         mov.l           ADDR1(%a6),%a0          # pass ADDR1
2902         bsr.l           _real_unlock_page        2902         bsr.l           _real_unlock_page       # unlock page
2903                                                  2903 
2904         mov.l           %d2,%d0                  2904         mov.l           %d2,%d0                 # pass mode
2905         st              %d1                      2905         st              %d1                     # pass size
2906         mov.l           ADDR2(%a6),%a0           2906         mov.l           ADDR2(%a6),%a0          # pass ADDR2
2907         bsr.l           _real_unlock_page        2907         bsr.l           _real_unlock_page       # unlock page
2908         rts                                      2908         rts
2909                                                  2909 
2910 ########                                         2910 ########
2911         global          cr_cas2                  2911         global          cr_cas2
2912 cr_cas2:                                         2912 cr_cas2:
2913         mov.l           EXC_TEMP+0x4(%a6),%d0    2913         mov.l           EXC_TEMP+0x4(%a6),%d0
2914         bra.w           _compandset2             2914         bra.w           _compandset2
2915                                                  2915 
2916 #############################################    2916 #########################################################################
2917 # XDEF **************************************    2917 # XDEF **************************************************************** #
2918 #       _compandset(): routine to emulate cas    2918 #       _compandset(): routine to emulate cas w/ misaligned <ea>        #
2919 #                      (internal to package)     2919 #                      (internal to package)                            #
2920 #       _isp_cas_finish(): routine called whe    2920 #       _isp_cas_finish(): routine called when cas emulation completes  #
2921 #                          (external and inte    2921 #                          (external and internal to package)           #
2922 #       _isp_cas_restart(): restart cas emula    2922 #       _isp_cas_restart(): restart cas emulation after a fault         #
2923 #                           (external to pack    2923 #                           (external to package)                       #
2924 #       _isp_cas_terminate(): create access e    2924 #       _isp_cas_terminate(): create access error stack frame on fault  #
2925 #                             (external and i    2925 #                             (external and internal to package)        #
2926 #       _isp_cas_inrange(): checks whether in    2926 #       _isp_cas_inrange(): checks whether instr addess is within range #
2927 #                           of core cas/cas2e    2927 #                           of core cas/cas2emulation code              #
2928 #                           (external to pack    2928 #                           (external to package)                       #
2929 #                                                2929 #                                                                       #
2930 # XREF **************************************    2930 # XREF **************************************************************** #
2931 #       _calc_ea(): calculate effective addre    2931 #       _calc_ea(): calculate effective address                         #
2932 #                                                2932 #                                                                       #
2933 # INPUT *************************************    2933 # INPUT *************************************************************** #
2934 # compandset():                                  2934 # compandset():                                                         #
2935 #       none                                     2935 #       none                                                            #
2936 # _isp_cas_restart():                            2936 # _isp_cas_restart():                                                   #
2937 #       d6 = previous sfc/dfc                    2937 #       d6 = previous sfc/dfc                                           #
2938 # _isp_cas_finish():                             2938 # _isp_cas_finish():                                                    #
2939 # _isp_cas_terminate():                          2939 # _isp_cas_terminate():                                                 #
2940 #       a0 = failing address                     2940 #       a0 = failing address                                            #
2941 #       d0 = FSLW                                2941 #       d0 = FSLW                                                       #
2942 #       d6 = previous sfc/dfc                    2942 #       d6 = previous sfc/dfc                                           #
2943 # _isp_cas_inrange():                            2943 # _isp_cas_inrange():                                                   #
2944 #       a0 = instruction address to be checke    2944 #       a0 = instruction address to be checked                          #
2945 #                                                2945 #                                                                       #
2946 # OUTPUT ************************************    2946 # OUTPUT ************************************************************** #
2947 # compandset():                                  2947 # compandset():                                                         #
2948 #               none                             2948 #               none                                                    #
2949 # _isp_cas_restart():                            2949 # _isp_cas_restart():                                                   #
2950 #       a0 = effective address                   2950 #       a0 = effective address                                          #
2951 #       d7 = word or longword flag               2951 #       d7 = word or longword flag                                      #
2952 # _isp_cas_finish():                             2952 # _isp_cas_finish():                                                    #
2953 #       a0 = effective address                   2953 #       a0 = effective address                                          #
2954 # _isp_cas_terminate():                          2954 # _isp_cas_terminate():                                                 #
2955 #       initial register set before emulation    2955 #       initial register set before emulation exception                 #
2956 # _isp_cas_inrange():                            2956 # _isp_cas_inrange():                                                   #
2957 #       d0 = 0 => in range; -1 => out of rang    2957 #       d0 = 0 => in range; -1 => out of range                          #
2958 #                                                2958 #                                                                       #
2959 # ALGORITHM *********************************    2959 # ALGORITHM *********************************************************** #
2960 #                                                2960 #                                                                       #
2961 # compandset():                                  2961 # compandset():                                                         #
2962 #       First, calculate the effective addres    2962 #       First, calculate the effective address. Then, decode the        #
2963 # instruction word and fetch the "compare" (D    2963 # instruction word and fetch the "compare" (DC) and "update" (Du)       #
2964 # operands.                                      2964 # operands.                                                             #
2965 #       Next, call the external routine _real    2965 #       Next, call the external routine _real_lock_page() so that the   #
2966 # operating system can keep this page from be    2966 # operating system can keep this page from being paged out while we're  #
2967 # in this routine. If this call fails, jump t    2967 # in this routine. If this call fails, jump to _cas_terminate2().       #
2968 #       The routine then branches to _real_ca    2968 #       The routine then branches to _real_cas(). This external routine #
2969 # that actually emulates cas can be supplied     2969 # that actually emulates cas can be supplied by the external os or      #
2970 # made to point directly back into the 060ISP    2970 # made to point directly back into the 060ISP which has a routine for   #
2971 # this purpose.                                  2971 # this purpose.                                                         #
2972 #                                                2972 #                                                                       #
2973 # _isp_cas_finish():                             2973 # _isp_cas_finish():                                                    #
2974 #       Either way, after emulation, the pack    2974 #       Either way, after emulation, the package is re-entered at       #
2975 # _isp_cas_finish(). This routine re-compares    2975 # _isp_cas_finish(). This routine re-compares the operands in order to  #
2976 # set the condition codes. Finally, these rou    2976 # set the condition codes. Finally, these routines will call            #
2977 # _real_unlock_page() in order to unlock the     2977 # _real_unlock_page() in order to unlock the pages that were previously #
2978 # locked.                                        2978 # locked.                                                               #
2979 #                                                2979 #                                                                       #
2980 # _isp_cas_restart():                            2980 # _isp_cas_restart():                                                   #
2981 #       This routine can be entered from an a    2981 #       This routine can be entered from an access error handler where  #
2982 # the emulation sequence should be re-started    2982 # the emulation sequence should be re-started from the beginning.       #
2983 #                                                2983 #                                                                       #
2984 # _isp_cas_terminate():                          2984 # _isp_cas_terminate():                                                 #
2985 #       This routine can be entered from an a    2985 #       This routine can be entered from an access error handler where  #
2986 # an emulation operand access failed and the     2986 # an emulation operand access failed and the operating system would     #
2987 # like an access error stack frame created in    2987 # like an access error stack frame created instead of the current       #
2988 # unimplemented integer instruction frame.       2988 # unimplemented integer instruction frame.                              #
2989 #       Also, the package enters here if a ca    2989 #       Also, the package enters here if a call to _real_lock_page()    #
2990 # fails.                                         2990 # fails.                                                                #
2991 #                                                2991 #                                                                       #
2992 # _isp_cas_inrange():                            2992 # _isp_cas_inrange():                                                   #
2993 #       Checks to see whether the instruction    2993 #       Checks to see whether the instruction address passed to it in   #
2994 # a0 is within the software package cas/cas2     2994 # a0 is within the software package cas/cas2 emulation routines. This   #
2995 # can be helpful for an operating system to d    2995 # can be helpful for an operating system to determine whether an access #
2996 # error during emulation was due to a cas/cas    2996 # error during emulation was due to a cas/cas2 emulation access.        #
2997 #                                                2997 #                                                                       #
2998 #############################################    2998 #########################################################################
2999                                                  2999 
3000 set DC,         EXC_TEMP+0x8                     3000 set DC,         EXC_TEMP+0x8
3001 set ADDR,       EXC_TEMP+0x4                     3001 set ADDR,       EXC_TEMP+0x4
3002                                                  3002 
3003         global          _compandset              3003         global          _compandset
3004 _compandset:                                     3004 _compandset:
3005         btst            &0x1,EXC_OPWORD(%a6)     3005         btst            &0x1,EXC_OPWORD(%a6)    # word or long operation?
3006         bne.b           compandsetl              3006         bne.b           compandsetl             # long
3007                                                  3007 
3008 compandsetw:                                     3008 compandsetw:
3009         movq.l          &0x2,%d0                 3009         movq.l          &0x2,%d0                # size = 2 bytes
3010         bsr.l           _calc_ea                 3010         bsr.l           _calc_ea                # a0 = calculated <ea>
3011         mov.l           %a0,ADDR(%a6)            3011         mov.l           %a0,ADDR(%a6)           # save <ea> for possible restart
3012         sf              %d7                      3012         sf              %d7                     # clear d7 for word size
3013         bra.b           compandsetfetch          3013         bra.b           compandsetfetch
3014                                                  3014 
3015 compandsetl:                                     3015 compandsetl:
3016         movq.l          &0x4,%d0                 3016         movq.l          &0x4,%d0                # size = 4 bytes
3017         bsr.l           _calc_ea                 3017         bsr.l           _calc_ea                # a0 = calculated <ea>
3018         mov.l           %a0,ADDR(%a6)            3018         mov.l           %a0,ADDR(%a6)           # save <ea> for possible restart
3019         st              %d7                      3019         st              %d7                     # set d7 for longword size
3020                                                  3020 
3021 compandsetfetch:                                 3021 compandsetfetch:
3022         mov.w           EXC_EXTWORD(%a6),%d0     3022         mov.w           EXC_EXTWORD(%a6),%d0    # fetch cas extension word
3023         mov.l           %d0,%d1                  3023         mov.l           %d0,%d1                 # make a copy
3024                                                  3024 
3025         lsr.w           &0x6,%d0                 3025         lsr.w           &0x6,%d0
3026         andi.w          &0x7,%d0                 3026         andi.w          &0x7,%d0                # extract Du
3027         mov.l           (EXC_DREGS,%a6,%d0.w*    3027         mov.l           (EXC_DREGS,%a6,%d0.w*4),%d2 # get update operand
3028                                                  3028 
3029         andi.w          &0x7,%d1                 3029         andi.w          &0x7,%d1                # extract Dc
3030         mov.l           (EXC_DREGS,%a6,%d1.w*    3030         mov.l           (EXC_DREGS,%a6,%d1.w*4),%d4 # get compare operand
3031         mov.w           %d1,DC(%a6)              3031         mov.w           %d1,DC(%a6)             # save Dc
3032                                                  3032 
3033         btst            &0x5,EXC_ISR(%a6)        3033         btst            &0x5,EXC_ISR(%a6)       # which mode for exception?
3034         sne             %d6                      3034         sne             %d6                     # set on supervisor mode
3035                                                  3035 
3036         mov.l           %a0,%a2                  3036         mov.l           %a0,%a2                 # save temporarily
3037         mov.l           %d7,%d1                  3037         mov.l           %d7,%d1                 # pass size
3038         mov.l           %d6,%d0                  3038         mov.l           %d6,%d0                 # pass mode
3039         bsr.l           _real_lock_page          3039         bsr.l           _real_lock_page         # lock page
3040         tst.l           %d0                      3040         tst.l           %d0                     # did error occur?
3041         bne.w           _cas_terminate2          3041         bne.w           _cas_terminate2         # yes, clean up the mess
3042         mov.l           %a2,%a0                  3042         mov.l           %a2,%a0                 # pass addr in a0
3043                                                  3043 
3044         bra.l           _real_cas                3044         bra.l           _real_cas
3045                                                  3045 
3046 ########                                         3046 ########
3047         global          _isp_cas_finish          3047         global          _isp_cas_finish
3048 _isp_cas_finish:                                 3048 _isp_cas_finish:
3049         btst            &0x1,EXC_OPWORD(%a6)     3049         btst            &0x1,EXC_OPWORD(%a6)
3050         bne.b           cas_finish_l             3050         bne.b           cas_finish_l
3051                                                  3051 
3052 # just do the compare again since it's faster    3052 # just do the compare again since it's faster than saving the ccodes
3053 # from the locked routine...                     3053 # from the locked routine...
3054 cas_finish_w:                                    3054 cas_finish_w:
3055         mov.w           EXC_CC(%a6),%cc          3055         mov.w           EXC_CC(%a6),%cc         # restore cc
3056         cmp.w           %d0,%d4                  3056         cmp.w           %d0,%d4                 # do word compare
3057         mov.w           %cc,EXC_CC(%a6)          3057         mov.w           %cc,EXC_CC(%a6)         # save cc
3058                                                  3058 
3059         tst.b           %d1                      3059         tst.b           %d1                     # update compare reg?
3060         bne.b           cas_finish_w_done        3060         bne.b           cas_finish_w_done       # no
3061                                                  3061 
3062         mov.w           DC(%a6),%d3              3062         mov.w           DC(%a6),%d3
3063         mov.w           %d0,(EXC_DREGS+2,%a6,    3063         mov.w           %d0,(EXC_DREGS+2,%a6,%d3.w*4) # Dc = destination
3064                                                  3064 
3065 cas_finish_w_done:                               3065 cas_finish_w_done:
3066         mov.l           ADDR(%a6),%a0            3066         mov.l           ADDR(%a6),%a0           # pass addr
3067         sf              %d1                      3067         sf              %d1                     # pass size
3068         btst            &0x5,EXC_ISR(%a6)        3068         btst            &0x5,EXC_ISR(%a6)
3069         sne             %d0                      3069         sne             %d0                     # pass mode
3070         bsr.l           _real_unlock_page        3070         bsr.l           _real_unlock_page       # unlock page
3071         rts                                      3071         rts
3072                                                  3072 
3073 # just do the compare again since it's faster    3073 # just do the compare again since it's faster than saving the ccodes
3074 # from the locked routine...                     3074 # from the locked routine...
3075 cas_finish_l:                                    3075 cas_finish_l:
3076         mov.w           EXC_CC(%a6),%cc          3076         mov.w           EXC_CC(%a6),%cc         # restore cc
3077         cmp.l           %d0,%d4                  3077         cmp.l           %d0,%d4                 # do longword compare
3078         mov.w           %cc,EXC_CC(%a6)          3078         mov.w           %cc,EXC_CC(%a6)         # save cc
3079                                                  3079 
3080         tst.b           %d1                      3080         tst.b           %d1                     # update compare reg?
3081         bne.b           cas_finish_l_done        3081         bne.b           cas_finish_l_done       # no
3082                                                  3082 
3083         mov.w           DC(%a6),%d3              3083         mov.w           DC(%a6),%d3
3084         mov.l           %d0,(EXC_DREGS,%a6,%d    3084         mov.l           %d0,(EXC_DREGS,%a6,%d3.w*4) # Dc = destination
3085                                                  3085 
3086 cas_finish_l_done:                               3086 cas_finish_l_done:
3087         mov.l           ADDR(%a6),%a0            3087         mov.l           ADDR(%a6),%a0           # pass addr
3088         st              %d1                      3088         st              %d1                     # pass size
3089         btst            &0x5,EXC_ISR(%a6)        3089         btst            &0x5,EXC_ISR(%a6)
3090         sne             %d0                      3090         sne             %d0                     # pass mode
3091         bsr.l           _real_unlock_page        3091         bsr.l           _real_unlock_page       # unlock page
3092         rts                                      3092         rts
3093                                                  3093 
3094 ########                                         3094 ########
3095                                                  3095 
3096         global          _isp_cas_restart         3096         global          _isp_cas_restart
3097 _isp_cas_restart:                                3097 _isp_cas_restart:
3098         mov.l           %d6,%sfc                 3098         mov.l           %d6,%sfc                # restore previous sfc
3099         mov.l           %d6,%dfc                 3099         mov.l           %d6,%dfc                # restore previous dfc
3100                                                  3100 
3101         cmpi.b          EXC_OPWORD+1(%a6),&0x    3101         cmpi.b          EXC_OPWORD+1(%a6),&0xfc # cas or cas2?
3102         beq.l           cr_cas2                  3102         beq.l           cr_cas2                 # cas2
3103 cr_cas:                                          3103 cr_cas:
3104         mov.l           ADDR(%a6),%a0            3104         mov.l           ADDR(%a6),%a0           # load <ea>
3105         btst            &0x1,EXC_OPWORD(%a6)     3105         btst            &0x1,EXC_OPWORD(%a6)    # word or long operation?
3106         sne             %d7                      3106         sne             %d7                     # set d7 accordingly
3107         bra.w           compandsetfetch          3107         bra.w           compandsetfetch
3108                                                  3108 
3109 ########                                         3109 ########
3110                                                  3110 
3111 # At this stage, it would be nice if d0 held     3111 # At this stage, it would be nice if d0 held the FSLW.
3112         global          _isp_cas_terminate       3112         global          _isp_cas_terminate
3113 _isp_cas_terminate:                              3113 _isp_cas_terminate:
3114         mov.l           %d6,%sfc                 3114         mov.l           %d6,%sfc                # restore previous sfc
3115         mov.l           %d6,%dfc                 3115         mov.l           %d6,%dfc                # restore previous dfc
3116                                                  3116 
3117         global          _cas_terminate2          3117         global          _cas_terminate2
3118 _cas_terminate2:                                 3118 _cas_terminate2:
3119         mov.l           %a0,%a2                  3119         mov.l           %a0,%a2                 # copy failing addr to a2
3120                                                  3120 
3121         mov.l           %d0,-(%sp)               3121         mov.l           %d0,-(%sp)
3122         bsr.l           isp_restore              3122         bsr.l           isp_restore             # restore An (if ()+ or -())
3123         mov.l           (%sp)+,%d0               3123         mov.l           (%sp)+,%d0
3124                                                  3124 
3125         addq.l          &0x4,%sp                 3125         addq.l          &0x4,%sp                # remove sub return addr
3126         subq.l          &0x8,%sp                 3126         subq.l          &0x8,%sp                # make room for bigger stack
3127         subq.l          &0x8,%a6                 3127         subq.l          &0x8,%a6                # shift frame ptr down, too
3128         mov.l           &26,%d1                  3128         mov.l           &26,%d1                 # want to move 51 longwords
3129         lea             0x8(%sp),%a0             3129         lea             0x8(%sp),%a0            # get address of old stack
3130         lea             0x0(%sp),%a1             3130         lea             0x0(%sp),%a1            # get address of new stack
3131 cas_term_cont:                                   3131 cas_term_cont:
3132         mov.l           (%a0)+,(%a1)+            3132         mov.l           (%a0)+,(%a1)+           # move a longword
3133         dbra.w          %d1,cas_term_cont        3133         dbra.w          %d1,cas_term_cont       # keep going
3134                                                  3134 
3135         mov.w           &0x4008,EXC_IVOFF(%a6    3135         mov.w           &0x4008,EXC_IVOFF(%a6)  # put new stk fmt, voff
3136         mov.l           %a2,EXC_IVOFF+0x2(%a6    3136         mov.l           %a2,EXC_IVOFF+0x2(%a6)  # put faulting addr on stack
3137         mov.l           %d0,EXC_IVOFF+0x6(%a6    3137         mov.l           %d0,EXC_IVOFF+0x6(%a6)  # put FSLW on stack
3138         movm.l          EXC_DREGS(%a6),&0x3ff    3138         movm.l          EXC_DREGS(%a6),&0x3fff  # restore user regs
3139         unlk            %a6                      3139         unlk            %a6                     # unlink stack frame
3140         bra.l           _real_access             3140         bra.l           _real_access
3141                                                  3141 
3142 ########                                         3142 ########
3143                                                  3143 
3144         global          _isp_cas_inrange         3144         global          _isp_cas_inrange
3145 _isp_cas_inrange:                                3145 _isp_cas_inrange:
3146         clr.l           %d0                      3146         clr.l           %d0                     # clear return result
3147         lea             _CASHI(%pc),%a1          3147         lea             _CASHI(%pc),%a1         # load end of CAS core code
3148         cmp.l           %a1,%a0                  3148         cmp.l           %a1,%a0                 # is PC in range?
3149         blt.b           cin_no                   3149         blt.b           cin_no                  # no
3150         lea             _CASLO(%pc),%a1          3150         lea             _CASLO(%pc),%a1         # load begin of CAS core code
3151         cmp.l           %a0,%a1                  3151         cmp.l           %a0,%a1                 # is PC in range?
3152         blt.b           cin_no                   3152         blt.b           cin_no                  # no
3153         rts                                      3153         rts                                     # yes; return d0 = 0
3154 cin_no:                                          3154 cin_no:
3155         mov.l           &-0x1,%d0                3155         mov.l           &-0x1,%d0               # out of range; return d0 = -1
3156         rts                                      3156         rts
3157                                                  3157 
3158 #############################################    3158 #################################################################
3159 #############################################    3159 #################################################################
3160 #############################################    3160 #################################################################
3161 # This is the start of the cas and cas2 "core    3161 # This is the start of the cas and cas2 "core" emulation code.  #
3162 # This is the section that may need to be rep    3162 # This is the section that may need to be replaced by the host  #
3163 # OS if it is too operating system-specific.     3163 # OS if it is too operating system-specific.                    #
3164 # Please refer to the package documentation t    3164 # Please refer to the package documentation to see how to       #
3165 # "replace" this section, if necessary.          3165 # "replace" this section, if necessary.                         #
3166 #############################################    3166 #################################################################
3167 #############################################    3167 #################################################################
3168 #############################################    3168 #################################################################
3169                                                  3169 
3170 #       ######      ##      ######     ####      3170 #       ######      ##      ######     ####
3171 #       #          #  #     #         #    #     3171 #       #          #  #     #         #    #
3172 #       #         ######    ######        #      3172 #       #         ######    ######        #
3173 #       #         #    #         #      #        3173 #       #         #    #         #      #
3174 #       ######    #    #    ######    ######     3174 #       ######    #    #    ######    ######
3175                                                  3175 
3176 #############################################    3176 #########################################################################
3177 # XDEF **************************************    3177 # XDEF **************************************************************** #
3178 #       _isp_cas2(): "core" emulation code fo    3178 #       _isp_cas2(): "core" emulation code for the cas2 instruction     #
3179 #                                                3179 #                                                                       #
3180 # XREF **************************************    3180 # XREF **************************************************************** #
3181 #       _isp_cas2_finish() - only exit point     3181 #       _isp_cas2_finish() - only exit point for this emulation code;   #
3182 #                            do clean-up; cal    3182 #                            do clean-up; calculate ccodes; store       #
3183 #                            Compare Ops if a    3183 #                            Compare Ops if appropriate.                #
3184 #                                                3184 #                                                                       #
3185 # INPUT *************************************    3185 # INPUT *************************************************************** #
3186 #       *see chart below*                        3186 #       *see chart below*                                               #
3187 #                                                3187 #                                                                       #
3188 # OUTPUT ************************************    3188 # OUTPUT ************************************************************** #
3189 #       *see chart below*                        3189 #       *see chart below*                                               #
3190 #                                                3190 #                                                                       #
3191 # ALGORITHM *********************************    3191 # ALGORITHM *********************************************************** #
3192 #       (1) Make several copies of the effect    3192 #       (1) Make several copies of the effective address.               #
3193 #       (2) Save current SR; Then mask off al    3193 #       (2) Save current SR; Then mask off all maskable interrupts.     #
3194 #       (3) Save current SFC/DFC (ASSUMED TO     3194 #       (3) Save current SFC/DFC (ASSUMED TO BE EQUAL!!!); Then set     #
3195 #           according to whether exception oc    3195 #           according to whether exception occurred in user or          #
3196 #           supervisor mode.                     3196 #           supervisor mode.                                            #
3197 #       (4) Use "plpaw" instruction to pre-lo    3197 #       (4) Use "plpaw" instruction to pre-load ATC with effective      #
3198 #           address pages(s). THIS SHOULD NOT    3198 #           address pages(s). THIS SHOULD NOT FAULT!!! The relevant     #
3199 #           page(s) should have already been     3199 #           page(s) should have already been made resident prior to     #
3200 #           entering this routine.               3200 #           entering this routine.                                      #
3201 #       (5) Push the operand lines from the c    3201 #       (5) Push the operand lines from the cache w/ "cpushl".          #
3202 #           In the 68040, this was done withi    3202 #           In the 68040, this was done within the locked region. In    #
3203 #           the 68060, it is done outside of     3203 #           the 68060, it is done outside of the locked region.         #
3204 #       (6) Use "plpar" instruction to do a r    3204 #       (6) Use "plpar" instruction to do a re-load of ATC entries for  #
3205 #           ADDR1 since ADDR2 entries may hav    3205 #           ADDR1 since ADDR2 entries may have pushed ADDR1 out of the  #
3206 #           ATC.                                 3206 #           ATC.                                                        #
3207 #       (7) Pre-fetch the core emulation inst    3207 #       (7) Pre-fetch the core emulation instructions by executing      #
3208 #           one branch within each physical l    3208 #           one branch within each physical line (16 bytes) of the code #
3209 #           before actually executing the cod    3209 #           before actually executing the code.                         #
3210 #       (8) Load the BUSCR w/ the bus lock va    3210 #       (8) Load the BUSCR w/ the bus lock value.                       #
3211 #       (9) Fetch the source operands using "    3211 #       (9) Fetch the source operands using "moves".                    #
3212 #       (10)Do the compares. If both equal, g    3212 #       (10)Do the compares. If both equal, go to step (13).            #
3213 #       (11)Unequal. No update occurs. But, w    3213 #       (11)Unequal. No update occurs. But, we do write the DST1 op     #
3214 #           back to itself (as w/ the '040) s    3214 #           back to itself (as w/ the '040) so we can gracefully unlock #
3215 #           the bus (and assert LOCKE*) using    3215 #           the bus (and assert LOCKE*) using BUSCR and the final move. #
3216 #       (12)Exit.                                3216 #       (12)Exit.                                                       #
3217 #       (13)Write update operand to the DST l    3217 #       (13)Write update operand to the DST locations. Use BUSCR to     #
3218 #           assert LOCKE* for the final write    3218 #           assert LOCKE* for the final write operation.                #
3219 #       (14)Exit.                                3219 #       (14)Exit.                                                       #
3220 #                                                3220 #                                                                       #
3221 #       The algorithm is actually implemented    3221 #       The algorithm is actually implemented slightly differently      #
3222 # depending on the size of the operation and     3222 # depending on the size of the operation and the misalignment of the    #
3223 # operands. A misaligned operand must be writ    3223 # operands. A misaligned operand must be written in aligned chunks or   #
3224 # else the BUSCR register control gets confus    3224 # else the BUSCR register control gets confused.                        #
3225 #                                                3225 #                                                                       #
3226 #############################################    3226 #########################################################################
3227                                                  3227 
3228 #############################################    3228 #################################################################
3229 # THIS IS THE STATE OF THE INTEGER REGISTER F    3229 # THIS IS THE STATE OF THE INTEGER REGISTER FILE UPON           #
3230 # ENTERING _isp_cas2().                          3230 # ENTERING _isp_cas2().                                         #
3231 #                                                3231 #                                                               #
3232 # D0 = xxxxxxxx                                  3232 # D0 = xxxxxxxx                                                 #
3233 # D1 = xxxxxxxx                                  3233 # D1 = xxxxxxxx                                                 #
3234 # D2 = cmp operand 1                             3234 # D2 = cmp operand 1                                            #
3235 # D3 = cmp operand 2                             3235 # D3 = cmp operand 2                                            #
3236 # D4 = update oper 1                             3236 # D4 = update oper 1                                            #
3237 # D5 = update oper 2                             3237 # D5 = update oper 2                                            #
3238 # D6 = 'xxxxxxff if supervisor mode; 'xxxxxx0    3238 # D6 = 'xxxxxxff if supervisor mode; 'xxxxxx00 if user mode     #
3239 # D7 = 'xxxxxxff if longword operation; 'xxxx    3239 # D7 = 'xxxxxxff if longword operation; 'xxxxxx00 if word       #
3240 # A0 = ADDR1                                     3240 # A0 = ADDR1                                                    #
3241 # A1 = ADDR2                                     3241 # A1 = ADDR2                                                    #
3242 # A2 = xxxxxxxx                                  3242 # A2 = xxxxxxxx                                                 #
3243 # A3 = xxxxxxxx                                  3243 # A3 = xxxxxxxx                                                 #
3244 # A4 = xxxxxxxx                                  3244 # A4 = xxxxxxxx                                                 #
3245 # A5 = xxxxxxxx                                  3245 # A5 = xxxxxxxx                                                 #
3246 # A6 = frame pointer                             3246 # A6 = frame pointer                                            #
3247 # A7 = stack pointer                             3247 # A7 = stack pointer                                            #
3248 #############################################    3248 #################################################################
3249                                                  3249 
3250 #       align           0x1000                   3250 #       align           0x1000
3251 # beginning label used by _isp_cas_inrange()     3251 # beginning label used by _isp_cas_inrange()
3252         global          _CASLO                   3252         global          _CASLO
3253 _CASLO:                                          3253 _CASLO:
3254                                                  3254 
3255         global          _isp_cas2                3255         global          _isp_cas2
3256 _isp_cas2:                                       3256 _isp_cas2:
3257         tst.b           %d6                      3257         tst.b           %d6                     # user or supervisor mode?
3258         bne.b           cas2_supervisor          3258         bne.b           cas2_supervisor         # supervisor
3259 cas2_user:                                       3259 cas2_user:
3260         movq.l          &0x1,%d0                 3260         movq.l          &0x1,%d0                # load user data fc
3261         bra.b           cas2_cont                3261         bra.b           cas2_cont
3262 cas2_supervisor:                                 3262 cas2_supervisor:
3263         movq.l          &0x5,%d0                 3263         movq.l          &0x5,%d0                # load supervisor data fc
3264 cas2_cont:                                       3264 cas2_cont:
3265         tst.b           %d7                      3265         tst.b           %d7                     # word or longword?
3266         beq.w           cas2w                    3266         beq.w           cas2w                   # word
3267                                                  3267 
3268 ####                                             3268 ####
3269 cas2l:                                           3269 cas2l:
3270         mov.l           %a0,%a2                  3270         mov.l           %a0,%a2                 # copy ADDR1
3271         mov.l           %a1,%a3                  3271         mov.l           %a1,%a3                 # copy ADDR2
3272         mov.l           %a0,%a4                  3272         mov.l           %a0,%a4                 # copy ADDR1
3273         mov.l           %a1,%a5                  3273         mov.l           %a1,%a5                 # copy ADDR2
3274                                                  3274 
3275         addq.l          &0x3,%a4                 3275         addq.l          &0x3,%a4                # ADDR1+3
3276         addq.l          &0x3,%a5                 3276         addq.l          &0x3,%a5                # ADDR2+3
3277         mov.l           %a2,%d1                  3277         mov.l           %a2,%d1                 # ADDR1
3278                                                  3278 
3279 # mask interrupts levels 0-6. save old mask v    3279 # mask interrupts levels 0-6. save old mask value.
3280         mov.w           %sr,%d7                  3280         mov.w           %sr,%d7                 # save current SR
3281         ori.w           &0x0700,%sr              3281         ori.w           &0x0700,%sr             # inhibit interrupts
3282                                                  3282 
3283 # load the SFC and DFC with the appropriate m    3283 # load the SFC and DFC with the appropriate mode.
3284         movc            %sfc,%d6                 3284         movc            %sfc,%d6                # save old SFC/DFC
3285         movc            %d0,%sfc                 3285         movc            %d0,%sfc                # store new SFC
3286         movc            %d0,%dfc                 3286         movc            %d0,%dfc                # store new DFC
3287                                                  3287 
3288 # pre-load the operand ATC. no page faults sh    3288 # pre-load the operand ATC. no page faults should occur here because
3289 # _real_lock_page() should have taken care of    3289 # _real_lock_page() should have taken care of this.
3290         plpaw           (%a2)                    3290         plpaw           (%a2)                   # load atc for ADDR1
3291         plpaw           (%a4)                    3291         plpaw           (%a4)                   # load atc for ADDR1+3
3292         plpaw           (%a3)                    3292         plpaw           (%a3)                   # load atc for ADDR2
3293         plpaw           (%a5)                    3293         plpaw           (%a5)                   # load atc for ADDR2+3
3294                                                  3294 
3295 # push the operand lines from the cache if th    3295 # push the operand lines from the cache if they exist.
3296         cpushl          %dc,(%a2)                3296         cpushl          %dc,(%a2)               # push line for ADDR1
3297         cpushl          %dc,(%a4)                3297         cpushl          %dc,(%a4)               # push line for ADDR1+3
3298         cpushl          %dc,(%a3)                3298         cpushl          %dc,(%a3)               # push line for ADDR2
3299         cpushl          %dc,(%a5)                3299         cpushl          %dc,(%a5)               # push line for ADDR2+2
3300                                                  3300 
3301         mov.l           %d1,%a2                  3301         mov.l           %d1,%a2                 # ADDR1
3302         addq.l          &0x3,%d1                 3302         addq.l          &0x3,%d1
3303         mov.l           %d1,%a4                  3303         mov.l           %d1,%a4                 # ADDR1+3
3304 # if ADDR1 was ATC resident before the above     3304 # if ADDR1 was ATC resident before the above "plpaw" and was executed
3305 # and it was the next entry scheduled for rep    3305 # and it was the next entry scheduled for replacement and ADDR2
3306 # shares the same set, then the "plpaw" for A    3306 # shares the same set, then the "plpaw" for ADDR2 can push the ADDR1
3307 # entries from the ATC. so, we do a second se    3307 # entries from the ATC. so, we do a second set of "plpa"s.
3308         plpar           (%a2)                    3308         plpar           (%a2)                   # load atc for ADDR1
3309         plpar           (%a4)                    3309         plpar           (%a4)                   # load atc for ADDR1+3
3310                                                  3310 
3311 # load the BUSCR values.                         3311 # load the BUSCR values.
3312         mov.l           &0x80000000,%a2          3312         mov.l           &0x80000000,%a2         # assert LOCK* buscr value
3313         mov.l           &0xa0000000,%a3          3313         mov.l           &0xa0000000,%a3         # assert LOCKE* buscr value
3314         mov.l           &0x00000000,%a4          3314         mov.l           &0x00000000,%a4         # buscr unlock value
3315                                                  3315 
3316 # there are three possible mis-aligned cases     3316 # there are three possible mis-aligned cases for longword cas. they
3317 # are separated because the final write which    3317 # are separated because the final write which asserts LOCKE* must
3318 # be aligned.                                    3318 # be aligned.
3319         mov.l           %a0,%d0                  3319         mov.l           %a0,%d0                 # is ADDR1 misaligned?
3320         andi.b          &0x3,%d0                 3320         andi.b          &0x3,%d0
3321         beq.b           CAS2L_ENTER              3321         beq.b           CAS2L_ENTER             # no
3322         cmpi.b          %d0,&0x2                 3322         cmpi.b          %d0,&0x2
3323         beq.w           CAS2L2_ENTER             3323         beq.w           CAS2L2_ENTER            # yes; word misaligned
3324         bra.w           CAS2L3_ENTER             3324         bra.w           CAS2L3_ENTER            # yes; byte misaligned
3325                                                  3325 
3326 #                                                3326 #
3327 # D0 = dst operand 1 <-                          3327 # D0 = dst operand 1 <-
3328 # D1 = dst operand 2 <-                          3328 # D1 = dst operand 2 <-
3329 # D2 = cmp operand 1                             3329 # D2 = cmp operand 1
3330 # D3 = cmp operand 2                             3330 # D3 = cmp operand 2
3331 # D4 = update oper 1                             3331 # D4 = update oper 1
3332 # D5 = update oper 2                             3332 # D5 = update oper 2
3333 # D6 = old SFC/DFC                               3333 # D6 = old SFC/DFC
3334 # D7 = old SR                                    3334 # D7 = old SR
3335 # A0 = ADDR1                                     3335 # A0 = ADDR1
3336 # A1 = ADDR2                                     3336 # A1 = ADDR2
3337 # A2 = bus LOCK*  value                          3337 # A2 = bus LOCK*  value
3338 # A3 = bus LOCKE* value                          3338 # A3 = bus LOCKE* value
3339 # A4 = bus unlock value                          3339 # A4 = bus unlock value
3340 # A5 = xxxxxxxx                                  3340 # A5 = xxxxxxxx
3341 #                                                3341 #
3342         align           0x10                     3342         align           0x10
3343 CAS2L_START:                                     3343 CAS2L_START:
3344         movc            %a2,%buscr               3344         movc            %a2,%buscr              # assert LOCK*
3345         movs.l          (%a1),%d1                3345         movs.l          (%a1),%d1               # fetch Dest2[31:0]
3346         movs.l          (%a0),%d0                3346         movs.l          (%a0),%d0               # fetch Dest1[31:0]
3347         bra.b           CAS2L_CONT               3347         bra.b           CAS2L_CONT
3348 CAS2L_ENTER:                                     3348 CAS2L_ENTER:
3349         bra.b           ~+16                     3349         bra.b           ~+16
3350                                                  3350 
3351 CAS2L_CONT:                                      3351 CAS2L_CONT:
3352         cmp.l           %d0,%d2                  3352         cmp.l           %d0,%d2                 # Dest1 - Compare1
3353         bne.b           CAS2L_NOUPDATE           3353         bne.b           CAS2L_NOUPDATE
3354         cmp.l           %d1,%d3                  3354         cmp.l           %d1,%d3                 # Dest2 - Compare2
3355         bne.b           CAS2L_NOUPDATE           3355         bne.b           CAS2L_NOUPDATE
3356         movs.l          %d5,(%a1)                3356         movs.l          %d5,(%a1)               # Update2[31:0] -> DEST2
3357         bra.b           CAS2L_UPDATE             3357         bra.b           CAS2L_UPDATE
3358         bra.b           ~+16                     3358         bra.b           ~+16
3359                                                  3359 
3360 CAS2L_UPDATE:                                    3360 CAS2L_UPDATE:
3361         movc            %a3,%buscr               3361         movc            %a3,%buscr              # assert LOCKE*
3362         movs.l          %d4,(%a0)                3362         movs.l          %d4,(%a0)               # Update1[31:0] -> DEST1
3363         movc            %a4,%buscr               3363         movc            %a4,%buscr              # unlock the bus
3364         bra.b           cas2l_update_done        3364         bra.b           cas2l_update_done
3365         bra.b           ~+16                     3365         bra.b           ~+16
3366                                                  3366 
3367 CAS2L_NOUPDATE:                                  3367 CAS2L_NOUPDATE:
3368         movc            %a3,%buscr               3368         movc            %a3,%buscr              # assert LOCKE*
3369         movs.l          %d0,(%a0)                3369         movs.l          %d0,(%a0)               # Dest1[31:0] -> DEST1
3370         movc            %a4,%buscr               3370         movc            %a4,%buscr              # unlock the bus
3371         bra.b           cas2l_noupdate_done      3371         bra.b           cas2l_noupdate_done
3372         bra.b           ~+16                     3372         bra.b           ~+16
3373                                                  3373 
3374 CAS2L_FILLER:                                    3374 CAS2L_FILLER:
3375         nop                                      3375         nop
3376         nop                                      3376         nop
3377         nop                                      3377         nop
3378         nop                                      3378         nop
3379         nop                                      3379         nop
3380         nop                                      3380         nop
3381         nop                                      3381         nop
3382         bra.b           CAS2L_START              3382         bra.b           CAS2L_START
3383                                                  3383 
3384 ####                                             3384 ####
3385                                                  3385 
3386 #############################################    3386 #################################################################
3387 # THIS MUST BE THE STATE OF THE INTEGER REGIS    3387 # THIS MUST BE THE STATE OF THE INTEGER REGISTER FILE UPON      #
3388 # ENTERING _isp_cas2().                          3388 # ENTERING _isp_cas2().                                         #
3389 #                                                3389 #                                                               #
3390 # D0 = destination[31:0] operand 1               3390 # D0 = destination[31:0] operand 1                              #
3391 # D1 = destination[31:0] operand 2               3391 # D1 = destination[31:0] operand 2                              #
3392 # D2 = cmp[31:0] operand 1                       3392 # D2 = cmp[31:0] operand 1                                      #
3393 # D3 = cmp[31:0] operand 2                       3393 # D3 = cmp[31:0] operand 2                                      #
3394 # D4 = 'xxxxxx11 -> no reg update; 'xxxxxx00     3394 # D4 = 'xxxxxx11 -> no reg update; 'xxxxxx00 -> update required #
3395 # D5 = xxxxxxxx                                  3395 # D5 = xxxxxxxx                                                 #
3396 # D6 = xxxxxxxx                                  3396 # D6 = xxxxxxxx                                                 #
3397 # D7 = xxxxxxxx                                  3397 # D7 = xxxxxxxx                                                 #
3398 # A0 = xxxxxxxx                                  3398 # A0 = xxxxxxxx                                                 #
3399 # A1 = xxxxxxxx                                  3399 # A1 = xxxxxxxx                                                 #
3400 # A2 = xxxxxxxx                                  3400 # A2 = xxxxxxxx                                                 #
3401 # A3 = xxxxxxxx                                  3401 # A3 = xxxxxxxx                                                 #
3402 # A4 = xxxxxxxx                                  3402 # A4 = xxxxxxxx                                                 #
3403 # A5 = xxxxxxxx                                  3403 # A5 = xxxxxxxx                                                 #
3404 # A6 = frame pointer                             3404 # A6 = frame pointer                                            #
3405 # A7 = stack pointer                             3405 # A7 = stack pointer                                            #
3406 #############################################    3406 #################################################################
3407                                                  3407 
3408 cas2l_noupdate_done:                             3408 cas2l_noupdate_done:
3409                                                  3409 
3410 # restore previous SFC/DFC value.                3410 # restore previous SFC/DFC value.
3411         movc            %d6,%sfc                 3411         movc            %d6,%sfc                # restore old SFC
3412         movc            %d6,%dfc                 3412         movc            %d6,%dfc                # restore old DFC
3413                                                  3413 
3414 # restore previous interrupt mask level.         3414 # restore previous interrupt mask level.
3415         mov.w           %d7,%sr                  3415         mov.w           %d7,%sr                 # restore old SR
3416                                                  3416 
3417         sf              %d4                      3417         sf              %d4                     # indicate no update was done
3418         bra.l           _isp_cas2_finish         3418         bra.l           _isp_cas2_finish
3419                                                  3419 
3420 cas2l_update_done:                               3420 cas2l_update_done:
3421                                                  3421 
3422 # restore previous SFC/DFC value.                3422 # restore previous SFC/DFC value.
3423         movc            %d6,%sfc                 3423         movc            %d6,%sfc                # restore old SFC
3424         movc            %d6,%dfc                 3424         movc            %d6,%dfc                # restore old DFC
3425                                                  3425 
3426 # restore previous interrupt mask level.         3426 # restore previous interrupt mask level.
3427         mov.w           %d7,%sr                  3427         mov.w           %d7,%sr                 # restore old SR
3428                                                  3428 
3429         st              %d4                      3429         st              %d4                     # indicate update was done
3430         bra.l           _isp_cas2_finish         3430         bra.l           _isp_cas2_finish
3431 ####                                             3431 ####
3432                                                  3432 
3433         align           0x10                     3433         align           0x10
3434 CAS2L2_START:                                    3434 CAS2L2_START:
3435         movc            %a2,%buscr               3435         movc            %a2,%buscr              # assert LOCK*
3436         movs.l          (%a1),%d1                3436         movs.l          (%a1),%d1               # fetch Dest2[31:0]
3437         movs.l          (%a0),%d0                3437         movs.l          (%a0),%d0               # fetch Dest1[31:0]
3438         bra.b           CAS2L2_CONT              3438         bra.b           CAS2L2_CONT
3439 CAS2L2_ENTER:                                    3439 CAS2L2_ENTER:
3440         bra.b           ~+16                     3440         bra.b           ~+16
3441                                                  3441 
3442 CAS2L2_CONT:                                     3442 CAS2L2_CONT:
3443         cmp.l           %d0,%d2                  3443         cmp.l           %d0,%d2                 # Dest1 - Compare1
3444         bne.b           CAS2L2_NOUPDATE          3444         bne.b           CAS2L2_NOUPDATE
3445         cmp.l           %d1,%d3                  3445         cmp.l           %d1,%d3                 # Dest2 - Compare2
3446         bne.b           CAS2L2_NOUPDATE          3446         bne.b           CAS2L2_NOUPDATE
3447         movs.l          %d5,(%a1)                3447         movs.l          %d5,(%a1)               # Update2[31:0] -> Dest2
3448         bra.b           CAS2L2_UPDATE            3448         bra.b           CAS2L2_UPDATE
3449         bra.b           ~+16                     3449         bra.b           ~+16
3450                                                  3450 
3451 CAS2L2_UPDATE:                                   3451 CAS2L2_UPDATE:
3452         swap            %d4                      3452         swap            %d4                     # get Update1[31:16]
3453         movs.w          %d4,(%a0)+               3453         movs.w          %d4,(%a0)+              # Update1[31:16] -> DEST1
3454         movc            %a3,%buscr               3454         movc            %a3,%buscr              # assert LOCKE*
3455         swap            %d4                      3455         swap            %d4                     # get Update1[15:0]
3456         bra.b           CAS2L2_UPDATE2           3456         bra.b           CAS2L2_UPDATE2
3457         bra.b           ~+16                     3457         bra.b           ~+16
3458                                                  3458 
3459 CAS2L2_UPDATE2:                                  3459 CAS2L2_UPDATE2:
3460         movs.w          %d4,(%a0)                3460         movs.w          %d4,(%a0)               # Update1[15:0] -> DEST1+0x2
3461         movc            %a4,%buscr               3461         movc            %a4,%buscr              # unlock the bus
3462         bra.w           cas2l_update_done        3462         bra.w           cas2l_update_done
3463         nop                                      3463         nop
3464         bra.b           ~+16                     3464         bra.b           ~+16
3465                                                  3465 
3466 CAS2L2_NOUPDATE:                                 3466 CAS2L2_NOUPDATE:
3467         swap            %d0                      3467         swap            %d0                     # get Dest1[31:16]
3468         movs.w          %d0,(%a0)+               3468         movs.w          %d0,(%a0)+              # Dest1[31:16] -> DEST1
3469         movc            %a3,%buscr               3469         movc            %a3,%buscr              # assert LOCKE*
3470         swap            %d0                      3470         swap            %d0                     # get Dest1[15:0]
3471         bra.b           CAS2L2_NOUPDATE2         3471         bra.b           CAS2L2_NOUPDATE2
3472         bra.b           ~+16                     3472         bra.b           ~+16
3473                                                  3473 
3474 CAS2L2_NOUPDATE2:                                3474 CAS2L2_NOUPDATE2:
3475         movs.w          %d0,(%a0)                3475         movs.w          %d0,(%a0)               # Dest1[15:0] -> DEST1+0x2
3476         movc            %a4,%buscr               3476         movc            %a4,%buscr              # unlock the bus
3477         bra.w           cas2l_noupdate_done      3477         bra.w           cas2l_noupdate_done
3478         nop                                      3478         nop
3479         bra.b           ~+16                     3479         bra.b           ~+16
3480                                                  3480 
3481 CAS2L2_FILLER:                                   3481 CAS2L2_FILLER:
3482         nop                                      3482         nop
3483         nop                                      3483         nop
3484         nop                                      3484         nop
3485         nop                                      3485         nop
3486         nop                                      3486         nop
3487         nop                                      3487         nop
3488         nop                                      3488         nop
3489         bra.b           CAS2L2_START             3489         bra.b           CAS2L2_START
3490                                                  3490 
3491 #################################                3491 #################################
3492                                                  3492 
3493         align           0x10                     3493         align           0x10
3494 CAS2L3_START:                                    3494 CAS2L3_START:
3495         movc            %a2,%buscr               3495         movc            %a2,%buscr              # assert LOCK*
3496         movs.l          (%a1),%d1                3496         movs.l          (%a1),%d1               # fetch Dest2[31:0]
3497         movs.l          (%a0),%d0                3497         movs.l          (%a0),%d0               # fetch Dest1[31:0]
3498         bra.b           CAS2L3_CONT              3498         bra.b           CAS2L3_CONT
3499 CAS2L3_ENTER:                                    3499 CAS2L3_ENTER:
3500         bra.b           ~+16                     3500         bra.b           ~+16
3501                                                  3501 
3502 CAS2L3_CONT:                                     3502 CAS2L3_CONT:
3503         cmp.l           %d0,%d2                  3503         cmp.l           %d0,%d2                 # Dest1 - Compare1
3504         bne.b           CAS2L3_NOUPDATE          3504         bne.b           CAS2L3_NOUPDATE
3505         cmp.l           %d1,%d3                  3505         cmp.l           %d1,%d3                 # Dest2 - Compare2
3506         bne.b           CAS2L3_NOUPDATE          3506         bne.b           CAS2L3_NOUPDATE
3507         movs.l          %d5,(%a1)                3507         movs.l          %d5,(%a1)               # Update2[31:0] -> DEST2
3508         bra.b           CAS2L3_UPDATE            3508         bra.b           CAS2L3_UPDATE
3509         bra.b           ~+16                     3509         bra.b           ~+16
3510                                                  3510 
3511 CAS2L3_UPDATE:                                   3511 CAS2L3_UPDATE:
3512         rol.l           &0x8,%d4                 3512         rol.l           &0x8,%d4                # get Update1[31:24]
3513         movs.b          %d4,(%a0)+               3513         movs.b          %d4,(%a0)+              # Update1[31:24] -> DEST1
3514         swap            %d4                      3514         swap            %d4                     # get Update1[23:8]
3515         movs.w          %d4,(%a0)+               3515         movs.w          %d4,(%a0)+              # Update1[23:8] -> DEST1+0x1
3516         bra.b           CAS2L3_UPDATE2           3516         bra.b           CAS2L3_UPDATE2
3517         bra.b           ~+16                     3517         bra.b           ~+16
3518                                                  3518 
3519 CAS2L3_UPDATE2:                                  3519 CAS2L3_UPDATE2:
3520         rol.l           &0x8,%d4                 3520         rol.l           &0x8,%d4                # get Update1[7:0]
3521         movc            %a3,%buscr               3521         movc            %a3,%buscr              # assert LOCKE*
3522         movs.b          %d4,(%a0)                3522         movs.b          %d4,(%a0)               # Update1[7:0] -> DEST1+0x3
3523         bra.b           CAS2L3_UPDATE3           3523         bra.b           CAS2L3_UPDATE3
3524         nop                                      3524         nop
3525         bra.b           ~+16                     3525         bra.b           ~+16
3526                                                  3526 
3527 CAS2L3_UPDATE3:                                  3527 CAS2L3_UPDATE3:
3528         movc            %a4,%buscr               3528         movc            %a4,%buscr              # unlock the bus
3529         bra.w           cas2l_update_done        3529         bra.w           cas2l_update_done
3530         nop                                      3530         nop
3531         nop                                      3531         nop
3532         nop                                      3532         nop
3533         bra.b           ~+16                     3533         bra.b           ~+16
3534                                                  3534 
3535 CAS2L3_NOUPDATE:                                 3535 CAS2L3_NOUPDATE:
3536         rol.l           &0x8,%d0                 3536         rol.l           &0x8,%d0                # get Dest1[31:24]
3537         movs.b          %d0,(%a0)+               3537         movs.b          %d0,(%a0)+              # Dest1[31:24] -> DEST1
3538         swap            %d0                      3538         swap            %d0                     # get Dest1[23:8]
3539         movs.w          %d0,(%a0)+               3539         movs.w          %d0,(%a0)+              # Dest1[23:8] -> DEST1+0x1
3540         bra.b           CAS2L3_NOUPDATE2         3540         bra.b           CAS2L3_NOUPDATE2
3541         bra.b           ~+16                     3541         bra.b           ~+16
3542                                                  3542 
3543 CAS2L3_NOUPDATE2:                                3543 CAS2L3_NOUPDATE2:
3544         rol.l           &0x8,%d0                 3544         rol.l           &0x8,%d0                # get Dest1[7:0]
3545         movc            %a3,%buscr               3545         movc            %a3,%buscr              # assert LOCKE*
3546         movs.b          %d0,(%a0)                3546         movs.b          %d0,(%a0)               # Update1[7:0] -> DEST1+0x3
3547         bra.b           CAS2L3_NOUPDATE3         3547         bra.b           CAS2L3_NOUPDATE3
3548         nop                                      3548         nop
3549         bra.b           ~+16                     3549         bra.b           ~+16
3550                                                  3550 
3551 CAS2L3_NOUPDATE3:                                3551 CAS2L3_NOUPDATE3:
3552         movc            %a4,%buscr               3552         movc            %a4,%buscr              # unlock the bus
3553         bra.w           cas2l_noupdate_done      3553         bra.w           cas2l_noupdate_done
3554         nop                                      3554         nop
3555         nop                                      3555         nop
3556         nop                                      3556         nop
3557         bra.b           ~+14                     3557         bra.b           ~+14
3558                                                  3558 
3559 CAS2L3_FILLER:                                   3559 CAS2L3_FILLER:
3560         nop                                      3560         nop
3561         nop                                      3561         nop
3562         nop                                      3562         nop
3563         nop                                      3563         nop
3564         nop                                      3564         nop
3565         nop                                      3565         nop
3566         bra.w           CAS2L3_START             3566         bra.w           CAS2L3_START
3567                                                  3567 
3568 #############################################    3568 #############################################################
3569 #############################################    3569 #############################################################
3570                                                  3570 
3571 cas2w:                                           3571 cas2w:
3572         mov.l           %a0,%a2                  3572         mov.l           %a0,%a2                 # copy ADDR1
3573         mov.l           %a1,%a3                  3573         mov.l           %a1,%a3                 # copy ADDR2
3574         mov.l           %a0,%a4                  3574         mov.l           %a0,%a4                 # copy ADDR1
3575         mov.l           %a1,%a5                  3575         mov.l           %a1,%a5                 # copy ADDR2
3576                                                  3576 
3577         addq.l          &0x1,%a4                 3577         addq.l          &0x1,%a4                # ADDR1+1
3578         addq.l          &0x1,%a5                 3578         addq.l          &0x1,%a5                # ADDR2+1
3579         mov.l           %a2,%d1                  3579         mov.l           %a2,%d1                 # ADDR1
3580                                                  3580 
3581 # mask interrupt levels 0-6. save old mask va    3581 # mask interrupt levels 0-6. save old mask value.
3582         mov.w           %sr,%d7                  3582         mov.w           %sr,%d7                 # save current SR
3583         ori.w           &0x0700,%sr              3583         ori.w           &0x0700,%sr             # inhibit interrupts
3584                                                  3584 
3585 # load the SFC and DFC with the appropriate m    3585 # load the SFC and DFC with the appropriate mode.
3586         movc            %sfc,%d6                 3586         movc            %sfc,%d6                # save old SFC/DFC
3587         movc            %d0,%sfc                 3587         movc            %d0,%sfc                # store new SFC
3588         movc            %d0,%dfc                 3588         movc            %d0,%dfc                # store new DFC
3589                                                  3589 
3590 # pre-load the operand ATC. no page faults sh    3590 # pre-load the operand ATC. no page faults should occur because
3591 # _real_lock_page() should have taken care of    3591 # _real_lock_page() should have taken care of this.
3592         plpaw           (%a2)                    3592         plpaw           (%a2)                   # load atc for ADDR1
3593         plpaw           (%a4)                    3593         plpaw           (%a4)                   # load atc for ADDR1+1
3594         plpaw           (%a3)                    3594         plpaw           (%a3)                   # load atc for ADDR2
3595         plpaw           (%a5)                    3595         plpaw           (%a5)                   # load atc for ADDR2+1
3596                                                  3596 
3597 # push the operand cache lines from the cache    3597 # push the operand cache lines from the cache if they exist.
3598         cpushl          %dc,(%a2)                3598         cpushl          %dc,(%a2)               # push line for ADDR1
3599         cpushl          %dc,(%a4)                3599         cpushl          %dc,(%a4)               # push line for ADDR1+1
3600         cpushl          %dc,(%a3)                3600         cpushl          %dc,(%a3)               # push line for ADDR2
3601         cpushl          %dc,(%a5)                3601         cpushl          %dc,(%a5)               # push line for ADDR2+1
3602                                                  3602 
3603         mov.l           %d1,%a2                  3603         mov.l           %d1,%a2                 # ADDR1
3604         addq.l          &0x3,%d1                 3604         addq.l          &0x3,%d1
3605         mov.l           %d1,%a4                  3605         mov.l           %d1,%a4                 # ADDR1+3
3606 # if ADDR1 was ATC resident before the above     3606 # if ADDR1 was ATC resident before the above "plpaw" and was executed
3607 # and it was the next entry scheduled for rep    3607 # and it was the next entry scheduled for replacement and ADDR2
3608 # shares the same set, then the "plpaw" for A    3608 # shares the same set, then the "plpaw" for ADDR2 can push the ADDR1
3609 # entries from the ATC. so, we do a second se    3609 # entries from the ATC. so, we do a second set of "plpa"s.
3610         plpar           (%a2)                    3610         plpar           (%a2)                   # load atc for ADDR1
3611         plpar           (%a4)                    3611         plpar           (%a4)                   # load atc for ADDR1+3
3612                                                  3612 
3613 # load the BUSCR values.                         3613 # load the BUSCR values.
3614         mov.l           &0x80000000,%a2          3614         mov.l           &0x80000000,%a2         # assert LOCK* buscr value
3615         mov.l           &0xa0000000,%a3          3615         mov.l           &0xa0000000,%a3         # assert LOCKE* buscr value
3616         mov.l           &0x00000000,%a4          3616         mov.l           &0x00000000,%a4         # buscr unlock value
3617                                                  3617 
3618 # there are two possible mis-aligned cases fo    3618 # there are two possible mis-aligned cases for word cas. they
3619 # are separated because the final write which    3619 # are separated because the final write which asserts LOCKE* must
3620 # be aligned.                                    3620 # be aligned.
3621         mov.l           %a0,%d0                  3621         mov.l           %a0,%d0                 # is ADDR1 misaligned?
3622         btst            &0x0,%d0                 3622         btst            &0x0,%d0
3623         bne.w           CAS2W2_ENTER             3623         bne.w           CAS2W2_ENTER            # yes
3624         bra.b           CAS2W_ENTER              3624         bra.b           CAS2W_ENTER             # no
3625                                                  3625 
3626 #                                                3626 #
3627 # D0 = dst operand 1 <-                          3627 # D0 = dst operand 1 <-
3628 # D1 = dst operand 2 <-                          3628 # D1 = dst operand 2 <-
3629 # D2 = cmp operand 1                             3629 # D2 = cmp operand 1
3630 # D3 = cmp operand 2                             3630 # D3 = cmp operand 2
3631 # D4 = update oper 1                             3631 # D4 = update oper 1
3632 # D5 = update oper 2                             3632 # D5 = update oper 2
3633 # D6 = old SFC/DFC                               3633 # D6 = old SFC/DFC
3634 # D7 = old SR                                    3634 # D7 = old SR
3635 # A0 = ADDR1                                     3635 # A0 = ADDR1
3636 # A1 = ADDR2                                     3636 # A1 = ADDR2
3637 # A2 = bus LOCK*  value                          3637 # A2 = bus LOCK*  value
3638 # A3 = bus LOCKE* value                          3638 # A3 = bus LOCKE* value
3639 # A4 = bus unlock value                          3639 # A4 = bus unlock value
3640 # A5 = xxxxxxxx                                  3640 # A5 = xxxxxxxx
3641 #                                                3641 #
3642         align           0x10                     3642         align           0x10
3643 CAS2W_START:                                     3643 CAS2W_START:
3644         movc            %a2,%buscr               3644         movc            %a2,%buscr              # assert LOCK*
3645         movs.w          (%a1),%d1                3645         movs.w          (%a1),%d1               # fetch Dest2[15:0]
3646         movs.w          (%a0),%d0                3646         movs.w          (%a0),%d0               # fetch Dest1[15:0]
3647         bra.b           CAS2W_CONT2              3647         bra.b           CAS2W_CONT2
3648 CAS2W_ENTER:                                     3648 CAS2W_ENTER:
3649         bra.b           ~+16                     3649         bra.b           ~+16
3650                                                  3650 
3651 CAS2W_CONT2:                                     3651 CAS2W_CONT2:
3652         cmp.w           %d0,%d2                  3652         cmp.w           %d0,%d2                 # Dest1 - Compare1
3653         bne.b           CAS2W_NOUPDATE           3653         bne.b           CAS2W_NOUPDATE
3654         cmp.w           %d1,%d3                  3654         cmp.w           %d1,%d3                 # Dest2 - Compare2
3655         bne.b           CAS2W_NOUPDATE           3655         bne.b           CAS2W_NOUPDATE
3656         movs.w          %d5,(%a1)                3656         movs.w          %d5,(%a1)               # Update2[15:0] -> DEST2
3657         bra.b           CAS2W_UPDATE             3657         bra.b           CAS2W_UPDATE
3658         bra.b           ~+16                     3658         bra.b           ~+16
3659                                                  3659 
3660 CAS2W_UPDATE:                                    3660 CAS2W_UPDATE:
3661         movc            %a3,%buscr               3661         movc            %a3,%buscr              # assert LOCKE*
3662         movs.w          %d4,(%a0)                3662         movs.w          %d4,(%a0)               # Update1[15:0] -> DEST1
3663         movc            %a4,%buscr               3663         movc            %a4,%buscr              # unlock the bus
3664         bra.b           cas2w_update_done        3664         bra.b           cas2w_update_done
3665         bra.b           ~+16                     3665         bra.b           ~+16
3666                                                  3666 
3667 CAS2W_NOUPDATE:                                  3667 CAS2W_NOUPDATE:
3668         movc            %a3,%buscr               3668         movc            %a3,%buscr              # assert LOCKE*
3669         movs.w          %d0,(%a0)                3669         movs.w          %d0,(%a0)               # Dest1[15:0] -> DEST1
3670         movc            %a4,%buscr               3670         movc            %a4,%buscr              # unlock the bus
3671         bra.b           cas2w_noupdate_done      3671         bra.b           cas2w_noupdate_done
3672         bra.b           ~+16                     3672         bra.b           ~+16
3673                                                  3673 
3674 CAS2W_FILLER:                                    3674 CAS2W_FILLER:
3675         nop                                      3675         nop
3676         nop                                      3676         nop
3677         nop                                      3677         nop
3678         nop                                      3678         nop
3679         nop                                      3679         nop
3680         nop                                      3680         nop
3681         nop                                      3681         nop
3682         bra.b           CAS2W_START              3682         bra.b           CAS2W_START
3683                                                  3683 
3684 ####                                             3684 ####
3685                                                  3685 
3686 #############################################    3686 #################################################################
3687 # THIS MUST BE THE STATE OF THE INTEGER REGIS    3687 # THIS MUST BE THE STATE OF THE INTEGER REGISTER FILE UPON      #
3688 # ENTERING _isp_cas2().                          3688 # ENTERING _isp_cas2().                                         #
3689 #                                                3689 #                                                               #
3690 # D0 = destination[15:0] operand 1               3690 # D0 = destination[15:0] operand 1                              #
3691 # D1 = destination[15:0] operand 2               3691 # D1 = destination[15:0] operand 2                              #
3692 # D2 = cmp[15:0] operand 1                       3692 # D2 = cmp[15:0] operand 1                                      #
3693 # D3 = cmp[15:0] operand 2                       3693 # D3 = cmp[15:0] operand 2                                      #
3694 # D4 = 'xxxxxx11 -> no reg update; 'xxxxxx00     3694 # D4 = 'xxxxxx11 -> no reg update; 'xxxxxx00 -> update required #
3695 # D5 = xxxxxxxx                                  3695 # D5 = xxxxxxxx                                                 #
3696 # D6 = xxxxxxxx                                  3696 # D6 = xxxxxxxx                                                 #
3697 # D7 = xxxxxxxx                                  3697 # D7 = xxxxxxxx                                                 #
3698 # A0 = xxxxxxxx                                  3698 # A0 = xxxxxxxx                                                 #
3699 # A1 = xxxxxxxx                                  3699 # A1 = xxxxxxxx                                                 #
3700 # A2 = xxxxxxxx                                  3700 # A2 = xxxxxxxx                                                 #
3701 # A3 = xxxxxxxx                                  3701 # A3 = xxxxxxxx                                                 #
3702 # A4 = xxxxxxxx                                  3702 # A4 = xxxxxxxx                                                 #
3703 # A5 = xxxxxxxx                                  3703 # A5 = xxxxxxxx                                                 #
3704 # A6 = frame pointer                             3704 # A6 = frame pointer                                            #
3705 # A7 = stack pointer                             3705 # A7 = stack pointer                                            #
3706 #############################################    3706 #################################################################
3707                                                  3707 
3708 cas2w_noupdate_done:                             3708 cas2w_noupdate_done:
3709                                                  3709 
3710 # restore previous SFC/DFC value.                3710 # restore previous SFC/DFC value.
3711         movc            %d6,%sfc                 3711         movc            %d6,%sfc                # restore old SFC
3712         movc            %d6,%dfc                 3712         movc            %d6,%dfc                # restore old DFC
3713                                                  3713 
3714 # restore previous interrupt mask level.         3714 # restore previous interrupt mask level.
3715         mov.w           %d7,%sr                  3715         mov.w           %d7,%sr                 # restore old SR
3716                                                  3716 
3717         sf              %d4                      3717         sf              %d4                     # indicate no update was done
3718         bra.l           _isp_cas2_finish         3718         bra.l           _isp_cas2_finish
3719                                                  3719 
3720 cas2w_update_done:                               3720 cas2w_update_done:
3721                                                  3721 
3722 # restore previous SFC/DFC value.                3722 # restore previous SFC/DFC value.
3723         movc            %d6,%sfc                 3723         movc            %d6,%sfc                # restore old SFC
3724         movc            %d6,%dfc                 3724         movc            %d6,%dfc                # restore old DFC
3725                                                  3725 
3726 # restore previous interrupt mask level.         3726 # restore previous interrupt mask level.
3727         mov.w           %d7,%sr                  3727         mov.w           %d7,%sr                 # restore old SR
3728                                                  3728 
3729         st              %d4                      3729         st              %d4                     # indicate update was done
3730         bra.l           _isp_cas2_finish         3730         bra.l           _isp_cas2_finish
3731 ####                                             3731 ####
3732                                                  3732 
3733         align           0x10                     3733         align           0x10
3734 CAS2W2_START:                                    3734 CAS2W2_START:
3735         movc            %a2,%buscr               3735         movc            %a2,%buscr              # assert LOCK*
3736         movs.w          (%a1),%d1                3736         movs.w          (%a1),%d1               # fetch Dest2[15:0]
3737         movs.w          (%a0),%d0                3737         movs.w          (%a0),%d0               # fetch Dest1[15:0]
3738         bra.b           CAS2W2_CONT2             3738         bra.b           CAS2W2_CONT2
3739 CAS2W2_ENTER:                                    3739 CAS2W2_ENTER:
3740         bra.b           ~+16                     3740         bra.b           ~+16
3741                                                  3741 
3742 CAS2W2_CONT2:                                    3742 CAS2W2_CONT2:
3743         cmp.w           %d0,%d2                  3743         cmp.w           %d0,%d2                 # Dest1 - Compare1
3744         bne.b           CAS2W2_NOUPDATE          3744         bne.b           CAS2W2_NOUPDATE
3745         cmp.w           %d1,%d3                  3745         cmp.w           %d1,%d3                 # Dest2 - Compare2
3746         bne.b           CAS2W2_NOUPDATE          3746         bne.b           CAS2W2_NOUPDATE
3747         movs.w          %d5,(%a1)                3747         movs.w          %d5,(%a1)               # Update2[15:0] -> DEST2
3748         bra.b           CAS2W2_UPDATE            3748         bra.b           CAS2W2_UPDATE
3749         bra.b           ~+16                     3749         bra.b           ~+16
3750                                                  3750 
3751 CAS2W2_UPDATE:                                   3751 CAS2W2_UPDATE:
3752         ror.l           &0x8,%d4                 3752         ror.l           &0x8,%d4                # get Update1[15:8]
3753         movs.b          %d4,(%a0)+               3753         movs.b          %d4,(%a0)+              # Update1[15:8] -> DEST1
3754         movc            %a3,%buscr               3754         movc            %a3,%buscr              # assert LOCKE*
3755         rol.l           &0x8,%d4                 3755         rol.l           &0x8,%d4                # get Update1[7:0]
3756         bra.b           CAS2W2_UPDATE2           3756         bra.b           CAS2W2_UPDATE2
3757         bra.b           ~+16                     3757         bra.b           ~+16
3758                                                  3758 
3759 CAS2W2_UPDATE2:                                  3759 CAS2W2_UPDATE2:
3760         movs.b          %d4,(%a0)                3760         movs.b          %d4,(%a0)               # Update1[7:0] -> DEST1+0x1
3761         movc            %a4,%buscr               3761         movc            %a4,%buscr              # unlock the bus
3762         bra.w           cas2w_update_done        3762         bra.w           cas2w_update_done
3763         nop                                      3763         nop
3764         bra.b           ~+16                     3764         bra.b           ~+16
3765                                                  3765 
3766 CAS2W2_NOUPDATE:                                 3766 CAS2W2_NOUPDATE:
3767         ror.l           &0x8,%d0                 3767         ror.l           &0x8,%d0                # get Dest1[15:8]
3768         movs.b          %d0,(%a0)+               3768         movs.b          %d0,(%a0)+              # Dest1[15:8] -> DEST1
3769         movc            %a3,%buscr               3769         movc            %a3,%buscr              # assert LOCKE*
3770         rol.l           &0x8,%d0                 3770         rol.l           &0x8,%d0                # get Dest1[7:0]
3771         bra.b           CAS2W2_NOUPDATE2         3771         bra.b           CAS2W2_NOUPDATE2
3772         bra.b           ~+16                     3772         bra.b           ~+16
3773                                                  3773 
3774 CAS2W2_NOUPDATE2:                                3774 CAS2W2_NOUPDATE2:
3775         movs.b          %d0,(%a0)                3775         movs.b          %d0,(%a0)               # Dest1[7:0] -> DEST1+0x1
3776         movc            %a4,%buscr               3776         movc            %a4,%buscr              # unlock the bus
3777         bra.w           cas2w_noupdate_done      3777         bra.w           cas2w_noupdate_done
3778         nop                                      3778         nop
3779         bra.b           ~+16                     3779         bra.b           ~+16
3780                                                  3780 
3781 CAS2W2_FILLER:                                   3781 CAS2W2_FILLER:
3782         nop                                      3782         nop
3783         nop                                      3783         nop
3784         nop                                      3784         nop
3785         nop                                      3785         nop
3786         nop                                      3786         nop
3787         nop                                      3787         nop
3788         nop                                      3788         nop
3789         bra.b           CAS2W2_START             3789         bra.b           CAS2W2_START
3790                                                  3790 
3791 #       ######      ##      ######               3791 #       ######      ##      ######
3792 #       #          #  #     #                    3792 #       #          #  #     #
3793 #       #         ######    ######               3793 #       #         ######    ######
3794 #       #         #    #         #               3794 #       #         #    #         #
3795 #       ######    #    #    ######               3795 #       ######    #    #    ######
3796                                                  3796 
3797 #############################################    3797 #########################################################################
3798 # XDEF **************************************    3798 # XDEF **************************************************************** #
3799 #       _isp_cas(): "core" emulation code for    3799 #       _isp_cas(): "core" emulation code for the cas instruction       #
3800 #                                                3800 #                                                                       #
3801 # XREF **************************************    3801 # XREF **************************************************************** #
3802 #       _isp_cas_finish() - only exit point f    3802 #       _isp_cas_finish() - only exit point for this emulation code;    #
3803 #                           do clean-up          3803 #                           do clean-up                                 #
3804 #                                                3804 #                                                                       #
3805 # INPUT *************************************    3805 # INPUT *************************************************************** #
3806 #       *see entry chart below*                  3806 #       *see entry chart below*                                         #
3807 #                                                3807 #                                                                       #
3808 # OUTPUT ************************************    3808 # OUTPUT ************************************************************** #
3809 #       *see exit chart below*                   3809 #       *see exit chart below*                                          #
3810 #                                                3810 #                                                                       #
3811 # ALGORITHM *********************************    3811 # ALGORITHM *********************************************************** #
3812 #       (1) Make several copies of the effect    3812 #       (1) Make several copies of the effective address.               #
3813 #       (2) Save current SR; Then mask off al    3813 #       (2) Save current SR; Then mask off all maskable interrupts.     #
3814 #       (3) Save current DFC/SFC (ASSUMED TO     3814 #       (3) Save current DFC/SFC (ASSUMED TO BE EQUAL!!!); Then set     #
3815 #           SFC/DFC according to whether exce    3815 #           SFC/DFC according to whether exception occurred in user or  #
3816 #           supervisor mode.                     3816 #           supervisor mode.                                            #
3817 #       (4) Use "plpaw" instruction to pre-lo    3817 #       (4) Use "plpaw" instruction to pre-load ATC with effective      #
3818 #           address page(s). THIS SHOULD NOT     3818 #           address page(s). THIS SHOULD NOT FAULT!!! The relevant      #
3819 #           page(s) should have been made res    3819 #           page(s) should have been made resident prior to entering    #
3820 #           this routine.                        3820 #           this routine.                                               #
3821 #       (5) Push the operand lines from the c    3821 #       (5) Push the operand lines from the cache w/ "cpushl".          #
3822 #           In the 68040, this was done withi    3822 #           In the 68040, this was done within the locked region. In    #
3823 #           the 68060, it is done outside of     3823 #           the 68060, it is done outside of the locked region.         #
3824 #       (6) Pre-fetch the core emulation inst    3824 #       (6) Pre-fetch the core emulation instructions by executing one  #
3825 #           branch within each physical line     3825 #           branch within each physical line (16 bytes) of the code     #
3826 #           before actually executing the cod    3826 #           before actually executing the code.                         #
3827 #       (7) Load the BUSCR with the bus lock     3827 #       (7) Load the BUSCR with the bus lock value.                     #
3828 #       (8) Fetch the source operand.            3828 #       (8) Fetch the source operand.                                   #
3829 #       (9) Do the compare. If equal, go to s    3829 #       (9) Do the compare. If equal, go to step (12).                  #
3830 #       (10)Unequal. No update occurs. But, w    3830 #       (10)Unequal. No update occurs. But, we do write the DST op back #
3831 #           to itself (as w/ the '040) so we     3831 #           to itself (as w/ the '040) so we can gracefully unlock      #
3832 #           the bus (and assert LOCKE*) using    3832 #           the bus (and assert LOCKE*) using BUSCR and the final move. #
3833 #       (11)Exit.                                3833 #       (11)Exit.                                                       #
3834 #       (12)Write update operand to the DST l    3834 #       (12)Write update operand to the DST location. Use BUSCR to      #
3835 #           assert LOCKE* for the final write    3835 #           assert LOCKE* for the final write operation.                #
3836 #       (13)Exit.                                3836 #       (13)Exit.                                                       #
3837 #                                                3837 #                                                                       #
3838 #       The algorithm is actually implemented    3838 #       The algorithm is actually implemented slightly differently      #
3839 # depending on the size of the operation and     3839 # depending on the size of the operation and the misalignment of the    #
3840 # operand. A misaligned operand must be writt    3840 # operand. A misaligned operand must be written in aligned chunks or    #
3841 # else the BUSCR register control gets confus    3841 # else the BUSCR register control gets confused.                        #
3842 #                                                3842 #                                                                       #
3843 #############################################    3843 #########################################################################
3844                                                  3844 
3845 #############################################    3845 #########################################################
3846 # THIS IS THE STATE OF THE INTEGER REGISTER F    3846 # THIS IS THE STATE OF THE INTEGER REGISTER FILE UPON   #
3847 # ENTERING _isp_cas().                           3847 # ENTERING _isp_cas().                                  #
3848 #                                                3848 #                                                       #
3849 # D0 = xxxxxxxx                                  3849 # D0 = xxxxxxxx                                         #
3850 # D1 = xxxxxxxx                                  3850 # D1 = xxxxxxxx                                         #
3851 # D2 = update operand                            3851 # D2 = update operand                                   #
3852 # D3 = xxxxxxxx                                  3852 # D3 = xxxxxxxx                                         #
3853 # D4 = compare operand                           3853 # D4 = compare operand                                  #
3854 # D5 = xxxxxxxx                                  3854 # D5 = xxxxxxxx                                         #
3855 # D6 = supervisor ('xxxxxxff) or user mode ('    3855 # D6 = supervisor ('xxxxxxff) or user mode ('xxxxxx00)  #
3856 # D7 = longword ('xxxxxxff) or word size ('xx    3856 # D7 = longword ('xxxxxxff) or word size ('xxxxxx00)    #
3857 # A0 = ADDR                                      3857 # A0 = ADDR                                             #
3858 # A1 = xxxxxxxx                                  3858 # A1 = xxxxxxxx                                         #
3859 # A2 = xxxxxxxx                                  3859 # A2 = xxxxxxxx                                         #
3860 # A3 = xxxxxxxx                                  3860 # A3 = xxxxxxxx                                         #
3861 # A4 = xxxxxxxx                                  3861 # A4 = xxxxxxxx                                         #
3862 # A5 = xxxxxxxx                                  3862 # A5 = xxxxxxxx                                         #
3863 # A6 = frame pointer                             3863 # A6 = frame pointer                                    #
3864 # A7 = stack pointer                             3864 # A7 = stack pointer                                    #
3865 #############################################    3865 #########################################################
3866                                                  3866 
3867         global          _isp_cas                 3867         global          _isp_cas
3868 _isp_cas:                                        3868 _isp_cas:
3869         tst.b           %d6                      3869         tst.b           %d6                     # user or supervisor mode?
3870         bne.b           cas_super                3870         bne.b           cas_super               # supervisor
3871 cas_user:                                        3871 cas_user:
3872         movq.l          &0x1,%d0                 3872         movq.l          &0x1,%d0                # load user data fc
3873         bra.b           cas_cont                 3873         bra.b           cas_cont
3874 cas_super:                                       3874 cas_super:
3875         movq.l          &0x5,%d0                 3875         movq.l          &0x5,%d0                # load supervisor data fc
3876                                                  3876 
3877 cas_cont:                                        3877 cas_cont:
3878         tst.b           %d7                      3878         tst.b           %d7                     # word or longword?
3879         bne.w           casl                     3879         bne.w           casl                    # longword
3880                                                  3880 
3881 ####                                             3881 ####
3882 casw:                                            3882 casw:
3883         mov.l           %a0,%a1                  3883         mov.l           %a0,%a1                 # make copy for plpaw1
3884         mov.l           %a0,%a2                  3884         mov.l           %a0,%a2                 # make copy for plpaw2
3885         addq.l          &0x1,%a2                 3885         addq.l          &0x1,%a2                # plpaw2 points to end of word
3886                                                  3886 
3887         mov.l           %d2,%d3                  3887         mov.l           %d2,%d3                 # d3 = update[7:0]
3888         lsr.w           &0x8,%d2                 3888         lsr.w           &0x8,%d2                # d2 = update[15:8]
3889                                                  3889 
3890 # mask interrupt levels 0-6. save old mask va    3890 # mask interrupt levels 0-6. save old mask value.
3891         mov.w           %sr,%d7                  3891         mov.w           %sr,%d7                 # save current SR
3892         ori.w           &0x0700,%sr              3892         ori.w           &0x0700,%sr             # inhibit interrupts
3893                                                  3893 
3894 # load the SFC and DFC with the appropriate m    3894 # load the SFC and DFC with the appropriate mode.
3895         movc            %sfc,%d6                 3895         movc            %sfc,%d6                # save old SFC/DFC
3896         movc            %d0,%sfc                 3896         movc            %d0,%sfc                # load new sfc
3897         movc            %d0,%dfc                 3897         movc            %d0,%dfc                # load new dfc
3898                                                  3898 
3899 # pre-load the operand ATC. no page faults sh    3899 # pre-load the operand ATC. no page faults should occur here because
3900 # _real_lock_page() should have taken care of    3900 # _real_lock_page() should have taken care of this.
3901         plpaw           (%a1)                    3901         plpaw           (%a1)                   # load atc for ADDR
3902         plpaw           (%a2)                    3902         plpaw           (%a2)                   # load atc for ADDR+1
3903                                                  3903 
3904 # push the operand lines from the cache if th    3904 # push the operand lines from the cache if they exist.
3905         cpushl          %dc,(%a1)                3905         cpushl          %dc,(%a1)               # push dirty data
3906         cpushl          %dc,(%a2)                3906         cpushl          %dc,(%a2)               # push dirty data
3907                                                  3907 
3908 # load the BUSCR values.                         3908 # load the BUSCR values.
3909         mov.l           &0x80000000,%a1          3909         mov.l           &0x80000000,%a1         # assert LOCK* buscr value
3910         mov.l           &0xa0000000,%a2          3910         mov.l           &0xa0000000,%a2         # assert LOCKE* buscr value
3911         mov.l           &0x00000000,%a3          3911         mov.l           &0x00000000,%a3         # buscr unlock value
3912                                                  3912 
3913 # pre-load the instruction cache for the foll    3913 # pre-load the instruction cache for the following algorithm.
3914 # this will minimize the number of cycles tha    3914 # this will minimize the number of cycles that LOCK* will be asserted.
3915         bra.b           CASW_ENTER               3915         bra.b           CASW_ENTER              # start pre-loading icache
3916                                                  3916 
3917 #                                                3917 #
3918 # D0 = dst operand <-                            3918 # D0 = dst operand <-
3919 # D1 = update[15:8] operand                      3919 # D1 = update[15:8] operand
3920 # D2 = update[7:0]  operand                      3920 # D2 = update[7:0]  operand
3921 # D3 = xxxxxxxx                                  3921 # D3 = xxxxxxxx
3922 # D4 = compare[15:0] operand                     3922 # D4 = compare[15:0] operand
3923 # D5 = xxxxxxxx                                  3923 # D5 = xxxxxxxx
3924 # D6 = old SFC/DFC                               3924 # D6 = old SFC/DFC
3925 # D7 = old SR                                    3925 # D7 = old SR
3926 # A0 = ADDR                                      3926 # A0 = ADDR
3927 # A1 = bus LOCK*  value                          3927 # A1 = bus LOCK*  value
3928 # A2 = bus LOCKE* value                          3928 # A2 = bus LOCKE* value
3929 # A3 = bus unlock value                          3929 # A3 = bus unlock value
3930 # A4 = xxxxxxxx                                  3930 # A4 = xxxxxxxx
3931 # A5 = xxxxxxxx                                  3931 # A5 = xxxxxxxx
3932 #                                                3932 #
3933         align           0x10                     3933         align           0x10
3934 CASW_START:                                      3934 CASW_START:
3935         movc            %a1,%buscr               3935         movc            %a1,%buscr              # assert LOCK*
3936         movs.w          (%a0),%d0                3936         movs.w          (%a0),%d0               # fetch Dest[15:0]
3937         cmp.w           %d0,%d4                  3937         cmp.w           %d0,%d4                 # Dest - Compare
3938         bne.b           CASW_NOUPDATE            3938         bne.b           CASW_NOUPDATE
3939         bra.b           CASW_UPDATE              3939         bra.b           CASW_UPDATE
3940 CASW_ENTER:                                      3940 CASW_ENTER:
3941         bra.b           ~+16                     3941         bra.b           ~+16
3942                                                  3942 
3943 CASW_UPDATE:                                     3943 CASW_UPDATE:
3944         movs.b          %d2,(%a0)+               3944         movs.b          %d2,(%a0)+              # Update[15:8] -> DEST
3945         movc            %a2,%buscr               3945         movc            %a2,%buscr              # assert LOCKE*
3946         movs.b          %d3,(%a0)                3946         movs.b          %d3,(%a0)               # Update[7:0] -> DEST+0x1
3947         bra.b           CASW_UPDATE2             3947         bra.b           CASW_UPDATE2
3948         bra.b           ~+16                     3948         bra.b           ~+16
3949                                                  3949 
3950 CASW_UPDATE2:                                    3950 CASW_UPDATE2:
3951         movc            %a3,%buscr               3951         movc            %a3,%buscr              # unlock the bus
3952         bra.b           casw_update_done         3952         bra.b           casw_update_done
3953         nop                                      3953         nop
3954         nop                                      3954         nop
3955         nop                                      3955         nop
3956         nop                                      3956         nop
3957         bra.b           ~+16                     3957         bra.b           ~+16
3958                                                  3958 
3959 CASW_NOUPDATE:                                   3959 CASW_NOUPDATE:
3960         ror.l           &0x8,%d0                 3960         ror.l           &0x8,%d0                # get Dest[15:8]
3961         movs.b          %d0,(%a0)+               3961         movs.b          %d0,(%a0)+              # Dest[15:8] -> DEST
3962         movc            %a2,%buscr               3962         movc            %a2,%buscr              # assert LOCKE*
3963         rol.l           &0x8,%d0                 3963         rol.l           &0x8,%d0                # get Dest[7:0]
3964         bra.b           CASW_NOUPDATE2           3964         bra.b           CASW_NOUPDATE2
3965         bra.b           ~+16                     3965         bra.b           ~+16
3966                                                  3966 
3967 CASW_NOUPDATE2:                                  3967 CASW_NOUPDATE2:
3968         movs.b          %d0,(%a0)                3968         movs.b          %d0,(%a0)               # Dest[7:0] -> DEST+0x1
3969         movc            %a3,%buscr               3969         movc            %a3,%buscr              # unlock the bus
3970         bra.b           casw_noupdate_done       3970         bra.b           casw_noupdate_done
3971         nop                                      3971         nop
3972         nop                                      3972         nop
3973         bra.b           ~+16                     3973         bra.b           ~+16
3974                                                  3974 
3975 CASW_FILLER:                                     3975 CASW_FILLER:
3976         nop                                      3976         nop
3977         nop                                      3977         nop
3978         nop                                      3978         nop
3979         nop                                      3979         nop
3980         nop                                      3980         nop
3981         nop                                      3981         nop
3982         nop                                      3982         nop
3983         bra.b           CASW_START               3983         bra.b           CASW_START
3984                                                  3984 
3985 #############################################    3985 #################################################################
3986 # THIS MUST BE THE STATE OF THE INTEGER REGIS    3986 # THIS MUST BE THE STATE OF THE INTEGER REGISTER FILE UPON      #
3987 # CALLING _isp_cas_finish().                     3987 # CALLING _isp_cas_finish().                                    #
3988 #                                                3988 #                                                               #
3989 # D0 = destination[15:0] operand                 3989 # D0 = destination[15:0] operand                                #
3990 # D1 = 'xxxxxx11 -> no reg update; 'xxxxxx00     3990 # D1 = 'xxxxxx11 -> no reg update; 'xxxxxx00 -> update required #
3991 # D2 = xxxxxxxx                                  3991 # D2 = xxxxxxxx                                                 #
3992 # D3 = xxxxxxxx                                  3992 # D3 = xxxxxxxx                                                 #
3993 # D4 = compare[15:0] operand                     3993 # D4 = compare[15:0] operand                                    #
3994 # D5 = xxxxxxxx                                  3994 # D5 = xxxxxxxx                                                 #
3995 # D6 = xxxxxxxx                                  3995 # D6 = xxxxxxxx                                                 #
3996 # D7 = xxxxxxxx                                  3996 # D7 = xxxxxxxx                                                 #
3997 # A0 = xxxxxxxx                                  3997 # A0 = xxxxxxxx                                                 #
3998 # A1 = xxxxxxxx                                  3998 # A1 = xxxxxxxx                                                 #
3999 # A2 = xxxxxxxx                                  3999 # A2 = xxxxxxxx                                                 #
4000 # A3 = xxxxxxxx                                  4000 # A3 = xxxxxxxx                                                 #
4001 # A4 = xxxxxxxx                                  4001 # A4 = xxxxxxxx                                                 #
4002 # A5 = xxxxxxxx                                  4002 # A5 = xxxxxxxx                                                 #
4003 # A6 = frame pointer                             4003 # A6 = frame pointer                                            #
4004 # A7 = stack pointer                             4004 # A7 = stack pointer                                            #
4005 #############################################    4005 #################################################################
4006                                                  4006 
4007 casw_noupdate_done:                              4007 casw_noupdate_done:
4008                                                  4008 
4009 # restore previous SFC/DFC value.                4009 # restore previous SFC/DFC value.
4010         movc            %d6,%sfc                 4010         movc            %d6,%sfc                # restore old SFC
4011         movc            %d6,%dfc                 4011         movc            %d6,%dfc                # restore old DFC
4012                                                  4012 
4013 # restore previous interrupt mask level.         4013 # restore previous interrupt mask level.
4014         mov.w           %d7,%sr                  4014         mov.w           %d7,%sr                 # restore old SR
4015                                                  4015 
4016         sf              %d1                      4016         sf              %d1                     # indicate no update was done
4017         bra.l           _isp_cas_finish          4017         bra.l           _isp_cas_finish
4018                                                  4018 
4019 casw_update_done:                                4019 casw_update_done:
4020                                                  4020 
4021 # restore previous SFC/DFC value.                4021 # restore previous SFC/DFC value.
4022         movc            %d6,%sfc                 4022         movc            %d6,%sfc                # restore old SFC
4023         movc            %d6,%dfc                 4023         movc            %d6,%dfc                # restore old DFC
4024                                                  4024 
4025 # restore previous interrupt mask level.         4025 # restore previous interrupt mask level.
4026         mov.w           %d7,%sr                  4026         mov.w           %d7,%sr                 # restore old SR
4027                                                  4027 
4028         st              %d1                      4028         st              %d1                     # indicate update was done
4029         bra.l           _isp_cas_finish          4029         bra.l           _isp_cas_finish
4030                                                  4030 
4031 ################                                 4031 ################
4032                                                  4032 
4033 # there are two possible mis-aligned cases fo    4033 # there are two possible mis-aligned cases for longword cas. they
4034 # are separated because the final write which    4034 # are separated because the final write which asserts LOCKE* must
4035 # be an aligned write.                           4035 # be an aligned write.
4036 casl:                                            4036 casl:
4037         mov.l           %a0,%a1                  4037         mov.l           %a0,%a1                 # make copy for plpaw1
4038         mov.l           %a0,%a2                  4038         mov.l           %a0,%a2                 # make copy for plpaw2
4039         addq.l          &0x3,%a2                 4039         addq.l          &0x3,%a2                # plpaw2 points to end of longword
4040                                                  4040 
4041         mov.l           %a0,%d1                  4041         mov.l           %a0,%d1                 # byte or word misaligned?
4042         btst            &0x0,%d1                 4042         btst            &0x0,%d1
4043         bne.w           casl2                    4043         bne.w           casl2                   # byte misaligned
4044                                                  4044 
4045         mov.l           %d2,%d3                  4045         mov.l           %d2,%d3                 # d3 = update[15:0]
4046         swap            %d2                      4046         swap            %d2                     # d2 = update[31:16]
4047                                                  4047 
4048 # mask interrupts levels 0-6. save old mask v    4048 # mask interrupts levels 0-6. save old mask value.
4049         mov.w           %sr,%d7                  4049         mov.w           %sr,%d7                 # save current SR
4050         ori.w           &0x0700,%sr              4050         ori.w           &0x0700,%sr             # inhibit interrupts
4051                                                  4051 
4052 # load the SFC and DFC with the appropriate m    4052 # load the SFC and DFC with the appropriate mode.
4053         movc            %sfc,%d6                 4053         movc            %sfc,%d6                # save old SFC/DFC
4054         movc            %d0,%sfc                 4054         movc            %d0,%sfc                # load new sfc
4055         movc            %d0,%dfc                 4055         movc            %d0,%dfc                # load new dfc
4056                                                  4056 
4057 # pre-load the operand ATC. no page faults sh    4057 # pre-load the operand ATC. no page faults should occur here because
4058 # _real_lock_page() should have taken care of    4058 # _real_lock_page() should have taken care of this.
4059         plpaw           (%a1)                    4059         plpaw           (%a1)                   # load atc for ADDR
4060         plpaw           (%a2)                    4060         plpaw           (%a2)                   # load atc for ADDR+3
4061                                                  4061 
4062 # push the operand lines from the cache if th    4062 # push the operand lines from the cache if they exist.
4063         cpushl          %dc,(%a1)                4063         cpushl          %dc,(%a1)               # push dirty data
4064         cpushl          %dc,(%a2)                4064         cpushl          %dc,(%a2)               # push dirty data
4065                                                  4065 
4066 # load the BUSCR values.                         4066 # load the BUSCR values.
4067         mov.l           &0x80000000,%a1          4067         mov.l           &0x80000000,%a1         # assert LOCK* buscr value
4068         mov.l           &0xa0000000,%a2          4068         mov.l           &0xa0000000,%a2         # assert LOCKE* buscr value
4069         mov.l           &0x00000000,%a3          4069         mov.l           &0x00000000,%a3         # buscr unlock value
4070                                                  4070 
4071         bra.b           CASL_ENTER               4071         bra.b           CASL_ENTER              # start pre-loading icache
4072                                                  4072 
4073 #                                                4073 #
4074 # D0 = dst operand <-                            4074 # D0 = dst operand <-
4075 # D1 = xxxxxxxx                                  4075 # D1 = xxxxxxxx
4076 # D2 = update[31:16] operand                     4076 # D2 = update[31:16] operand
4077 # D3 = update[15:0]  operand                     4077 # D3 = update[15:0]  operand
4078 # D4 = compare[31:0] operand                     4078 # D4 = compare[31:0] operand
4079 # D5 = xxxxxxxx                                  4079 # D5 = xxxxxxxx
4080 # D6 = old SFC/DFC                               4080 # D6 = old SFC/DFC
4081 # D7 = old SR                                    4081 # D7 = old SR
4082 # A0 = ADDR                                      4082 # A0 = ADDR
4083 # A1 = bus LOCK*  value                          4083 # A1 = bus LOCK*  value
4084 # A2 = bus LOCKE* value                          4084 # A2 = bus LOCKE* value
4085 # A3 = bus unlock value                          4085 # A3 = bus unlock value
4086 # A4 = xxxxxxxx                                  4086 # A4 = xxxxxxxx
4087 # A5 = xxxxxxxx                                  4087 # A5 = xxxxxxxx
4088 #                                                4088 #
4089         align           0x10                     4089         align           0x10
4090 CASL_START:                                      4090 CASL_START:
4091         movc            %a1,%buscr               4091         movc            %a1,%buscr              # assert LOCK*
4092         movs.l          (%a0),%d0                4092         movs.l          (%a0),%d0               # fetch Dest[31:0]
4093         cmp.l           %d0,%d4                  4093         cmp.l           %d0,%d4                 # Dest - Compare
4094         bne.b           CASL_NOUPDATE            4094         bne.b           CASL_NOUPDATE
4095         bra.b           CASL_UPDATE              4095         bra.b           CASL_UPDATE
4096 CASL_ENTER:                                      4096 CASL_ENTER:
4097         bra.b           ~+16                     4097         bra.b           ~+16
4098                                                  4098 
4099 CASL_UPDATE:                                     4099 CASL_UPDATE:
4100         movs.w          %d2,(%a0)+               4100         movs.w          %d2,(%a0)+              # Update[31:16] -> DEST
4101         movc            %a2,%buscr               4101         movc            %a2,%buscr              # assert LOCKE*
4102         movs.w          %d3,(%a0)                4102         movs.w          %d3,(%a0)               # Update[15:0] -> DEST+0x2
4103         bra.b           CASL_UPDATE2             4103         bra.b           CASL_UPDATE2
4104         bra.b           ~+16                     4104         bra.b           ~+16
4105                                                  4105 
4106 CASL_UPDATE2:                                    4106 CASL_UPDATE2:
4107         movc            %a3,%buscr               4107         movc            %a3,%buscr              # unlock the bus
4108         bra.b           casl_update_done         4108         bra.b           casl_update_done
4109         nop                                      4109         nop
4110         nop                                      4110         nop
4111         nop                                      4111         nop
4112         nop                                      4112         nop
4113         bra.b           ~+16                     4113         bra.b           ~+16
4114                                                  4114 
4115 CASL_NOUPDATE:                                   4115 CASL_NOUPDATE:
4116         swap            %d0                      4116         swap            %d0                     # get Dest[31:16]
4117         movs.w          %d0,(%a0)+               4117         movs.w          %d0,(%a0)+              # Dest[31:16] -> DEST
4118         swap            %d0                      4118         swap            %d0                     # get Dest[15:0]
4119         movc            %a2,%buscr               4119         movc            %a2,%buscr              # assert LOCKE*
4120         bra.b           CASL_NOUPDATE2           4120         bra.b           CASL_NOUPDATE2
4121         bra.b           ~+16                     4121         bra.b           ~+16
4122                                                  4122 
4123 CASL_NOUPDATE2:                                  4123 CASL_NOUPDATE2:
4124         movs.w          %d0,(%a0)                4124         movs.w          %d0,(%a0)               # Dest[15:0] -> DEST+0x2
4125         movc            %a3,%buscr               4125         movc            %a3,%buscr              # unlock the bus
4126         bra.b           casl_noupdate_done       4126         bra.b           casl_noupdate_done
4127         nop                                      4127         nop
4128         nop                                      4128         nop
4129         bra.b           ~+16                     4129         bra.b           ~+16
4130                                                  4130 
4131 CASL_FILLER:                                     4131 CASL_FILLER:
4132         nop                                      4132         nop
4133         nop                                      4133         nop
4134         nop                                      4134         nop
4135         nop                                      4135         nop
4136         nop                                      4136         nop
4137         nop                                      4137         nop
4138         nop                                      4138         nop
4139         bra.b           CASL_START               4139         bra.b           CASL_START
4140                                                  4140 
4141 #############################################    4141 #################################################################
4142 # THIS MUST BE THE STATE OF THE INTEGER REGIS    4142 # THIS MUST BE THE STATE OF THE INTEGER REGISTER FILE UPON      #
4143 # CALLING _isp_cas_finish().                     4143 # CALLING _isp_cas_finish().                                    #
4144 #                                                4144 #                                                               #
4145 # D0 = destination[31:0] operand                 4145 # D0 = destination[31:0] operand                                #
4146 # D1 = 'xxxxxx11 -> no reg update; 'xxxxxx00     4146 # D1 = 'xxxxxx11 -> no reg update; 'xxxxxx00 -> update required #
4147 # D2 = xxxxxxxx                                  4147 # D2 = xxxxxxxx                                                 #
4148 # D3 = xxxxxxxx                                  4148 # D3 = xxxxxxxx                                                 #
4149 # D4 = compare[31:0] operand                     4149 # D4 = compare[31:0] operand                                    #
4150 # D5 = xxxxxxxx                                  4150 # D5 = xxxxxxxx                                                 #
4151 # D6 = xxxxxxxx                                  4151 # D6 = xxxxxxxx                                                 #
4152 # D7 = xxxxxxxx                                  4152 # D7 = xxxxxxxx                                                 #
4153 # A0 = xxxxxxxx                                  4153 # A0 = xxxxxxxx                                                 #
4154 # A1 = xxxxxxxx                                  4154 # A1 = xxxxxxxx                                                 #
4155 # A2 = xxxxxxxx                                  4155 # A2 = xxxxxxxx                                                 #
4156 # A3 = xxxxxxxx                                  4156 # A3 = xxxxxxxx                                                 #
4157 # A4 = xxxxxxxx                                  4157 # A4 = xxxxxxxx                                                 #
4158 # A5 = xxxxxxxx                                  4158 # A5 = xxxxxxxx                                                 #
4159 # A6 = frame pointer                             4159 # A6 = frame pointer                                            #
4160 # A7 = stack pointer                             4160 # A7 = stack pointer                                            #
4161 #############################################    4161 #################################################################
4162                                                  4162 
4163 casl_noupdate_done:                              4163 casl_noupdate_done:
4164                                                  4164 
4165 # restore previous SFC/DFC value.                4165 # restore previous SFC/DFC value.
4166         movc            %d6,%sfc                 4166         movc            %d6,%sfc                # restore old SFC
4167         movc            %d6,%dfc                 4167         movc            %d6,%dfc                # restore old DFC
4168                                                  4168 
4169 # restore previous interrupt mask level.         4169 # restore previous interrupt mask level.
4170         mov.w           %d7,%sr                  4170         mov.w           %d7,%sr                 # restore old SR
4171                                                  4171 
4172         sf              %d1                      4172         sf              %d1                     # indicate no update was done
4173         bra.l           _isp_cas_finish          4173         bra.l           _isp_cas_finish
4174                                                  4174 
4175 casl_update_done:                                4175 casl_update_done:
4176                                                  4176 
4177 # restore previous SFC/DFC value.                4177 # restore previous SFC/DFC value.
4178         movc            %d6,%sfc                 4178         movc            %d6,%sfc                # restore old SFC
4179         movc            %d6,%dfc                 4179         movc            %d6,%dfc                # restore old DFC
4180                                                  4180 
4181 # restore previous interrupts mask level.        4181 # restore previous interrupts mask level.
4182         mov.w           %d7,%sr                  4182         mov.w           %d7,%sr                 # restore old SR
4183                                                  4183 
4184         st              %d1                      4184         st              %d1                     # indicate update was done
4185         bra.l           _isp_cas_finish          4185         bra.l           _isp_cas_finish
4186                                                  4186 
4187 #######################################          4187 #######################################
4188 casl2:                                           4188 casl2:
4189         mov.l           %d2,%d5                  4189         mov.l           %d2,%d5                 # d5 = Update[7:0]
4190         lsr.l           &0x8,%d2                 4190         lsr.l           &0x8,%d2
4191         mov.l           %d2,%d3                  4191         mov.l           %d2,%d3                 # d3 = Update[23:8]
4192         swap            %d2                      4192         swap            %d2                     # d2 = Update[31:24]
4193                                                  4193 
4194 # mask interrupts levels 0-6. save old mask v    4194 # mask interrupts levels 0-6. save old mask value.
4195         mov.w           %sr,%d7                  4195         mov.w           %sr,%d7                 # save current SR
4196         ori.w           &0x0700,%sr              4196         ori.w           &0x0700,%sr             # inhibit interrupts
4197                                                  4197 
4198 # load the SFC and DFC with the appropriate m    4198 # load the SFC and DFC with the appropriate mode.
4199         movc            %sfc,%d6                 4199         movc            %sfc,%d6                # save old SFC/DFC
4200         movc            %d0,%sfc                 4200         movc            %d0,%sfc                # load new sfc
4201         movc            %d0,%dfc                 4201         movc            %d0,%dfc                # load new dfc
4202                                                  4202 
4203 # pre-load the operand ATC. no page faults sh    4203 # pre-load the operand ATC. no page faults should occur here because
4204 # _real_lock_page() should have taken care of    4204 # _real_lock_page() should have taken care of this already.
4205         plpaw           (%a1)                    4205         plpaw           (%a1)                   # load atc for ADDR
4206         plpaw           (%a2)                    4206         plpaw           (%a2)                   # load atc for ADDR+3
4207                                                  4207 
4208 # puch the operand lines from the cache if th    4208 # puch the operand lines from the cache if they exist.
4209         cpushl          %dc,(%a1)                4209         cpushl          %dc,(%a1)               # push dirty data
4210         cpushl          %dc,(%a2)                4210         cpushl          %dc,(%a2)               # push dirty data
4211                                                  4211 
4212 # load the BUSCR values.                         4212 # load the BUSCR values.
4213         mov.l           &0x80000000,%a1          4213         mov.l           &0x80000000,%a1         # assert LOCK* buscr value
4214         mov.l           &0xa0000000,%a2          4214         mov.l           &0xa0000000,%a2         # assert LOCKE* buscr value
4215         mov.l           &0x00000000,%a3          4215         mov.l           &0x00000000,%a3         # buscr unlock value
4216                                                  4216 
4217 # pre-load the instruction cache for the foll    4217 # pre-load the instruction cache for the following algorithm.
4218 # this will minimize the number of cycles tha    4218 # this will minimize the number of cycles that LOCK* will be asserted.
4219         bra.b           CASL2_ENTER              4219         bra.b           CASL2_ENTER             # start pre-loading icache
4220                                                  4220 
4221 #                                                4221 #
4222 # D0 = dst operand <-                            4222 # D0 = dst operand <-
4223 # D1 = xxxxxxxx                                  4223 # D1 = xxxxxxxx
4224 # D2 = update[31:24] operand                     4224 # D2 = update[31:24] operand
4225 # D3 = update[23:8]  operand                     4225 # D3 = update[23:8]  operand
4226 # D4 = compare[31:0] operand                     4226 # D4 = compare[31:0] operand
4227 # D5 = update[7:0]  operand                      4227 # D5 = update[7:0]  operand
4228 # D6 = old SFC/DFC                               4228 # D6 = old SFC/DFC
4229 # D7 = old SR                                    4229 # D7 = old SR
4230 # A0 = ADDR                                      4230 # A0 = ADDR
4231 # A1 = bus LOCK*  value                          4231 # A1 = bus LOCK*  value
4232 # A2 = bus LOCKE* value                          4232 # A2 = bus LOCKE* value
4233 # A3 = bus unlock value                          4233 # A3 = bus unlock value
4234 # A4 = xxxxxxxx                                  4234 # A4 = xxxxxxxx
4235 # A5 = xxxxxxxx                                  4235 # A5 = xxxxxxxx
4236 #                                                4236 #
4237         align           0x10                     4237         align           0x10
4238 CASL2_START:                                     4238 CASL2_START:
4239         movc            %a1,%buscr               4239         movc            %a1,%buscr              # assert LOCK*
4240         movs.l          (%a0),%d0                4240         movs.l          (%a0),%d0               # fetch Dest[31:0]
4241         cmp.l           %d0,%d4                  4241         cmp.l           %d0,%d4                 # Dest - Compare
4242         bne.b           CASL2_NOUPDATE           4242         bne.b           CASL2_NOUPDATE
4243         bra.b           CASL2_UPDATE             4243         bra.b           CASL2_UPDATE
4244 CASL2_ENTER:                                     4244 CASL2_ENTER:
4245         bra.b           ~+16                     4245         bra.b           ~+16
4246                                                  4246 
4247 CASL2_UPDATE:                                    4247 CASL2_UPDATE:
4248         movs.b          %d2,(%a0)+               4248         movs.b          %d2,(%a0)+              # Update[31:24] -> DEST
4249         movs.w          %d3,(%a0)+               4249         movs.w          %d3,(%a0)+              # Update[23:8] -> DEST+0x1
4250         movc            %a2,%buscr               4250         movc            %a2,%buscr              # assert LOCKE*
4251         bra.b           CASL2_UPDATE2            4251         bra.b           CASL2_UPDATE2
4252         bra.b           ~+16                     4252         bra.b           ~+16
4253                                                  4253 
4254 CASL2_UPDATE2:                                   4254 CASL2_UPDATE2:
4255         movs.b          %d5,(%a0)                4255         movs.b          %d5,(%a0)               # Update[7:0] -> DEST+0x3
4256         movc            %a3,%buscr               4256         movc            %a3,%buscr              # unlock the bus
4257         bra.w           casl_update_done         4257         bra.w           casl_update_done
4258         nop                                      4258         nop
4259         bra.b           ~+16                     4259         bra.b           ~+16
4260                                                  4260 
4261 CASL2_NOUPDATE:                                  4261 CASL2_NOUPDATE:
4262         rol.l           &0x8,%d0                 4262         rol.l           &0x8,%d0                # get Dest[31:24]
4263         movs.b          %d0,(%a0)+               4263         movs.b          %d0,(%a0)+              # Dest[31:24] -> DEST
4264         swap            %d0                      4264         swap            %d0                     # get Dest[23:8]
4265         movs.w          %d0,(%a0)+               4265         movs.w          %d0,(%a0)+              # Dest[23:8] -> DEST+0x1
4266         bra.b           CASL2_NOUPDATE2          4266         bra.b           CASL2_NOUPDATE2
4267         bra.b           ~+16                     4267         bra.b           ~+16
4268                                                  4268 
4269 CASL2_NOUPDATE2:                                 4269 CASL2_NOUPDATE2:
4270         rol.l           &0x8,%d0                 4270         rol.l           &0x8,%d0                # get Dest[7:0]
4271         movc            %a2,%buscr               4271         movc            %a2,%buscr              # assert LOCKE*
4272         movs.b          %d0,(%a0)                4272         movs.b          %d0,(%a0)               # Dest[7:0] -> DEST+0x3
4273         bra.b           CASL2_NOUPDATE3          4273         bra.b           CASL2_NOUPDATE3
4274         nop                                      4274         nop
4275         bra.b           ~+16                     4275         bra.b           ~+16
4276                                                  4276 
4277 CASL2_NOUPDATE3:                                 4277 CASL2_NOUPDATE3:
4278         movc            %a3,%buscr               4278         movc            %a3,%buscr              # unlock the bus
4279         bra.w           casl_noupdate_done       4279         bra.w           casl_noupdate_done
4280         nop                                      4280         nop
4281         nop                                      4281         nop
4282         nop                                      4282         nop
4283         bra.b           ~+16                     4283         bra.b           ~+16
4284                                                  4284 
4285 CASL2_FILLER:                                    4285 CASL2_FILLER:
4286         nop                                      4286         nop
4287         nop                                      4287         nop
4288         nop                                      4288         nop
4289         nop                                      4289         nop
4290         nop                                      4290         nop
4291         nop                                      4291         nop
4292         nop                                      4292         nop
4293         bra.b           CASL2_START              4293         bra.b           CASL2_START
4294                                                  4294 
4295 ####                                             4295 ####
4296 ####                                             4296 ####
4297 # end label used by _isp_cas_inrange()           4297 # end label used by _isp_cas_inrange()
4298         global          _CASHI                   4298         global          _CASHI
4299 _CASHI:                                          4299 _CASHI:
                                                      

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php