| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | ############################################################################### | 
 | 2 | # | 
 | 3 | # switch_to.S: context switch operation | 
 | 4 | # | 
 | 5 | # Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. | 
 | 6 | # Written by David Howells (dhowells@redhat.com) | 
 | 7 | # | 
 | 8 | # This program is free software; you can redistribute it and/or | 
 | 9 | # modify it under the terms of the GNU General Public License | 
 | 10 | # as published by the Free Software Foundation; either version | 
 | 11 | # 2 of the License, or (at your option) any later version. | 
 | 12 | # | 
 | 13 | ############################################################################### | 
| David Howells | 84e8cd6 | 2006-07-10 04:44:55 -0700 | [diff] [blame] | 14 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 15 | #include <linux/linkage.h> | 
 | 16 | #include <asm/thread_info.h> | 
 | 17 | #include <asm/processor.h> | 
 | 18 | #include <asm/registers.h> | 
 | 19 | #include <asm/spr-regs.h> | 
 | 20 |  | 
 | 21 | .macro LEDS val | 
 | 22 | 	setlos		#~\val,gr27 | 
 | 23 | 	st		gr27,@(gr30,gr0) | 
 | 24 | 	membar | 
 | 25 | 	dcf		@(gr30,gr0) | 
 | 26 | .endm | 
 | 27 |  | 
 | 28 | 	.section	.sdata | 
 | 29 | 	.balign		8 | 
 | 30 |  | 
 | 31 | 	# address of frame 0 (userspace) on current kernel stack | 
 | 32 | 	.globl		__kernel_frame0_ptr | 
 | 33 | __kernel_frame0_ptr: | 
| David Howells | 84e8cd6 | 2006-07-10 04:44:55 -0700 | [diff] [blame] | 34 | 	.long		init_thread_union + THREAD_SIZE - FRV_FRAME0_SIZE | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 35 |  | 
 | 36 | 	# address of current task | 
 | 37 | 	.globl		__kernel_current_task | 
 | 38 | __kernel_current_task: | 
 | 39 | 	.long		init_task | 
 | 40 |  | 
 | 41 | 	.section	.text | 
 | 42 | 	.balign		4 | 
 | 43 |  | 
 | 44 | ############################################################################### | 
 | 45 | # | 
 | 46 | # struct task_struct *__switch_to(struct thread_struct *prev_thread, | 
 | 47 | #				  struct thread_struct *next_thread, | 
 | 48 | #				  struct task_struct *prev) | 
 | 49 | # | 
 | 50 | ############################################################################### | 
 | 51 | 	.globl		__switch_to | 
 | 52 | __switch_to: | 
 | 53 | 	# save outgoing process's context | 
 | 54 | 	sethi.p		%hi(__switch_back),gr13 | 
 | 55 | 	setlo		%lo(__switch_back),gr13 | 
 | 56 | 	movsg		lr,gr12 | 
 | 57 |  | 
 | 58 | 	stdi		gr28,@(gr8,#__THREAD_FRAME) | 
 | 59 | 	sti		sp  ,@(gr8,#__THREAD_SP) | 
 | 60 | 	sti		fp  ,@(gr8,#__THREAD_FP) | 
 | 61 | 	stdi		gr12,@(gr8,#__THREAD_LR) | 
 | 62 | 	stdi		gr16,@(gr8,#__THREAD_GR(16)) | 
 | 63 | 	stdi		gr18,@(gr8,#__THREAD_GR(18)) | 
 | 64 | 	stdi		gr20,@(gr8,#__THREAD_GR(20)) | 
 | 65 | 	stdi		gr22,@(gr8,#__THREAD_GR(22)) | 
 | 66 | 	stdi		gr24,@(gr8,#__THREAD_GR(24)) | 
 | 67 | 	stdi.p		gr26,@(gr8,#__THREAD_GR(26)) | 
 | 68 |  | 
 | 69 | 	or		gr8,gr8,gr22 | 
 | 70 | 	ldi.p		@(gr8,#__THREAD_USER),gr8 | 
 | 71 | 	call		save_user_regs | 
 | 72 | 	or		gr22,gr22,gr8 | 
 | 73 | 	 | 
 | 74 | 	# retrieve the new context | 
 | 75 | 	sethi.p		%hi(__kernel_frame0_ptr),gr6 | 
 | 76 | 	setlo		%lo(__kernel_frame0_ptr),gr6 | 
 | 77 | 	movsg		psr,gr4 | 
 | 78 |  | 
 | 79 | 	lddi.p		@(gr9,#__THREAD_FRAME),gr10 | 
 | 80 | 	or		gr10,gr10,gr27		; save prev for the return value | 
 | 81 |  | 
 | 82 | 	ldi		@(gr11,#4),gr19		; get new_current->thread_info | 
 | 83 |  | 
 | 84 | 	lddi		@(gr9,#__THREAD_SP),gr12 | 
 | 85 | 	ldi		@(gr9,#__THREAD_LR),gr14 | 
 | 86 | 	ldi		@(gr9,#__THREAD_PC),gr18 | 
 | 87 | 	ldi.p		@(gr9,#__THREAD_FRAME0),gr7 | 
 | 88 |  | 
 | 89 | 	# actually switch kernel contexts with ordinary exceptions disabled | 
 | 90 | 	andi		gr4,#~PSR_ET,gr5 | 
 | 91 | 	movgs		gr5,psr | 
 | 92 |  | 
 | 93 | 	or.p		gr10,gr0,gr28		; set __frame | 
 | 94 | 	or		gr11,gr0,gr29		; set __current | 
 | 95 | 	or.p		gr12,gr0,sp | 
 | 96 | 	or		gr13,gr0,fp | 
 | 97 | 	or		gr19,gr0,gr15		; set __current_thread_info | 
 | 98 |  | 
 | 99 | 	sti		gr7,@(gr6,#0)		; set __kernel_frame0_ptr | 
 | 100 | 	sti		gr29,@(gr6,#4)		; set __kernel_current_task | 
 | 101 |  | 
 | 102 | 	movgs		gr14,lr | 
 | 103 | 	bar | 
 | 104 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 105 | 	# jump to __switch_back or ret_from_fork as appropriate | 
 | 106 | 	# - move prev to GR8 | 
 | 107 | 	movgs		gr4,psr | 
 | 108 | 	jmpl.p		@(gr18,gr0) | 
 | 109 | 	or		gr27,gr27,gr8 | 
 | 110 |  | 
 | 111 | ############################################################################### | 
 | 112 | # | 
 | 113 | # restore incoming process's context | 
 | 114 | # - on entry: | 
 | 115 | #   - SP, FP, LR, GR15, GR28 and GR29 will have been set up appropriately | 
 | 116 | #   - GR8 will point to the outgoing task_struct | 
 | 117 | #   - GR9 will point to the incoming thread_struct | 
 | 118 | # | 
 | 119 | ############################################################################### | 
 | 120 | __switch_back: | 
 | 121 | 	lddi		@(gr9,#__THREAD_GR(16)),gr16 | 
 | 122 | 	lddi		@(gr9,#__THREAD_GR(18)),gr18 | 
 | 123 | 	lddi		@(gr9,#__THREAD_GR(20)),gr20 | 
 | 124 | 	lddi		@(gr9,#__THREAD_GR(22)),gr22 | 
 | 125 | 	lddi		@(gr9,#__THREAD_GR(24)),gr24 | 
 | 126 | 	lddi		@(gr9,#__THREAD_GR(26)),gr26 | 
 | 127 |  | 
 | 128 | 	# fall through into restore_user_regs() | 
 | 129 | 	ldi.p		@(gr9,#__THREAD_USER),gr8 | 
 | 130 | 	or		gr8,gr8,gr9 | 
 | 131 |  | 
 | 132 | ############################################################################### | 
 | 133 | # | 
 | 134 | # restore extra general regs and FP/Media regs | 
 | 135 | # - void *restore_user_regs(const struct user_context *target, void *retval) | 
 | 136 | # - on entry: | 
 | 137 | #   - GR8 will point to the user context to swap in | 
 | 138 | #   - GR9 will contain the value to be returned in GR8 (prev task on context switch) | 
 | 139 | # | 
 | 140 | ############################################################################### | 
 | 141 | 	.globl		restore_user_regs | 
 | 142 | restore_user_regs: | 
 | 143 | 	movsg		hsr0,gr6 | 
 | 144 | 	ori		gr6,#HSR0_GRHE|HSR0_FRLE|HSR0_FRHE,gr6 | 
 | 145 | 	movgs		gr6,hsr0 | 
 | 146 | 	movsg		hsr0,gr6 | 
 | 147 |  | 
 | 148 | 	movsg		psr,gr7 | 
 | 149 | 	ori		gr7,#PSR_EF|PSR_EM,gr7 | 
 | 150 | 	movgs		gr7,psr | 
 | 151 | 	movsg		psr,gr7 | 
 | 152 | 	srli		gr7,#24,gr7 | 
 | 153 | 	bar | 
 | 154 |  | 
 | 155 | 	lddi		@(gr8,#__FPMEDIA_MSR(0)),gr4 | 
 | 156 |  | 
 | 157 | 	movgs		gr4,msr0 | 
 | 158 | 	movgs		gr5,msr1 | 
 | 159 |  | 
 | 160 | 	lddfi		@(gr8,#__FPMEDIA_ACC(0)),fr16 | 
 | 161 | 	lddfi		@(gr8,#__FPMEDIA_ACC(2)),fr18 | 
 | 162 | 	ldbfi		@(gr8,#__FPMEDIA_ACCG(0)),fr20 | 
 | 163 | 	ldbfi		@(gr8,#__FPMEDIA_ACCG(1)),fr21 | 
 | 164 | 	ldbfi		@(gr8,#__FPMEDIA_ACCG(2)),fr22 | 
 | 165 | 	ldbfi		@(gr8,#__FPMEDIA_ACCG(3)),fr23 | 
 | 166 |  | 
 | 167 | 	mwtacc		fr16,acc0 | 
 | 168 | 	mwtacc		fr17,acc1 | 
 | 169 | 	mwtacc		fr18,acc2 | 
 | 170 | 	mwtacc		fr19,acc3 | 
 | 171 | 	mwtaccg		fr20,accg0 | 
 | 172 | 	mwtaccg		fr21,accg1 | 
 | 173 | 	mwtaccg		fr22,accg2 | 
 | 174 | 	mwtaccg		fr23,accg3 | 
 | 175 |  | 
 | 176 | 	# some CPUs have extra ACCx and ACCGx regs and maybe FSRx regs | 
 | 177 | 	subicc.p	gr7,#0x50,gr0,icc0 | 
 | 178 | 	subicc		gr7,#0x31,gr0,icc1 | 
 | 179 | 	beq		icc0,#0,__restore_acc_fr451 | 
 | 180 | 	beq		icc1,#0,__restore_acc_fr555 | 
 | 181 | __restore_acc_cont: | 
 | 182 |  | 
 | 183 | 	# some CPU's have GR32-GR63 | 
 | 184 | 	setlos		#HSR0_FRHE,gr4 | 
 | 185 | 	andcc		gr6,gr4,gr0,icc0 | 
 | 186 | 	beq		icc0,#1,__restore_skip_gr32_gr63 | 
 | 187 |  | 
 | 188 | 	lddi		@(gr8,#__INT_GR(32)),gr32 | 
 | 189 | 	lddi		@(gr8,#__INT_GR(34)),gr34 | 
 | 190 | 	lddi		@(gr8,#__INT_GR(36)),gr36 | 
 | 191 | 	lddi		@(gr8,#__INT_GR(38)),gr38 | 
 | 192 | 	lddi		@(gr8,#__INT_GR(40)),gr40 | 
 | 193 | 	lddi		@(gr8,#__INT_GR(42)),gr42 | 
 | 194 | 	lddi		@(gr8,#__INT_GR(44)),gr44 | 
 | 195 | 	lddi		@(gr8,#__INT_GR(46)),gr46 | 
 | 196 | 	lddi		@(gr8,#__INT_GR(48)),gr48 | 
 | 197 | 	lddi		@(gr8,#__INT_GR(50)),gr50 | 
 | 198 | 	lddi		@(gr8,#__INT_GR(52)),gr52 | 
 | 199 | 	lddi		@(gr8,#__INT_GR(54)),gr54 | 
 | 200 | 	lddi		@(gr8,#__INT_GR(56)),gr56 | 
 | 201 | 	lddi		@(gr8,#__INT_GR(58)),gr58 | 
 | 202 | 	lddi		@(gr8,#__INT_GR(60)),gr60 | 
 | 203 | 	lddi		@(gr8,#__INT_GR(62)),gr62 | 
 | 204 | __restore_skip_gr32_gr63: | 
 | 205 |  | 
 | 206 | 	# all CPU's have FR0-FR31 | 
 | 207 | 	lddfi		@(gr8,#__FPMEDIA_FR( 0)),fr0 | 
 | 208 | 	lddfi		@(gr8,#__FPMEDIA_FR( 2)),fr2 | 
 | 209 | 	lddfi		@(gr8,#__FPMEDIA_FR( 4)),fr4 | 
 | 210 | 	lddfi		@(gr8,#__FPMEDIA_FR( 6)),fr6 | 
 | 211 | 	lddfi		@(gr8,#__FPMEDIA_FR( 8)),fr8 | 
 | 212 | 	lddfi		@(gr8,#__FPMEDIA_FR(10)),fr10 | 
 | 213 | 	lddfi		@(gr8,#__FPMEDIA_FR(12)),fr12 | 
 | 214 | 	lddfi		@(gr8,#__FPMEDIA_FR(14)),fr14 | 
 | 215 | 	lddfi		@(gr8,#__FPMEDIA_FR(16)),fr16 | 
 | 216 | 	lddfi		@(gr8,#__FPMEDIA_FR(18)),fr18 | 
 | 217 | 	lddfi		@(gr8,#__FPMEDIA_FR(20)),fr20 | 
 | 218 | 	lddfi		@(gr8,#__FPMEDIA_FR(22)),fr22 | 
 | 219 | 	lddfi		@(gr8,#__FPMEDIA_FR(24)),fr24 | 
 | 220 | 	lddfi		@(gr8,#__FPMEDIA_FR(26)),fr26 | 
 | 221 | 	lddfi		@(gr8,#__FPMEDIA_FR(28)),fr28 | 
 | 222 | 	lddfi.p		@(gr8,#__FPMEDIA_FR(30)),fr30 | 
 | 223 |  | 
 | 224 | 	# some CPU's have FR32-FR63 | 
 | 225 | 	setlos		#HSR0_FRHE,gr4 | 
 | 226 | 	andcc		gr6,gr4,gr0,icc0 | 
 | 227 | 	beq		icc0,#1,__restore_skip_fr32_fr63 | 
 | 228 |  | 
 | 229 | 	lddfi		@(gr8,#__FPMEDIA_FR(32)),fr32 | 
 | 230 | 	lddfi		@(gr8,#__FPMEDIA_FR(34)),fr34 | 
 | 231 | 	lddfi		@(gr8,#__FPMEDIA_FR(36)),fr36 | 
 | 232 | 	lddfi		@(gr8,#__FPMEDIA_FR(38)),fr38 | 
 | 233 | 	lddfi		@(gr8,#__FPMEDIA_FR(40)),fr40 | 
 | 234 | 	lddfi		@(gr8,#__FPMEDIA_FR(42)),fr42 | 
 | 235 | 	lddfi		@(gr8,#__FPMEDIA_FR(44)),fr44 | 
 | 236 | 	lddfi		@(gr8,#__FPMEDIA_FR(46)),fr46 | 
 | 237 | 	lddfi		@(gr8,#__FPMEDIA_FR(48)),fr48 | 
 | 238 | 	lddfi		@(gr8,#__FPMEDIA_FR(50)),fr50 | 
 | 239 | 	lddfi		@(gr8,#__FPMEDIA_FR(52)),fr52 | 
 | 240 | 	lddfi		@(gr8,#__FPMEDIA_FR(54)),fr54 | 
 | 241 | 	lddfi		@(gr8,#__FPMEDIA_FR(56)),fr56 | 
 | 242 | 	lddfi		@(gr8,#__FPMEDIA_FR(58)),fr58 | 
 | 243 | 	lddfi		@(gr8,#__FPMEDIA_FR(60)),fr60 | 
 | 244 | 	lddfi		@(gr8,#__FPMEDIA_FR(62)),fr62 | 
 | 245 | __restore_skip_fr32_fr63: | 
 | 246 |  | 
 | 247 | 	lddi		@(gr8,#__FPMEDIA_FNER(0)),gr4 | 
 | 248 | 	movsg		fner0,gr4 | 
 | 249 | 	movsg		fner1,gr5 | 
 | 250 | 	or.p		gr9,gr9,gr8 | 
 | 251 | 	bralr | 
 | 252 |  | 
 | 253 | 	# the FR451 also has ACC8-11/ACCG8-11 regs (but not 4-7...) | 
 | 254 | __restore_acc_fr451: | 
 | 255 | 	lddfi		@(gr8,#__FPMEDIA_ACC(4)),fr16 | 
 | 256 | 	lddfi		@(gr8,#__FPMEDIA_ACC(6)),fr18 | 
 | 257 | 	ldbfi		@(gr8,#__FPMEDIA_ACCG(4)),fr20 | 
 | 258 | 	ldbfi		@(gr8,#__FPMEDIA_ACCG(5)),fr21 | 
 | 259 | 	ldbfi		@(gr8,#__FPMEDIA_ACCG(6)),fr22 | 
 | 260 | 	ldbfi		@(gr8,#__FPMEDIA_ACCG(7)),fr23 | 
 | 261 |  | 
 | 262 | 	mwtacc		fr16,acc8 | 
 | 263 | 	mwtacc		fr17,acc9 | 
 | 264 | 	mwtacc		fr18,acc10 | 
 | 265 | 	mwtacc		fr19,acc11 | 
 | 266 | 	mwtaccg		fr20,accg8 | 
 | 267 | 	mwtaccg		fr21,accg9 | 
 | 268 | 	mwtaccg		fr22,accg10 | 
 | 269 | 	mwtaccg		fr23,accg11 | 
 | 270 | 	bra		__restore_acc_cont | 
 | 271 |  | 
 | 272 | 	# the FR555 also has ACC4-7/ACCG4-7 regs and an FSR0 reg | 
 | 273 | __restore_acc_fr555: | 
 | 274 | 	lddfi		@(gr8,#__FPMEDIA_ACC(4)),fr16 | 
 | 275 | 	lddfi		@(gr8,#__FPMEDIA_ACC(6)),fr18 | 
 | 276 | 	ldbfi		@(gr8,#__FPMEDIA_ACCG(4)),fr20 | 
 | 277 | 	ldbfi		@(gr8,#__FPMEDIA_ACCG(5)),fr21 | 
 | 278 | 	ldbfi		@(gr8,#__FPMEDIA_ACCG(6)),fr22 | 
 | 279 | 	ldbfi		@(gr8,#__FPMEDIA_ACCG(7)),fr23 | 
 | 280 |  | 
 | 281 | 	mnop.p | 
 | 282 | 	mwtacc		fr16,acc4 | 
 | 283 | 	mnop.p | 
 | 284 | 	mwtacc		fr17,acc5 | 
 | 285 | 	mnop.p | 
 | 286 | 	mwtacc		fr18,acc6 | 
 | 287 | 	mnop.p | 
 | 288 | 	mwtacc		fr19,acc7 | 
 | 289 | 	mnop.p | 
 | 290 | 	mwtaccg		fr20,accg4 | 
 | 291 | 	mnop.p | 
 | 292 | 	mwtaccg		fr21,accg5 | 
 | 293 | 	mnop.p | 
 | 294 | 	mwtaccg		fr22,accg6 | 
 | 295 | 	mnop.p | 
 | 296 | 	mwtaccg		fr23,accg7 | 
 | 297 |  | 
 | 298 | 	ldi		@(gr8,#__FPMEDIA_FSR(0)),gr4 | 
 | 299 | 	movgs		gr4,fsr0 | 
 | 300 |  | 
 | 301 | 	bra		__restore_acc_cont | 
 | 302 |  | 
 | 303 |  | 
 | 304 | ############################################################################### | 
 | 305 | # | 
 | 306 | # save extra general regs and FP/Media regs | 
 | 307 | # - void save_user_regs(struct user_context *target) | 
 | 308 | # | 
 | 309 | ############################################################################### | 
 | 310 | 	.globl		save_user_regs | 
 | 311 | save_user_regs: | 
 | 312 | 	movsg		hsr0,gr6 | 
 | 313 | 	ori		gr6,#HSR0_GRHE|HSR0_FRLE|HSR0_FRHE,gr6 | 
 | 314 | 	movgs		gr6,hsr0 | 
 | 315 | 	movsg		hsr0,gr6 | 
 | 316 |  | 
 | 317 | 	movsg		psr,gr7 | 
 | 318 | 	ori		gr7,#PSR_EF|PSR_EM,gr7 | 
 | 319 | 	movgs		gr7,psr | 
 | 320 | 	movsg		psr,gr7 | 
 | 321 | 	srli		gr7,#24,gr7 | 
 | 322 | 	bar | 
 | 323 |  | 
 | 324 | 	movsg		fner0,gr4 | 
 | 325 | 	movsg		fner1,gr5 | 
 | 326 | 	stdi.p		gr4,@(gr8,#__FPMEDIA_FNER(0)) | 
 | 327 |  | 
 | 328 | 	# some CPU's have GR32-GR63 | 
 | 329 | 	setlos		#HSR0_GRHE,gr4 | 
 | 330 | 	andcc		gr6,gr4,gr0,icc0 | 
 | 331 | 	beq		icc0,#1,__save_skip_gr32_gr63 | 
 | 332 |  | 
 | 333 | 	stdi		gr32,@(gr8,#__INT_GR(32)) | 
 | 334 | 	stdi		gr34,@(gr8,#__INT_GR(34)) | 
 | 335 | 	stdi		gr36,@(gr8,#__INT_GR(36)) | 
 | 336 | 	stdi		gr38,@(gr8,#__INT_GR(38)) | 
 | 337 | 	stdi		gr40,@(gr8,#__INT_GR(40)) | 
 | 338 | 	stdi		gr42,@(gr8,#__INT_GR(42)) | 
 | 339 | 	stdi		gr44,@(gr8,#__INT_GR(44)) | 
 | 340 | 	stdi		gr46,@(gr8,#__INT_GR(46)) | 
 | 341 | 	stdi		gr48,@(gr8,#__INT_GR(48)) | 
 | 342 | 	stdi		gr50,@(gr8,#__INT_GR(50)) | 
 | 343 | 	stdi		gr52,@(gr8,#__INT_GR(52)) | 
 | 344 | 	stdi		gr54,@(gr8,#__INT_GR(54)) | 
 | 345 | 	stdi		gr56,@(gr8,#__INT_GR(56)) | 
 | 346 | 	stdi		gr58,@(gr8,#__INT_GR(58)) | 
 | 347 | 	stdi		gr60,@(gr8,#__INT_GR(60)) | 
 | 348 | 	stdi		gr62,@(gr8,#__INT_GR(62)) | 
 | 349 | __save_skip_gr32_gr63: | 
 | 350 |  | 
 | 351 | 	# all CPU's have FR0-FR31 | 
 | 352 | 	stdfi		fr0 ,@(gr8,#__FPMEDIA_FR( 0)) | 
 | 353 | 	stdfi		fr2 ,@(gr8,#__FPMEDIA_FR( 2)) | 
 | 354 | 	stdfi		fr4 ,@(gr8,#__FPMEDIA_FR( 4)) | 
 | 355 | 	stdfi		fr6 ,@(gr8,#__FPMEDIA_FR( 6)) | 
 | 356 | 	stdfi		fr8 ,@(gr8,#__FPMEDIA_FR( 8)) | 
 | 357 | 	stdfi		fr10,@(gr8,#__FPMEDIA_FR(10)) | 
 | 358 | 	stdfi		fr12,@(gr8,#__FPMEDIA_FR(12)) | 
 | 359 | 	stdfi		fr14,@(gr8,#__FPMEDIA_FR(14)) | 
 | 360 | 	stdfi		fr16,@(gr8,#__FPMEDIA_FR(16)) | 
 | 361 | 	stdfi		fr18,@(gr8,#__FPMEDIA_FR(18)) | 
 | 362 | 	stdfi		fr20,@(gr8,#__FPMEDIA_FR(20)) | 
 | 363 | 	stdfi		fr22,@(gr8,#__FPMEDIA_FR(22)) | 
 | 364 | 	stdfi		fr24,@(gr8,#__FPMEDIA_FR(24)) | 
 | 365 | 	stdfi		fr26,@(gr8,#__FPMEDIA_FR(26)) | 
 | 366 | 	stdfi		fr28,@(gr8,#__FPMEDIA_FR(28)) | 
 | 367 | 	stdfi.p		fr30,@(gr8,#__FPMEDIA_FR(30)) | 
 | 368 |  | 
 | 369 | 	# some CPU's have FR32-FR63 | 
 | 370 | 	setlos		#HSR0_FRHE,gr4 | 
 | 371 | 	andcc		gr6,gr4,gr0,icc0 | 
 | 372 | 	beq		icc0,#1,__save_skip_fr32_fr63 | 
 | 373 |  | 
 | 374 | 	stdfi		fr32,@(gr8,#__FPMEDIA_FR(32)) | 
 | 375 | 	stdfi		fr34,@(gr8,#__FPMEDIA_FR(34)) | 
 | 376 | 	stdfi		fr36,@(gr8,#__FPMEDIA_FR(36)) | 
 | 377 | 	stdfi		fr38,@(gr8,#__FPMEDIA_FR(38)) | 
 | 378 | 	stdfi		fr40,@(gr8,#__FPMEDIA_FR(40)) | 
 | 379 | 	stdfi		fr42,@(gr8,#__FPMEDIA_FR(42)) | 
 | 380 | 	stdfi		fr44,@(gr8,#__FPMEDIA_FR(44)) | 
 | 381 | 	stdfi		fr46,@(gr8,#__FPMEDIA_FR(46)) | 
 | 382 | 	stdfi		fr48,@(gr8,#__FPMEDIA_FR(48)) | 
 | 383 | 	stdfi		fr50,@(gr8,#__FPMEDIA_FR(50)) | 
 | 384 | 	stdfi		fr52,@(gr8,#__FPMEDIA_FR(52)) | 
 | 385 | 	stdfi		fr54,@(gr8,#__FPMEDIA_FR(54)) | 
 | 386 | 	stdfi		fr56,@(gr8,#__FPMEDIA_FR(56)) | 
 | 387 | 	stdfi		fr58,@(gr8,#__FPMEDIA_FR(58)) | 
 | 388 | 	stdfi		fr60,@(gr8,#__FPMEDIA_FR(60)) | 
 | 389 | 	stdfi		fr62,@(gr8,#__FPMEDIA_FR(62)) | 
 | 390 | __save_skip_fr32_fr63: | 
 | 391 |  | 
 | 392 | 	mrdacc		acc0 ,fr4 | 
 | 393 | 	mrdacc		acc1 ,fr5 | 
 | 394 |  | 
 | 395 | 	stdfi.p		fr4 ,@(gr8,#__FPMEDIA_ACC(0)) | 
 | 396 |  | 
 | 397 | 	mrdacc		acc2 ,fr6 | 
 | 398 | 	mrdacc		acc3 ,fr7 | 
 | 399 |  | 
 | 400 | 	stdfi.p		fr6 ,@(gr8,#__FPMEDIA_ACC(2)) | 
 | 401 |  | 
 | 402 | 	mrdaccg		accg0,fr4 | 
 | 403 | 	stbfi.p		fr4 ,@(gr8,#__FPMEDIA_ACCG(0)) | 
 | 404 |  | 
 | 405 | 	mrdaccg		accg1,fr5 | 
 | 406 | 	stbfi.p		fr5 ,@(gr8,#__FPMEDIA_ACCG(1)) | 
 | 407 |  | 
 | 408 | 	mrdaccg		accg2,fr6 | 
 | 409 | 	stbfi.p		fr6 ,@(gr8,#__FPMEDIA_ACCG(2)) | 
 | 410 |  | 
 | 411 | 	mrdaccg		accg3,fr7 | 
 | 412 | 	stbfi		fr7 ,@(gr8,#__FPMEDIA_ACCG(3)) | 
 | 413 |  | 
 | 414 | 	movsg		msr0 ,gr4 | 
 | 415 | 	movsg		msr1 ,gr5 | 
 | 416 |  | 
 | 417 | 	stdi		gr4 ,@(gr8,#__FPMEDIA_MSR(0)) | 
 | 418 |  | 
 | 419 | 	# some CPUs have extra ACCx and ACCGx regs and maybe FSRx regs | 
 | 420 | 	subicc.p	gr7,#0x50,gr0,icc0 | 
 | 421 | 	subicc		gr7,#0x31,gr0,icc1 | 
 | 422 | 	beq		icc0,#0,__save_acc_fr451 | 
 | 423 | 	beq		icc1,#0,__save_acc_fr555 | 
 | 424 | __save_acc_cont: | 
 | 425 |  | 
 | 426 | 	lddfi		@(gr8,#__FPMEDIA_FR(4)),fr4 | 
 | 427 | 	lddfi.p		@(gr8,#__FPMEDIA_FR(6)),fr6 | 
 | 428 | 	bralr | 
 | 429 |  | 
 | 430 | 	# the FR451 also has ACC8-11/ACCG8-11 regs (but not 4-7...) | 
 | 431 | __save_acc_fr451: | 
 | 432 | 	mrdacc		acc8 ,fr4 | 
 | 433 | 	mrdacc		acc9 ,fr5 | 
 | 434 |  | 
 | 435 | 	stdfi.p		fr4 ,@(gr8,#__FPMEDIA_ACC(4)) | 
 | 436 |  | 
 | 437 | 	mrdacc		acc10,fr6 | 
 | 438 | 	mrdacc		acc11,fr7 | 
 | 439 |  | 
 | 440 | 	stdfi.p		fr6 ,@(gr8,#__FPMEDIA_ACC(6)) | 
 | 441 |  | 
 | 442 | 	mrdaccg		accg8,fr4 | 
 | 443 | 	stbfi.p		fr4 ,@(gr8,#__FPMEDIA_ACCG(4)) | 
 | 444 |  | 
 | 445 | 	mrdaccg		accg9,fr5 | 
 | 446 | 	stbfi.p		fr5 ,@(gr8,#__FPMEDIA_ACCG(5)) | 
 | 447 |  | 
 | 448 | 	mrdaccg		accg10,fr6 | 
 | 449 | 	stbfi.p		fr6 ,@(gr8,#__FPMEDIA_ACCG(6)) | 
 | 450 |  | 
 | 451 | 	mrdaccg		accg11,fr7 | 
 | 452 | 	stbfi		fr7 ,@(gr8,#__FPMEDIA_ACCG(7)) | 
 | 453 | 	bra		__save_acc_cont | 
 | 454 |  | 
 | 455 | 	# the FR555 also has ACC4-7/ACCG4-7 regs and an FSR0 reg | 
 | 456 | __save_acc_fr555: | 
 | 457 | 	mnop.p | 
 | 458 | 	mrdacc		acc4 ,fr4 | 
 | 459 | 	mnop.p | 
 | 460 | 	mrdacc		acc5 ,fr5 | 
 | 461 |  | 
 | 462 | 	stdfi		fr4 ,@(gr8,#__FPMEDIA_ACC(4)) | 
 | 463 |  | 
 | 464 | 	mnop.p | 
 | 465 | 	mrdacc		acc6 ,fr6 | 
 | 466 | 	mnop.p | 
 | 467 | 	mrdacc		acc7 ,fr7 | 
 | 468 |  | 
 | 469 | 	stdfi		fr6 ,@(gr8,#__FPMEDIA_ACC(6)) | 
 | 470 |  | 
 | 471 | 	mnop.p | 
 | 472 | 	mrdaccg		accg4,fr4 | 
 | 473 | 	stbfi		fr4 ,@(gr8,#__FPMEDIA_ACCG(4)) | 
 | 474 |  | 
 | 475 | 	mnop.p | 
 | 476 | 	mrdaccg		accg5,fr5 | 
 | 477 | 	stbfi		fr5 ,@(gr8,#__FPMEDIA_ACCG(5)) | 
 | 478 |  | 
 | 479 | 	mnop.p | 
 | 480 | 	mrdaccg		accg6,fr6 | 
 | 481 | 	stbfi		fr6 ,@(gr8,#__FPMEDIA_ACCG(6)) | 
 | 482 |  | 
 | 483 | 	mnop.p | 
 | 484 | 	mrdaccg		accg7,fr7 | 
 | 485 | 	stbfi		fr7 ,@(gr8,#__FPMEDIA_ACCG(7)) | 
 | 486 |  | 
 | 487 | 	movsg		fsr0 ,gr4 | 
 | 488 | 	sti		gr4 ,@(gr8,#__FPMEDIA_FSR(0)) | 
 | 489 | 	bra		__save_acc_cont |