root / target-ppc / op.c @ 64adab3f
History | View | Annotate | Download (21.1 kB)
1 |
/*
|
---|---|
2 |
* PowerPC emulation micro-operations for qemu.
|
3 |
*
|
4 |
* Copyright (c) 2003-2007 Jocelyn Mayer
|
5 |
*
|
6 |
* This library is free software; you can redistribute it and/or
|
7 |
* modify it under the terms of the GNU Lesser General Public
|
8 |
* License as published by the Free Software Foundation; either
|
9 |
* version 2 of the License, or (at your option) any later version.
|
10 |
*
|
11 |
* This library is distributed in the hope that it will be useful,
|
12 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14 |
* Lesser General Public License for more details.
|
15 |
*
|
16 |
* You should have received a copy of the GNU Lesser General Public
|
17 |
* License along with this library; if not, write to the Free Software
|
18 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
19 |
*/
|
20 |
|
21 |
//#define DEBUG_OP
|
22 |
|
23 |
#include "config.h" |
24 |
#include "exec.h" |
25 |
#include "host-utils.h" |
26 |
#include "helper_regs.h" |
27 |
#include "op_helper.h" |
28 |
|
29 |
#if !defined(CONFIG_USER_ONLY)
|
30 |
/* Segment registers load and store */
|
31 |
void OPPROTO op_load_sr (void) |
32 |
{ |
33 |
T0 = env->sr[T1]; |
34 |
RETURN(); |
35 |
} |
36 |
|
37 |
void OPPROTO op_store_sr (void) |
38 |
{ |
39 |
do_store_sr(env, T1, T0); |
40 |
RETURN(); |
41 |
} |
42 |
|
43 |
#if defined(TARGET_PPC64)
|
44 |
void OPPROTO op_load_slb (void) |
45 |
{ |
46 |
T0 = ppc_load_slb(env, T1); |
47 |
RETURN(); |
48 |
} |
49 |
|
50 |
void OPPROTO op_store_slb (void) |
51 |
{ |
52 |
ppc_store_slb(env, T1, T0); |
53 |
RETURN(); |
54 |
} |
55 |
#endif /* defined(TARGET_PPC64) */ |
56 |
|
57 |
void OPPROTO op_load_sdr1 (void) |
58 |
{ |
59 |
T0 = env->sdr1; |
60 |
RETURN(); |
61 |
} |
62 |
|
63 |
void OPPROTO op_store_sdr1 (void) |
64 |
{ |
65 |
do_store_sdr1(env, T0); |
66 |
RETURN(); |
67 |
} |
68 |
|
69 |
#if defined (TARGET_PPC64)
|
70 |
void OPPROTO op_load_asr (void) |
71 |
{ |
72 |
T0 = env->asr; |
73 |
RETURN(); |
74 |
} |
75 |
|
76 |
void OPPROTO op_store_asr (void) |
77 |
{ |
78 |
ppc_store_asr(env, T0); |
79 |
RETURN(); |
80 |
} |
81 |
#endif
|
82 |
|
83 |
void OPPROTO op_load_msr (void) |
84 |
{ |
85 |
T0 = env->msr; |
86 |
RETURN(); |
87 |
} |
88 |
|
89 |
void OPPROTO op_store_msr (void) |
90 |
{ |
91 |
do_store_msr(); |
92 |
RETURN(); |
93 |
} |
94 |
|
95 |
#if defined (TARGET_PPC64)
|
96 |
void OPPROTO op_store_msr_32 (void) |
97 |
{ |
98 |
T0 = (env->msr & ~0xFFFFFFFFULL) | (T0 & 0xFFFFFFFF); |
99 |
do_store_msr(); |
100 |
RETURN(); |
101 |
} |
102 |
#endif
|
103 |
|
104 |
void OPPROTO op_update_riee (void) |
105 |
{ |
106 |
/* We don't call do_store_msr here as we won't trigger
|
107 |
* any special case nor change hflags
|
108 |
*/
|
109 |
T0 &= (1 << MSR_RI) | (1 << MSR_EE); |
110 |
env->msr &= ~(1 << MSR_RI) | (1 << MSR_EE); |
111 |
env->msr |= T0; |
112 |
RETURN(); |
113 |
} |
114 |
#endif
|
115 |
|
116 |
/* SPR */
|
117 |
void OPPROTO op_load_spr (void) |
118 |
{ |
119 |
T0 = env->spr[PARAM1]; |
120 |
RETURN(); |
121 |
} |
122 |
|
123 |
void OPPROTO op_store_spr (void) |
124 |
{ |
125 |
env->spr[PARAM1] = T0; |
126 |
RETURN(); |
127 |
} |
128 |
|
129 |
void OPPROTO op_load_dump_spr (void) |
130 |
{ |
131 |
T0 = ppc_load_dump_spr(PARAM1); |
132 |
RETURN(); |
133 |
} |
134 |
|
135 |
void OPPROTO op_store_dump_spr (void) |
136 |
{ |
137 |
ppc_store_dump_spr(PARAM1, T0); |
138 |
RETURN(); |
139 |
} |
140 |
|
141 |
void OPPROTO op_mask_spr (void) |
142 |
{ |
143 |
env->spr[PARAM1] &= ~T0; |
144 |
RETURN(); |
145 |
} |
146 |
|
147 |
void OPPROTO op_load_tbl (void) |
148 |
{ |
149 |
T0 = cpu_ppc_load_tbl(env); |
150 |
RETURN(); |
151 |
} |
152 |
|
153 |
void OPPROTO op_load_tbu (void) |
154 |
{ |
155 |
T0 = cpu_ppc_load_tbu(env); |
156 |
RETURN(); |
157 |
} |
158 |
|
159 |
void OPPROTO op_load_atbl (void) |
160 |
{ |
161 |
T0 = cpu_ppc_load_atbl(env); |
162 |
RETURN(); |
163 |
} |
164 |
|
165 |
void OPPROTO op_load_atbu (void) |
166 |
{ |
167 |
T0 = cpu_ppc_load_atbu(env); |
168 |
RETURN(); |
169 |
} |
170 |
|
171 |
#if !defined(CONFIG_USER_ONLY)
|
172 |
void OPPROTO op_store_tbl (void) |
173 |
{ |
174 |
cpu_ppc_store_tbl(env, T0); |
175 |
RETURN(); |
176 |
} |
177 |
|
178 |
void OPPROTO op_store_tbu (void) |
179 |
{ |
180 |
cpu_ppc_store_tbu(env, T0); |
181 |
RETURN(); |
182 |
} |
183 |
|
184 |
void OPPROTO op_store_atbl (void) |
185 |
{ |
186 |
cpu_ppc_store_atbl(env, T0); |
187 |
RETURN(); |
188 |
} |
189 |
|
190 |
void OPPROTO op_store_atbu (void) |
191 |
{ |
192 |
cpu_ppc_store_atbu(env, T0); |
193 |
RETURN(); |
194 |
} |
195 |
|
196 |
void OPPROTO op_load_decr (void) |
197 |
{ |
198 |
T0 = cpu_ppc_load_decr(env); |
199 |
RETURN(); |
200 |
} |
201 |
|
202 |
void OPPROTO op_store_decr (void) |
203 |
{ |
204 |
cpu_ppc_store_decr(env, T0); |
205 |
RETURN(); |
206 |
} |
207 |
|
208 |
void OPPROTO op_load_ibat (void) |
209 |
{ |
210 |
T0 = env->IBAT[PARAM1][PARAM2]; |
211 |
RETURN(); |
212 |
} |
213 |
|
214 |
void OPPROTO op_store_ibatu (void) |
215 |
{ |
216 |
do_store_ibatu(env, PARAM1, T0); |
217 |
RETURN(); |
218 |
} |
219 |
|
220 |
void OPPROTO op_store_ibatl (void) |
221 |
{ |
222 |
#if 1 |
223 |
env->IBAT[1][PARAM1] = T0;
|
224 |
#else
|
225 |
do_store_ibatl(env, PARAM1, T0); |
226 |
#endif
|
227 |
RETURN(); |
228 |
} |
229 |
|
230 |
void OPPROTO op_load_dbat (void) |
231 |
{ |
232 |
T0 = env->DBAT[PARAM1][PARAM2]; |
233 |
RETURN(); |
234 |
} |
235 |
|
236 |
void OPPROTO op_store_dbatu (void) |
237 |
{ |
238 |
do_store_dbatu(env, PARAM1, T0); |
239 |
RETURN(); |
240 |
} |
241 |
|
242 |
void OPPROTO op_store_dbatl (void) |
243 |
{ |
244 |
#if 1 |
245 |
env->DBAT[1][PARAM1] = T0;
|
246 |
#else
|
247 |
do_store_dbatl(env, PARAM1, T0); |
248 |
#endif
|
249 |
RETURN(); |
250 |
} |
251 |
#endif /* !defined(CONFIG_USER_ONLY) */ |
252 |
|
253 |
/*** Integer shift ***/
|
254 |
void OPPROTO op_srli_T1 (void) |
255 |
{ |
256 |
T1 = (uint32_t)T1 >> PARAM1; |
257 |
RETURN(); |
258 |
} |
259 |
|
260 |
/* Load and store */
|
261 |
#define MEMSUFFIX _raw
|
262 |
#include "op_helper.h" |
263 |
#include "op_mem.h" |
264 |
#if !defined(CONFIG_USER_ONLY)
|
265 |
#define MEMSUFFIX _user
|
266 |
#include "op_helper.h" |
267 |
#include "op_mem.h" |
268 |
#define MEMSUFFIX _kernel
|
269 |
#include "op_helper.h" |
270 |
#include "op_mem.h" |
271 |
#define MEMSUFFIX _hypv
|
272 |
#include "op_helper.h" |
273 |
#include "op_mem.h" |
274 |
#endif
|
275 |
|
276 |
/* Special op to check and maybe clear reservation */
|
277 |
void OPPROTO op_check_reservation (void) |
278 |
{ |
279 |
if ((uint32_t)env->reserve == (uint32_t)(T0 & ~0x00000003)) |
280 |
env->reserve = (target_ulong)-1ULL;
|
281 |
RETURN(); |
282 |
} |
283 |
|
284 |
#if defined(TARGET_PPC64)
|
285 |
void OPPROTO op_check_reservation_64 (void) |
286 |
{ |
287 |
if ((uint64_t)env->reserve == (uint64_t)(T0 & ~0x00000003)) |
288 |
env->reserve = (target_ulong)-1ULL;
|
289 |
RETURN(); |
290 |
} |
291 |
#endif
|
292 |
|
293 |
void OPPROTO op_wait (void) |
294 |
{ |
295 |
env->halted = 1;
|
296 |
RETURN(); |
297 |
} |
298 |
|
299 |
/* Return from interrupt */
|
300 |
#if !defined(CONFIG_USER_ONLY)
|
301 |
void OPPROTO op_rfi (void) |
302 |
{ |
303 |
do_rfi(); |
304 |
RETURN(); |
305 |
} |
306 |
|
307 |
#if defined(TARGET_PPC64)
|
308 |
void OPPROTO op_rfid (void) |
309 |
{ |
310 |
do_rfid(); |
311 |
RETURN(); |
312 |
} |
313 |
|
314 |
void OPPROTO op_hrfid (void) |
315 |
{ |
316 |
do_hrfid(); |
317 |
RETURN(); |
318 |
} |
319 |
#endif
|
320 |
|
321 |
/* Exception vectors */
|
322 |
void OPPROTO op_store_excp_prefix (void) |
323 |
{ |
324 |
T0 &= env->ivpr_mask; |
325 |
env->excp_prefix = T0; |
326 |
RETURN(); |
327 |
} |
328 |
|
329 |
void OPPROTO op_store_excp_vector (void) |
330 |
{ |
331 |
T0 &= env->ivor_mask; |
332 |
env->excp_vectors[PARAM1] = T0; |
333 |
RETURN(); |
334 |
} |
335 |
#endif
|
336 |
|
337 |
/* Trap word */
|
338 |
void OPPROTO op_tw (void) |
339 |
{ |
340 |
do_tw(PARAM1); |
341 |
RETURN(); |
342 |
} |
343 |
|
344 |
#if defined(TARGET_PPC64)
|
345 |
void OPPROTO op_td (void) |
346 |
{ |
347 |
do_td(PARAM1); |
348 |
RETURN(); |
349 |
} |
350 |
#endif
|
351 |
|
352 |
#if !defined(CONFIG_USER_ONLY)
|
353 |
/* tlbia */
|
354 |
void OPPROTO op_tlbia (void) |
355 |
{ |
356 |
ppc_tlb_invalidate_all(env); |
357 |
RETURN(); |
358 |
} |
359 |
|
360 |
/* tlbie */
|
361 |
void OPPROTO op_tlbie (void) |
362 |
{ |
363 |
ppc_tlb_invalidate_one(env, (uint32_t)T0); |
364 |
RETURN(); |
365 |
} |
366 |
|
367 |
#if defined(TARGET_PPC64)
|
368 |
void OPPROTO op_tlbie_64 (void) |
369 |
{ |
370 |
ppc_tlb_invalidate_one(env, T0); |
371 |
RETURN(); |
372 |
} |
373 |
#endif
|
374 |
|
375 |
#if defined(TARGET_PPC64)
|
376 |
void OPPROTO op_slbia (void) |
377 |
{ |
378 |
ppc_slb_invalidate_all(env); |
379 |
RETURN(); |
380 |
} |
381 |
|
382 |
void OPPROTO op_slbie (void) |
383 |
{ |
384 |
ppc_slb_invalidate_one(env, (uint32_t)T0); |
385 |
RETURN(); |
386 |
} |
387 |
|
388 |
void OPPROTO op_slbie_64 (void) |
389 |
{ |
390 |
ppc_slb_invalidate_one(env, T0); |
391 |
RETURN(); |
392 |
} |
393 |
#endif
|
394 |
#endif
|
395 |
|
396 |
#if !defined(CONFIG_USER_ONLY)
|
397 |
/* PowerPC 602/603/755 software TLB load instructions */
|
398 |
void OPPROTO op_6xx_tlbld (void) |
399 |
{ |
400 |
do_load_6xx_tlb(0);
|
401 |
RETURN(); |
402 |
} |
403 |
|
404 |
void OPPROTO op_6xx_tlbli (void) |
405 |
{ |
406 |
do_load_6xx_tlb(1);
|
407 |
RETURN(); |
408 |
} |
409 |
|
410 |
/* PowerPC 74xx software TLB load instructions */
|
411 |
void OPPROTO op_74xx_tlbld (void) |
412 |
{ |
413 |
do_load_74xx_tlb(0);
|
414 |
RETURN(); |
415 |
} |
416 |
|
417 |
void OPPROTO op_74xx_tlbli (void) |
418 |
{ |
419 |
do_load_74xx_tlb(1);
|
420 |
RETURN(); |
421 |
} |
422 |
#endif
|
423 |
|
424 |
/* 601 specific */
|
425 |
void OPPROTO op_load_601_rtcl (void) |
426 |
{ |
427 |
T0 = cpu_ppc601_load_rtcl(env); |
428 |
RETURN(); |
429 |
} |
430 |
|
431 |
void OPPROTO op_load_601_rtcu (void) |
432 |
{ |
433 |
T0 = cpu_ppc601_load_rtcu(env); |
434 |
RETURN(); |
435 |
} |
436 |
|
437 |
#if !defined(CONFIG_USER_ONLY)
|
438 |
void OPPROTO op_store_601_rtcl (void) |
439 |
{ |
440 |
cpu_ppc601_store_rtcl(env, T0); |
441 |
RETURN(); |
442 |
} |
443 |
|
444 |
void OPPROTO op_store_601_rtcu (void) |
445 |
{ |
446 |
cpu_ppc601_store_rtcu(env, T0); |
447 |
RETURN(); |
448 |
} |
449 |
|
450 |
void OPPROTO op_store_hid0_601 (void) |
451 |
{ |
452 |
do_store_hid0_601(); |
453 |
RETURN(); |
454 |
} |
455 |
|
456 |
void OPPROTO op_load_601_bat (void) |
457 |
{ |
458 |
T0 = env->IBAT[PARAM1][PARAM2]; |
459 |
RETURN(); |
460 |
} |
461 |
|
462 |
void OPPROTO op_store_601_batl (void) |
463 |
{ |
464 |
do_store_ibatl_601(env, PARAM1, T0); |
465 |
RETURN(); |
466 |
} |
467 |
|
468 |
void OPPROTO op_store_601_batu (void) |
469 |
{ |
470 |
do_store_ibatu_601(env, PARAM1, T0); |
471 |
RETURN(); |
472 |
} |
473 |
#endif /* !defined(CONFIG_USER_ONLY) */ |
474 |
|
475 |
/* PowerPC 601 specific instructions (POWER bridge) */
|
476 |
/* XXX: those micro-ops need tests ! */
|
477 |
void OPPROTO op_POWER_abs (void) |
478 |
{ |
479 |
if ((int32_t)T0 == INT32_MIN)
|
480 |
T0 = INT32_MAX; |
481 |
else if ((int32_t)T0 < 0) |
482 |
T0 = -T0; |
483 |
RETURN(); |
484 |
} |
485 |
|
486 |
void OPPROTO op_POWER_abso (void) |
487 |
{ |
488 |
do_POWER_abso(); |
489 |
RETURN(); |
490 |
} |
491 |
|
492 |
void OPPROTO op_POWER_clcs (void) |
493 |
{ |
494 |
do_POWER_clcs(); |
495 |
RETURN(); |
496 |
} |
497 |
|
498 |
void OPPROTO op_POWER_div (void) |
499 |
{ |
500 |
do_POWER_div(); |
501 |
RETURN(); |
502 |
} |
503 |
|
504 |
void OPPROTO op_POWER_divo (void) |
505 |
{ |
506 |
do_POWER_divo(); |
507 |
RETURN(); |
508 |
} |
509 |
|
510 |
void OPPROTO op_POWER_divs (void) |
511 |
{ |
512 |
do_POWER_divs(); |
513 |
RETURN(); |
514 |
} |
515 |
|
516 |
void OPPROTO op_POWER_divso (void) |
517 |
{ |
518 |
do_POWER_divso(); |
519 |
RETURN(); |
520 |
} |
521 |
|
522 |
void OPPROTO op_POWER_doz (void) |
523 |
{ |
524 |
if ((int32_t)T1 > (int32_t)T0)
|
525 |
T0 = T1 - T0; |
526 |
else
|
527 |
T0 = 0;
|
528 |
RETURN(); |
529 |
} |
530 |
|
531 |
void OPPROTO op_POWER_dozo (void) |
532 |
{ |
533 |
do_POWER_dozo(); |
534 |
RETURN(); |
535 |
} |
536 |
|
537 |
void OPPROTO op_load_xer_cmp (void) |
538 |
{ |
539 |
T2 = xer_cmp; |
540 |
RETURN(); |
541 |
} |
542 |
|
543 |
void OPPROTO op_POWER_maskg (void) |
544 |
{ |
545 |
do_POWER_maskg(); |
546 |
RETURN(); |
547 |
} |
548 |
|
549 |
void OPPROTO op_POWER_maskir (void) |
550 |
{ |
551 |
T0 = (T0 & ~T2) | (T1 & T2); |
552 |
RETURN(); |
553 |
} |
554 |
|
555 |
void OPPROTO op_POWER_mul (void) |
556 |
{ |
557 |
uint64_t tmp; |
558 |
|
559 |
tmp = (uint64_t)T0 * (uint64_t)T1; |
560 |
env->spr[SPR_MQ] = tmp >> 32;
|
561 |
T0 = tmp; |
562 |
RETURN(); |
563 |
} |
564 |
|
565 |
void OPPROTO op_POWER_mulo (void) |
566 |
{ |
567 |
do_POWER_mulo(); |
568 |
RETURN(); |
569 |
} |
570 |
|
571 |
void OPPROTO op_POWER_nabs (void) |
572 |
{ |
573 |
if (T0 > 0) |
574 |
T0 = -T0; |
575 |
RETURN(); |
576 |
} |
577 |
|
578 |
void OPPROTO op_POWER_nabso (void) |
579 |
{ |
580 |
/* nabs never overflows */
|
581 |
if (T0 > 0) |
582 |
T0 = -T0; |
583 |
env->xer &= ~(1 << XER_OV);
|
584 |
RETURN(); |
585 |
} |
586 |
|
587 |
/* XXX: factorise POWER rotates... */
|
588 |
void OPPROTO op_POWER_rlmi (void) |
589 |
{ |
590 |
T0 = rotl32(T0, T2) & PARAM1; |
591 |
T0 |= T1 & (uint32_t)PARAM2; |
592 |
RETURN(); |
593 |
} |
594 |
|
595 |
void OPPROTO op_POWER_rrib (void) |
596 |
{ |
597 |
T2 &= 0x1FUL;
|
598 |
T0 = rotl32(T0 & INT32_MIN, T2); |
599 |
T0 |= T1 & ~rotl32(INT32_MIN, T2); |
600 |
RETURN(); |
601 |
} |
602 |
|
603 |
void OPPROTO op_POWER_sle (void) |
604 |
{ |
605 |
T1 &= 0x1FUL;
|
606 |
env->spr[SPR_MQ] = rotl32(T0, T1); |
607 |
T0 = T0 << T1; |
608 |
RETURN(); |
609 |
} |
610 |
|
611 |
void OPPROTO op_POWER_sleq (void) |
612 |
{ |
613 |
uint32_t tmp = env->spr[SPR_MQ]; |
614 |
|
615 |
T1 &= 0x1FUL;
|
616 |
env->spr[SPR_MQ] = rotl32(T0, T1); |
617 |
T0 = T0 << T1; |
618 |
T0 |= tmp >> (32 - T1);
|
619 |
RETURN(); |
620 |
} |
621 |
|
622 |
void OPPROTO op_POWER_sllq (void) |
623 |
{ |
624 |
uint32_t msk = UINT32_MAX; |
625 |
|
626 |
msk = msk << (T1 & 0x1FUL);
|
627 |
if (T1 & 0x20UL) |
628 |
msk = ~msk; |
629 |
T1 &= 0x1FUL;
|
630 |
T0 = (T0 << T1) & msk; |
631 |
T0 |= env->spr[SPR_MQ] & ~msk; |
632 |
RETURN(); |
633 |
} |
634 |
|
635 |
void OPPROTO op_POWER_slq (void) |
636 |
{ |
637 |
uint32_t msk = UINT32_MAX, tmp; |
638 |
|
639 |
msk = msk << (T1 & 0x1FUL);
|
640 |
if (T1 & 0x20UL) |
641 |
msk = ~msk; |
642 |
T1 &= 0x1FUL;
|
643 |
tmp = rotl32(T0, T1); |
644 |
T0 = tmp & msk; |
645 |
env->spr[SPR_MQ] = tmp; |
646 |
RETURN(); |
647 |
} |
648 |
|
649 |
void OPPROTO op_POWER_sraq (void) |
650 |
{ |
651 |
env->spr[SPR_MQ] = rotl32(T0, 32 - (T1 & 0x1FUL)); |
652 |
if (T1 & 0x20UL) |
653 |
T0 = UINT32_MAX; |
654 |
else
|
655 |
T0 = (int32_t)T0 >> T1; |
656 |
RETURN(); |
657 |
} |
658 |
|
659 |
void OPPROTO op_POWER_sre (void) |
660 |
{ |
661 |
T1 &= 0x1FUL;
|
662 |
env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
|
663 |
T0 = (int32_t)T0 >> T1; |
664 |
RETURN(); |
665 |
} |
666 |
|
667 |
void OPPROTO op_POWER_srea (void) |
668 |
{ |
669 |
T1 &= 0x1FUL;
|
670 |
env->spr[SPR_MQ] = T0 >> T1; |
671 |
T0 = (int32_t)T0 >> T1; |
672 |
RETURN(); |
673 |
} |
674 |
|
675 |
void OPPROTO op_POWER_sreq (void) |
676 |
{ |
677 |
uint32_t tmp; |
678 |
int32_t msk; |
679 |
|
680 |
T1 &= 0x1FUL;
|
681 |
msk = INT32_MIN >> T1; |
682 |
tmp = env->spr[SPR_MQ]; |
683 |
env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
|
684 |
T0 = T0 >> T1; |
685 |
T0 |= tmp & msk; |
686 |
RETURN(); |
687 |
} |
688 |
|
689 |
void OPPROTO op_POWER_srlq (void) |
690 |
{ |
691 |
uint32_t tmp; |
692 |
int32_t msk; |
693 |
|
694 |
msk = INT32_MIN >> (T1 & 0x1FUL);
|
695 |
if (T1 & 0x20UL) |
696 |
msk = ~msk; |
697 |
T1 &= 0x1FUL;
|
698 |
tmp = env->spr[SPR_MQ]; |
699 |
env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
|
700 |
T0 = T0 >> T1; |
701 |
T0 &= msk; |
702 |
T0 |= tmp & ~msk; |
703 |
RETURN(); |
704 |
} |
705 |
|
706 |
void OPPROTO op_POWER_srq (void) |
707 |
{ |
708 |
T1 &= 0x1FUL;
|
709 |
env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
|
710 |
T0 = T0 >> T1; |
711 |
RETURN(); |
712 |
} |
713 |
|
714 |
/* POWER instructions not implemented in PowerPC 601 */
|
715 |
#if !defined(CONFIG_USER_ONLY)
|
716 |
void OPPROTO op_POWER_mfsri (void) |
717 |
{ |
718 |
T1 = T0 >> 28;
|
719 |
T0 = env->sr[T1]; |
720 |
RETURN(); |
721 |
} |
722 |
|
723 |
void OPPROTO op_POWER_rac (void) |
724 |
{ |
725 |
do_POWER_rac(); |
726 |
RETURN(); |
727 |
} |
728 |
|
729 |
void OPPROTO op_POWER_rfsvc (void) |
730 |
{ |
731 |
do_POWER_rfsvc(); |
732 |
RETURN(); |
733 |
} |
734 |
#endif
|
735 |
|
736 |
/* PowerPC 602 specific instruction */
|
737 |
#if !defined(CONFIG_USER_ONLY)
|
738 |
void OPPROTO op_602_mfrom (void) |
739 |
{ |
740 |
do_op_602_mfrom(); |
741 |
RETURN(); |
742 |
} |
743 |
#endif
|
744 |
|
745 |
/* PowerPC 4xx specific micro-ops */
|
746 |
void OPPROTO op_load_dcr (void) |
747 |
{ |
748 |
do_load_dcr(); |
749 |
RETURN(); |
750 |
} |
751 |
|
752 |
void OPPROTO op_store_dcr (void) |
753 |
{ |
754 |
do_store_dcr(); |
755 |
RETURN(); |
756 |
} |
757 |
|
758 |
#if !defined(CONFIG_USER_ONLY)
|
759 |
/* Return from critical interrupt :
|
760 |
* same as rfi, except nip & MSR are loaded from SRR2/3 instead of SRR0/1
|
761 |
*/
|
762 |
void OPPROTO op_40x_rfci (void) |
763 |
{ |
764 |
do_40x_rfci(); |
765 |
RETURN(); |
766 |
} |
767 |
|
768 |
void OPPROTO op_rfci (void) |
769 |
{ |
770 |
do_rfci(); |
771 |
RETURN(); |
772 |
} |
773 |
|
774 |
void OPPROTO op_rfdi (void) |
775 |
{ |
776 |
do_rfdi(); |
777 |
RETURN(); |
778 |
} |
779 |
|
780 |
void OPPROTO op_rfmci (void) |
781 |
{ |
782 |
do_rfmci(); |
783 |
RETURN(); |
784 |
} |
785 |
|
786 |
void OPPROTO op_wrte (void) |
787 |
{ |
788 |
/* We don't call do_store_msr here as we won't trigger
|
789 |
* any special case nor change hflags
|
790 |
*/
|
791 |
T0 &= 1 << MSR_EE;
|
792 |
env->msr &= ~(1 << MSR_EE);
|
793 |
env->msr |= T0; |
794 |
RETURN(); |
795 |
} |
796 |
|
797 |
void OPPROTO op_440_tlbre (void) |
798 |
{ |
799 |
do_440_tlbre(PARAM1); |
800 |
RETURN(); |
801 |
} |
802 |
|
803 |
void OPPROTO op_440_tlbsx (void) |
804 |
{ |
805 |
T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR] & 0xFF);
|
806 |
RETURN(); |
807 |
} |
808 |
|
809 |
void OPPROTO op_4xx_tlbsx_check (void) |
810 |
{ |
811 |
int tmp;
|
812 |
|
813 |
tmp = xer_so; |
814 |
if ((int)T0 != -1) |
815 |
tmp |= 0x02;
|
816 |
env->crf[0] = tmp;
|
817 |
RETURN(); |
818 |
} |
819 |
|
820 |
void OPPROTO op_440_tlbwe (void) |
821 |
{ |
822 |
do_440_tlbwe(PARAM1); |
823 |
RETURN(); |
824 |
} |
825 |
|
826 |
void OPPROTO op_4xx_tlbre_lo (void) |
827 |
{ |
828 |
do_4xx_tlbre_lo(); |
829 |
RETURN(); |
830 |
} |
831 |
|
832 |
void OPPROTO op_4xx_tlbre_hi (void) |
833 |
{ |
834 |
do_4xx_tlbre_hi(); |
835 |
RETURN(); |
836 |
} |
837 |
|
838 |
void OPPROTO op_4xx_tlbsx (void) |
839 |
{ |
840 |
T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_40x_PID]); |
841 |
RETURN(); |
842 |
} |
843 |
|
844 |
void OPPROTO op_4xx_tlbwe_lo (void) |
845 |
{ |
846 |
do_4xx_tlbwe_lo(); |
847 |
RETURN(); |
848 |
} |
849 |
|
850 |
void OPPROTO op_4xx_tlbwe_hi (void) |
851 |
{ |
852 |
do_4xx_tlbwe_hi(); |
853 |
RETURN(); |
854 |
} |
855 |
#endif
|
856 |
|
857 |
/* SPR micro-ops */
|
858 |
/* 440 specific */
|
859 |
void OPPROTO op_440_dlmzb (void) |
860 |
{ |
861 |
do_440_dlmzb(); |
862 |
RETURN(); |
863 |
} |
864 |
|
865 |
void OPPROTO op_440_dlmzb_update_Rc (void) |
866 |
{ |
867 |
if (T0 == 8) |
868 |
T0 = 0x2;
|
869 |
else if (T0 < 4) |
870 |
T0 = 0x4;
|
871 |
else
|
872 |
T0 = 0x8;
|
873 |
RETURN(); |
874 |
} |
875 |
|
876 |
#if !defined(CONFIG_USER_ONLY)
|
877 |
void OPPROTO op_store_pir (void) |
878 |
{ |
879 |
env->spr[SPR_PIR] = T0 & 0x0000000FUL;
|
880 |
RETURN(); |
881 |
} |
882 |
|
883 |
void OPPROTO op_load_403_pb (void) |
884 |
{ |
885 |
do_load_403_pb(PARAM1); |
886 |
RETURN(); |
887 |
} |
888 |
|
889 |
void OPPROTO op_store_403_pb (void) |
890 |
{ |
891 |
do_store_403_pb(PARAM1); |
892 |
RETURN(); |
893 |
} |
894 |
|
895 |
void OPPROTO op_load_40x_pit (void) |
896 |
{ |
897 |
T0 = load_40x_pit(env); |
898 |
RETURN(); |
899 |
} |
900 |
|
901 |
void OPPROTO op_store_40x_pit (void) |
902 |
{ |
903 |
store_40x_pit(env, T0); |
904 |
RETURN(); |
905 |
} |
906 |
|
907 |
void OPPROTO op_store_40x_dbcr0 (void) |
908 |
{ |
909 |
store_40x_dbcr0(env, T0); |
910 |
RETURN(); |
911 |
} |
912 |
|
913 |
void OPPROTO op_store_40x_sler (void) |
914 |
{ |
915 |
store_40x_sler(env, T0); |
916 |
RETURN(); |
917 |
} |
918 |
|
919 |
void OPPROTO op_store_booke_tcr (void) |
920 |
{ |
921 |
store_booke_tcr(env, T0); |
922 |
RETURN(); |
923 |
} |
924 |
|
925 |
void OPPROTO op_store_booke_tsr (void) |
926 |
{ |
927 |
store_booke_tsr(env, T0); |
928 |
RETURN(); |
929 |
} |
930 |
#endif /* !defined(CONFIG_USER_ONLY) */ |
931 |
|
932 |
/* SPE extension */
|
933 |
void OPPROTO op_splatw_T1_64 (void) |
934 |
{ |
935 |
T1_64 = (T1_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL); |
936 |
RETURN(); |
937 |
} |
938 |
|
939 |
void OPPROTO op_extsh_T1_64 (void) |
940 |
{ |
941 |
T1_64 = (int32_t)((int16_t)T1_64); |
942 |
RETURN(); |
943 |
} |
944 |
|
945 |
void OPPROTO op_sli16_T1_64 (void) |
946 |
{ |
947 |
T1_64 = T1_64 << 16;
|
948 |
RETURN(); |
949 |
} |
950 |
|
951 |
void OPPROTO op_sli32_T1_64 (void) |
952 |
{ |
953 |
T1_64 = T1_64 << 32;
|
954 |
RETURN(); |
955 |
} |
956 |
|
957 |
void OPPROTO op_srli32_T1_64 (void) |
958 |
{ |
959 |
T1_64 = T1_64 >> 32;
|
960 |
RETURN(); |
961 |
} |
962 |
|
963 |
void OPPROTO op_evfssub (void) |
964 |
{ |
965 |
do_evfssub(); |
966 |
RETURN(); |
967 |
} |
968 |
|
969 |
void OPPROTO op_evfsadd (void) |
970 |
{ |
971 |
do_evfsadd(); |
972 |
RETURN(); |
973 |
} |
974 |
|
975 |
void OPPROTO op_evfsnabs (void) |
976 |
{ |
977 |
do_evfsnabs(); |
978 |
RETURN(); |
979 |
} |
980 |
|
981 |
void OPPROTO op_evfsabs (void) |
982 |
{ |
983 |
do_evfsabs(); |
984 |
RETURN(); |
985 |
} |
986 |
|
987 |
void OPPROTO op_evfsneg (void) |
988 |
{ |
989 |
do_evfsneg(); |
990 |
RETURN(); |
991 |
} |
992 |
|
993 |
void OPPROTO op_evfsdiv (void) |
994 |
{ |
995 |
do_evfsdiv(); |
996 |
RETURN(); |
997 |
} |
998 |
|
999 |
void OPPROTO op_evfsmul (void) |
1000 |
{ |
1001 |
do_evfsmul(); |
1002 |
RETURN(); |
1003 |
} |
1004 |
|
1005 |
void OPPROTO op_evfscmplt (void) |
1006 |
{ |
1007 |
do_evfscmplt(); |
1008 |
RETURN(); |
1009 |
} |
1010 |
|
1011 |
void OPPROTO op_evfscmpgt (void) |
1012 |
{ |
1013 |
do_evfscmpgt(); |
1014 |
RETURN(); |
1015 |
} |
1016 |
|
1017 |
void OPPROTO op_evfscmpeq (void) |
1018 |
{ |
1019 |
do_evfscmpeq(); |
1020 |
RETURN(); |
1021 |
} |
1022 |
|
1023 |
void OPPROTO op_evfscfsi (void) |
1024 |
{ |
1025 |
do_evfscfsi(); |
1026 |
RETURN(); |
1027 |
} |
1028 |
|
1029 |
void OPPROTO op_evfscfui (void) |
1030 |
{ |
1031 |
do_evfscfui(); |
1032 |
RETURN(); |
1033 |
} |
1034 |
|
1035 |
void OPPROTO op_evfscfsf (void) |
1036 |
{ |
1037 |
do_evfscfsf(); |
1038 |
RETURN(); |
1039 |
} |
1040 |
|
1041 |
void OPPROTO op_evfscfuf (void) |
1042 |
{ |
1043 |
do_evfscfuf(); |
1044 |
RETURN(); |
1045 |
} |
1046 |
|
1047 |
void OPPROTO op_evfsctsi (void) |
1048 |
{ |
1049 |
do_evfsctsi(); |
1050 |
RETURN(); |
1051 |
} |
1052 |
|
1053 |
void OPPROTO op_evfsctui (void) |
1054 |
{ |
1055 |
do_evfsctui(); |
1056 |
RETURN(); |
1057 |
} |
1058 |
|
1059 |
void OPPROTO op_evfsctsf (void) |
1060 |
{ |
1061 |
do_evfsctsf(); |
1062 |
RETURN(); |
1063 |
} |
1064 |
|
1065 |
void OPPROTO op_evfsctuf (void) |
1066 |
{ |
1067 |
do_evfsctuf(); |
1068 |
RETURN(); |
1069 |
} |
1070 |
|
1071 |
void OPPROTO op_evfsctuiz (void) |
1072 |
{ |
1073 |
do_evfsctuiz(); |
1074 |
RETURN(); |
1075 |
} |
1076 |
|
1077 |
void OPPROTO op_evfsctsiz (void) |
1078 |
{ |
1079 |
do_evfsctsiz(); |
1080 |
RETURN(); |
1081 |
} |
1082 |
|
1083 |
void OPPROTO op_evfststlt (void) |
1084 |
{ |
1085 |
do_evfststlt(); |
1086 |
RETURN(); |
1087 |
} |
1088 |
|
1089 |
void OPPROTO op_evfststgt (void) |
1090 |
{ |
1091 |
do_evfststgt(); |
1092 |
RETURN(); |
1093 |
} |
1094 |
|
1095 |
void OPPROTO op_evfststeq (void) |
1096 |
{ |
1097 |
do_evfststeq(); |
1098 |
RETURN(); |
1099 |
} |
1100 |
|
1101 |
void OPPROTO op_efssub (void) |
1102 |
{ |
1103 |
T0_64 = _do_efssub(T0_64, T1_64); |
1104 |
RETURN(); |
1105 |
} |
1106 |
|
1107 |
void OPPROTO op_efsadd (void) |
1108 |
{ |
1109 |
T0_64 = _do_efsadd(T0_64, T1_64); |
1110 |
RETURN(); |
1111 |
} |
1112 |
|
1113 |
void OPPROTO op_efsnabs (void) |
1114 |
{ |
1115 |
T0_64 = _do_efsnabs(T0_64); |
1116 |
RETURN(); |
1117 |
} |
1118 |
|
1119 |
void OPPROTO op_efsabs (void) |
1120 |
{ |
1121 |
T0_64 = _do_efsabs(T0_64); |
1122 |
RETURN(); |
1123 |
} |
1124 |
|
1125 |
void OPPROTO op_efsneg (void) |
1126 |
{ |
1127 |
T0_64 = _do_efsneg(T0_64); |
1128 |
RETURN(); |
1129 |
} |
1130 |
|
1131 |
void OPPROTO op_efsdiv (void) |
1132 |
{ |
1133 |
T0_64 = _do_efsdiv(T0_64, T1_64); |
1134 |
RETURN(); |
1135 |
} |
1136 |
|
1137 |
void OPPROTO op_efsmul (void) |
1138 |
{ |
1139 |
T0_64 = _do_efsmul(T0_64, T1_64); |
1140 |
RETURN(); |
1141 |
} |
1142 |
|
1143 |
void OPPROTO op_efscmplt (void) |
1144 |
{ |
1145 |
do_efscmplt(); |
1146 |
RETURN(); |
1147 |
} |
1148 |
|
1149 |
void OPPROTO op_efscmpgt (void) |
1150 |
{ |
1151 |
do_efscmpgt(); |
1152 |
RETURN(); |
1153 |
} |
1154 |
|
1155 |
void OPPROTO op_efscfd (void) |
1156 |
{ |
1157 |
do_efscfd(); |
1158 |
RETURN(); |
1159 |
} |
1160 |
|
1161 |
void OPPROTO op_efscmpeq (void) |
1162 |
{ |
1163 |
do_efscmpeq(); |
1164 |
RETURN(); |
1165 |
} |
1166 |
|
1167 |
void OPPROTO op_efscfsi (void) |
1168 |
{ |
1169 |
do_efscfsi(); |
1170 |
RETURN(); |
1171 |
} |
1172 |
|
1173 |
void OPPROTO op_efscfui (void) |
1174 |
{ |
1175 |
do_efscfui(); |
1176 |
RETURN(); |
1177 |
} |
1178 |
|
1179 |
void OPPROTO op_efscfsf (void) |
1180 |
{ |
1181 |
do_efscfsf(); |
1182 |
RETURN(); |
1183 |
} |
1184 |
|
1185 |
void OPPROTO op_efscfuf (void) |
1186 |
{ |
1187 |
do_efscfuf(); |
1188 |
RETURN(); |
1189 |
} |
1190 |
|
1191 |
void OPPROTO op_efsctsi (void) |
1192 |
{ |
1193 |
do_efsctsi(); |
1194 |
RETURN(); |
1195 |
} |
1196 |
|
1197 |
void OPPROTO op_efsctui (void) |
1198 |
{ |
1199 |
do_efsctui(); |
1200 |
RETURN(); |
1201 |
} |
1202 |
|
1203 |
void OPPROTO op_efsctsf (void) |
1204 |
{ |
1205 |
do_efsctsf(); |
1206 |
RETURN(); |
1207 |
} |
1208 |
|
1209 |
void OPPROTO op_efsctuf (void) |
1210 |
{ |
1211 |
do_efsctuf(); |
1212 |
RETURN(); |
1213 |
} |
1214 |
|
1215 |
void OPPROTO op_efsctsiz (void) |
1216 |
{ |
1217 |
do_efsctsiz(); |
1218 |
RETURN(); |
1219 |
} |
1220 |
|
1221 |
void OPPROTO op_efsctuiz (void) |
1222 |
{ |
1223 |
do_efsctuiz(); |
1224 |
RETURN(); |
1225 |
} |
1226 |
|
1227 |
void OPPROTO op_efststlt (void) |
1228 |
{ |
1229 |
T0 = _do_efststlt(T0_64, T1_64); |
1230 |
RETURN(); |
1231 |
} |
1232 |
|
1233 |
void OPPROTO op_efststgt (void) |
1234 |
{ |
1235 |
T0 = _do_efststgt(T0_64, T1_64); |
1236 |
RETURN(); |
1237 |
} |
1238 |
|
1239 |
void OPPROTO op_efststeq (void) |
1240 |
{ |
1241 |
T0 = _do_efststeq(T0_64, T1_64); |
1242 |
RETURN(); |
1243 |
} |
1244 |
|
1245 |
void OPPROTO op_efdsub (void) |
1246 |
{ |
1247 |
CPU_DoubleU u1, u2; |
1248 |
u1.ll = T0_64; |
1249 |
u2.ll = T1_64; |
1250 |
u1.d = float64_sub(u1.d, u2.d, &env->spe_status); |
1251 |
T0_64 = u1.ll; |
1252 |
RETURN(); |
1253 |
} |
1254 |
|
1255 |
void OPPROTO op_efdadd (void) |
1256 |
{ |
1257 |
CPU_DoubleU u1, u2; |
1258 |
u1.ll = T0_64; |
1259 |
u2.ll = T1_64; |
1260 |
u1.d = float64_add(u1.d, u2.d, &env->spe_status); |
1261 |
T0_64 = u1.ll; |
1262 |
RETURN(); |
1263 |
} |
1264 |
|
1265 |
void OPPROTO op_efdcfsid (void) |
1266 |
{ |
1267 |
do_efdcfsi(); |
1268 |
RETURN(); |
1269 |
} |
1270 |
|
1271 |
void OPPROTO op_efdcfuid (void) |
1272 |
{ |
1273 |
do_efdcfui(); |
1274 |
RETURN(); |
1275 |
} |
1276 |
|
1277 |
void OPPROTO op_efdnabs (void) |
1278 |
{ |
1279 |
T0_64 |= 0x8000000000000000ULL;
|
1280 |
RETURN(); |
1281 |
} |
1282 |
|
1283 |
void OPPROTO op_efdabs (void) |
1284 |
{ |
1285 |
T0_64 &= ~0x8000000000000000ULL;
|
1286 |
RETURN(); |
1287 |
} |
1288 |
|
1289 |
void OPPROTO op_efdneg (void) |
1290 |
{ |
1291 |
T0_64 ^= 0x8000000000000000ULL;
|
1292 |
RETURN(); |
1293 |
} |
1294 |
|
1295 |
void OPPROTO op_efddiv (void) |
1296 |
{ |
1297 |
CPU_DoubleU u1, u2; |
1298 |
u1.ll = T0_64; |
1299 |
u2.ll = T1_64; |
1300 |
u1.d = float64_div(u1.d, u2.d, &env->spe_status); |
1301 |
T0_64 = u1.ll; |
1302 |
RETURN(); |
1303 |
} |
1304 |
|
1305 |
void OPPROTO op_efdmul (void) |
1306 |
{ |
1307 |
CPU_DoubleU u1, u2; |
1308 |
u1.ll = T0_64; |
1309 |
u2.ll = T1_64; |
1310 |
u1.d = float64_mul(u1.d, u2.d, &env->spe_status); |
1311 |
T0_64 = u1.ll; |
1312 |
RETURN(); |
1313 |
} |
1314 |
|
1315 |
void OPPROTO op_efdctsidz (void) |
1316 |
{ |
1317 |
do_efdctsiz(); |
1318 |
RETURN(); |
1319 |
} |
1320 |
|
1321 |
void OPPROTO op_efdctuidz (void) |
1322 |
{ |
1323 |
do_efdctuiz(); |
1324 |
RETURN(); |
1325 |
} |
1326 |
|
1327 |
void OPPROTO op_efdcmplt (void) |
1328 |
{ |
1329 |
do_efdcmplt(); |
1330 |
RETURN(); |
1331 |
} |
1332 |
|
1333 |
void OPPROTO op_efdcmpgt (void) |
1334 |
{ |
1335 |
do_efdcmpgt(); |
1336 |
RETURN(); |
1337 |
} |
1338 |
|
1339 |
void OPPROTO op_efdcfs (void) |
1340 |
{ |
1341 |
do_efdcfs(); |
1342 |
RETURN(); |
1343 |
} |
1344 |
|
1345 |
void OPPROTO op_efdcmpeq (void) |
1346 |
{ |
1347 |
do_efdcmpeq(); |
1348 |
RETURN(); |
1349 |
} |
1350 |
|
1351 |
void OPPROTO op_efdcfsi (void) |
1352 |
{ |
1353 |
do_efdcfsi(); |
1354 |
RETURN(); |
1355 |
} |
1356 |
|
1357 |
void OPPROTO op_efdcfui (void) |
1358 |
{ |
1359 |
do_efdcfui(); |
1360 |
RETURN(); |
1361 |
} |
1362 |
|
1363 |
void OPPROTO op_efdcfsf (void) |
1364 |
{ |
1365 |
do_efdcfsf(); |
1366 |
RETURN(); |
1367 |
} |
1368 |
|
1369 |
void OPPROTO op_efdcfuf (void) |
1370 |
{ |
1371 |
do_efdcfuf(); |
1372 |
RETURN(); |
1373 |
} |
1374 |
|
1375 |
void OPPROTO op_efdctsi (void) |
1376 |
{ |
1377 |
do_efdctsi(); |
1378 |
RETURN(); |
1379 |
} |
1380 |
|
1381 |
void OPPROTO op_efdctui (void) |
1382 |
{ |
1383 |
do_efdctui(); |
1384 |
RETURN(); |
1385 |
} |
1386 |
|
1387 |
void OPPROTO op_efdctsf (void) |
1388 |
{ |
1389 |
do_efdctsf(); |
1390 |
RETURN(); |
1391 |
} |
1392 |
|
1393 |
void OPPROTO op_efdctuf (void) |
1394 |
{ |
1395 |
do_efdctuf(); |
1396 |
RETURN(); |
1397 |
} |
1398 |
|
1399 |
void OPPROTO op_efdctuiz (void) |
1400 |
{ |
1401 |
do_efdctuiz(); |
1402 |
RETURN(); |
1403 |
} |
1404 |
|
1405 |
void OPPROTO op_efdctsiz (void) |
1406 |
{ |
1407 |
do_efdctsiz(); |
1408 |
RETURN(); |
1409 |
} |
1410 |
|
1411 |
void OPPROTO op_efdtstlt (void) |
1412 |
{ |
1413 |
T0 = _do_efdtstlt(T0_64, T1_64); |
1414 |
RETURN(); |
1415 |
} |
1416 |
|
1417 |
void OPPROTO op_efdtstgt (void) |
1418 |
{ |
1419 |
T0 = _do_efdtstgt(T0_64, T1_64); |
1420 |
RETURN(); |
1421 |
} |
1422 |
|
1423 |
void OPPROTO op_efdtsteq (void) |
1424 |
{ |
1425 |
T0 = _do_efdtsteq(T0_64, T1_64); |
1426 |
RETURN(); |
1427 |
} |