2 Copyright (C) 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
5 This file is part of the GNU simulators.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21 #define WANT_CPU frvbf
22 #define WANT_CPU_FRVBF
28 /* Check for alignment and access restrictions. Return the corrected address.
31 fr400_check_data_read_address (SIM_CPU
*current_cpu
, SI address
, int align_mask
)
33 /* Check access restrictions for double word loads only. */
36 if ((USI
)address
>= 0xfe800000 && (USI
)address
<= 0xfeffffff)
37 frv_queue_data_access_error_interrupt (current_cpu
, address
);
43 fr500_check_data_read_address (SIM_CPU
*current_cpu
, SI address
, int align_mask
)
45 if (address
& align_mask
)
47 frv_queue_mem_address_not_aligned_interrupt (current_cpu
, address
);
48 address
&= ~align_mask
;
51 if ((USI
)address
>= 0xfeff0600 && (USI
)address
<= 0xfeff7fff
52 || (USI
)address
>= 0xfe800000 && (USI
)address
<= 0xfefeffff)
53 frv_queue_data_access_error_interrupt (current_cpu
, address
);
59 fr550_check_data_read_address (SIM_CPU
*current_cpu
, SI address
, int align_mask
)
61 if ((USI
)address
>= 0xfe800000 && (USI
)address
<= 0xfefeffff
63 && ((USI
)address
>= 0xfeff0000 && (USI
)address
<= 0xfeffffff)))
64 frv_queue_data_access_error_interrupt (current_cpu
, address
);
70 check_data_read_address (SIM_CPU
*current_cpu
, SI address
, int align_mask
)
72 SIM_DESC sd
= CPU_STATE (current_cpu
);
73 switch (STATE_ARCHITECTURE (sd
)->mach
)
76 address
= fr400_check_data_read_address (current_cpu
, address
,
79 case bfd_mach_frvtomcat
:
82 address
= fr500_check_data_read_address (current_cpu
, address
,
86 address
= fr550_check_data_read_address (current_cpu
, address
,
97 fr400_check_readwrite_address (SIM_CPU
*current_cpu
, SI address
, int align_mask
)
99 if (address
& align_mask
)
101 /* Make sure that this exception is not masked. */
102 USI isr
= GET_ISR ();
103 if (! GET_ISR_EMAM (isr
))
105 /* Bad alignment causes a data_access_error on fr400. */
106 frv_queue_data_access_error_interrupt (current_cpu
, address
);
108 address
&= ~align_mask
;
110 /* Nothing to check. */
115 fr500_check_readwrite_address (SIM_CPU
*current_cpu
, SI address
, int align_mask
)
117 if ((USI
)address
>= 0xfe000000 && (USI
)address
<= 0xfe003fff
118 || (USI
)address
>= 0xfe004000 && (USI
)address
<= 0xfe3fffff
119 || (USI
)address
>= 0xfe400000 && (USI
)address
<= 0xfe403fff
120 || (USI
)address
>= 0xfe404000 && (USI
)address
<= 0xfe7fffff)
121 frv_queue_data_access_exception_interrupt (current_cpu
);
127 fr550_check_readwrite_address (SIM_CPU
*current_cpu
, SI address
, int align_mask
)
129 /* No alignment restrictions on fr550 */
131 if ((USI
)address
>= 0xfe000000 && (USI
)address
<= 0xfe3fffff
132 || (USI
)address
>= 0xfe408000 && (USI
)address
<= 0xfe7fffff)
133 frv_queue_data_access_exception_interrupt (current_cpu
);
136 USI hsr0
= GET_HSR0 ();
137 if (! GET_HSR0_RME (hsr0
)
138 && (USI
)address
>= 0xfe400000 && (USI
)address
<= 0xfe407fff)
139 frv_queue_data_access_exception_interrupt (current_cpu
);
146 check_readwrite_address (SIM_CPU
*current_cpu
, SI address
, int align_mask
)
148 SIM_DESC sd
= CPU_STATE (current_cpu
);
149 switch (STATE_ARCHITECTURE (sd
)->mach
)
152 address
= fr400_check_readwrite_address (current_cpu
, address
,
155 case bfd_mach_frvtomcat
:
158 address
= fr500_check_readwrite_address (current_cpu
, address
,
162 address
= fr550_check_readwrite_address (current_cpu
, address
,
173 fr400_check_insn_read_address (SIM_CPU
*current_cpu
, PCADDR address
,
176 if (address
& align_mask
)
178 frv_queue_instruction_access_error_interrupt (current_cpu
);
179 address
&= ~align_mask
;
181 else if ((USI
)address
>= 0xfe800000 && (USI
)address
<= 0xfeffffff)
182 frv_queue_instruction_access_error_interrupt (current_cpu
);
188 fr500_check_insn_read_address (SIM_CPU
*current_cpu
, PCADDR address
,
191 if (address
& align_mask
)
193 frv_queue_mem_address_not_aligned_interrupt (current_cpu
, address
);
194 address
&= ~align_mask
;
197 if ((USI
)address
>= 0xfeff0600 && (USI
)address
<= 0xfeff7fff
198 || (USI
)address
>= 0xfe800000 && (USI
)address
<= 0xfefeffff)
199 frv_queue_instruction_access_error_interrupt (current_cpu
);
200 else if ((USI
)address
>= 0xfe004000 && (USI
)address
<= 0xfe3fffff
201 || (USI
)address
>= 0xfe400000 && (USI
)address
<= 0xfe403fff
202 || (USI
)address
>= 0xfe404000 && (USI
)address
<= 0xfe7fffff)
203 frv_queue_instruction_access_exception_interrupt (current_cpu
);
206 USI hsr0
= GET_HSR0 ();
207 if (! GET_HSR0_RME (hsr0
)
208 && (USI
)address
>= 0xfe000000 && (USI
)address
<= 0xfe003fff)
209 frv_queue_instruction_access_exception_interrupt (current_cpu
);
216 fr550_check_insn_read_address (SIM_CPU
*current_cpu
, PCADDR address
,
219 address
&= ~align_mask
;
221 if ((USI
)address
>= 0xfe800000 && (USI
)address
<= 0xfeffffff)
222 frv_queue_instruction_access_error_interrupt (current_cpu
);
223 else if ((USI
)address
>= 0xfe008000 && (USI
)address
<= 0xfe7fffff)
224 frv_queue_instruction_access_exception_interrupt (current_cpu
);
227 USI hsr0
= GET_HSR0 ();
228 if (! GET_HSR0_RME (hsr0
)
229 && (USI
)address
>= 0xfe000000 && (USI
)address
<= 0xfe007fff)
230 frv_queue_instruction_access_exception_interrupt (current_cpu
);
237 check_insn_read_address (SIM_CPU
*current_cpu
, PCADDR address
, int align_mask
)
239 SIM_DESC sd
= CPU_STATE (current_cpu
);
240 switch (STATE_ARCHITECTURE (sd
)->mach
)
243 address
= fr400_check_insn_read_address (current_cpu
, address
,
246 case bfd_mach_frvtomcat
:
249 address
= fr500_check_insn_read_address (current_cpu
, address
,
253 address
= fr550_check_insn_read_address (current_cpu
, address
,
265 frvbf_read_mem_QI (SIM_CPU
*current_cpu
, IADDR pc
, SI address
)
267 USI hsr0
= GET_HSR0 ();
268 FRV_CACHE
*cache
= CPU_DATA_CACHE (current_cpu
);
270 /* Check for access exceptions. */
271 address
= check_data_read_address (current_cpu
, address
, 0);
272 address
= check_readwrite_address (current_cpu
, address
, 0);
274 /* If we need to count cycles, then the cache operation will be
275 initiated from the model profiling functions.
276 See frvbf_model_.... */
279 CPU_LOAD_ADDRESS (current_cpu
) = address
;
280 CPU_LOAD_LENGTH (current_cpu
) = 1;
281 CPU_LOAD_SIGNED (current_cpu
) = 1;
282 return 0xb7; /* any random value */
285 if (GET_HSR0_DCE (hsr0
))
288 cycles
= frv_cache_read (cache
, 0, address
);
290 return CACHE_RETURN_DATA (cache
, 0, address
, QI
, 1);
293 return GETMEMQI (current_cpu
, pc
, address
);
297 frvbf_read_mem_UQI (SIM_CPU
*current_cpu
, IADDR pc
, SI address
)
299 USI hsr0
= GET_HSR0 ();
300 FRV_CACHE
*cache
= CPU_DATA_CACHE (current_cpu
);
302 /* Check for access exceptions. */
303 address
= check_data_read_address (current_cpu
, address
, 0);
304 address
= check_readwrite_address (current_cpu
, address
, 0);
306 /* If we need to count cycles, then the cache operation will be
307 initiated from the model profiling functions.
308 See frvbf_model_.... */
311 CPU_LOAD_ADDRESS (current_cpu
) = address
;
312 CPU_LOAD_LENGTH (current_cpu
) = 1;
313 CPU_LOAD_SIGNED (current_cpu
) = 0;
314 return 0xb7; /* any random value */
317 if (GET_HSR0_DCE (hsr0
))
320 cycles
= frv_cache_read (cache
, 0, address
);
322 return CACHE_RETURN_DATA (cache
, 0, address
, UQI
, 1);
325 return GETMEMUQI (current_cpu
, pc
, address
);
328 /* Read a HI which spans two cache lines */
330 read_mem_unaligned_HI (SIM_CPU
*current_cpu
, IADDR pc
, SI address
)
332 HI value
= frvbf_read_mem_QI (current_cpu
, pc
, address
);
334 value
|= frvbf_read_mem_UQI (current_cpu
, pc
, address
+ 1);
335 return T2H_2 (value
);
339 frvbf_read_mem_HI (SIM_CPU
*current_cpu
, IADDR pc
, SI address
)
344 /* Check for access exceptions. */
345 address
= check_data_read_address (current_cpu
, address
, 1);
346 address
= check_readwrite_address (current_cpu
, address
, 1);
348 /* If we need to count cycles, then the cache operation will be
349 initiated from the model profiling functions.
350 See frvbf_model_.... */
352 cache
= CPU_DATA_CACHE (current_cpu
);
355 CPU_LOAD_ADDRESS (current_cpu
) = address
;
356 CPU_LOAD_LENGTH (current_cpu
) = 2;
357 CPU_LOAD_SIGNED (current_cpu
) = 1;
358 return 0xb711; /* any random value */
361 if (GET_HSR0_DCE (hsr0
))
364 /* Handle access which crosses cache line boundary */
365 SIM_DESC sd
= CPU_STATE (current_cpu
);
366 if (STATE_ARCHITECTURE (sd
)->mach
== bfd_mach_fr550
)
368 if (DATA_CROSSES_CACHE_LINE (cache
, address
, 2))
369 return read_mem_unaligned_HI (current_cpu
, pc
, address
);
371 cycles
= frv_cache_read (cache
, 0, address
);
373 return CACHE_RETURN_DATA (cache
, 0, address
, HI
, 2);
376 return GETMEMHI (current_cpu
, pc
, address
);
380 frvbf_read_mem_UHI (SIM_CPU
*current_cpu
, IADDR pc
, SI address
)
385 /* Check for access exceptions. */
386 address
= check_data_read_address (current_cpu
, address
, 1);
387 address
= check_readwrite_address (current_cpu
, address
, 1);
389 /* If we need to count cycles, then the cache operation will be
390 initiated from the model profiling functions.
391 See frvbf_model_.... */
393 cache
= CPU_DATA_CACHE (current_cpu
);
396 CPU_LOAD_ADDRESS (current_cpu
) = address
;
397 CPU_LOAD_LENGTH (current_cpu
) = 2;
398 CPU_LOAD_SIGNED (current_cpu
) = 0;
399 return 0xb711; /* any random value */
402 if (GET_HSR0_DCE (hsr0
))
405 /* Handle access which crosses cache line boundary */
406 SIM_DESC sd
= CPU_STATE (current_cpu
);
407 if (STATE_ARCHITECTURE (sd
)->mach
== bfd_mach_fr550
)
409 if (DATA_CROSSES_CACHE_LINE (cache
, address
, 2))
410 return read_mem_unaligned_HI (current_cpu
, pc
, address
);
412 cycles
= frv_cache_read (cache
, 0, address
);
414 return CACHE_RETURN_DATA (cache
, 0, address
, UHI
, 2);
417 return GETMEMUHI (current_cpu
, pc
, address
);
420 /* Read a SI which spans two cache lines */
422 read_mem_unaligned_SI (SIM_CPU
*current_cpu
, IADDR pc
, SI address
)
424 FRV_CACHE
*cache
= CPU_DATA_CACHE (current_cpu
);
425 unsigned hi_len
= cache
->line_size
- (address
& (cache
->line_size
- 1));
433 valarray
[0] = frvbf_read_mem_QI (current_cpu
, pc
, address
);
434 SIvalue
= frvbf_read_mem_SI (current_cpu
, pc
, address
+ 1);
435 SIvalue
= H2T_4 (SIvalue
);
436 memcpy (valarray
+ 1, (char*)&SIvalue
, 3);
439 HIvalue
= frvbf_read_mem_HI (current_cpu
, pc
, address
);
440 HIvalue
= H2T_2 (HIvalue
);
441 memcpy (valarray
, (char*)&HIvalue
, 2);
442 HIvalue
= frvbf_read_mem_HI (current_cpu
, pc
, address
+ 2);
443 HIvalue
= H2T_2 (HIvalue
);
444 memcpy (valarray
+ 2, (char*)&HIvalue
, 2);
447 SIvalue
= frvbf_read_mem_SI (current_cpu
, pc
, address
- 1);
448 SIvalue
= H2T_4 (SIvalue
);
449 memcpy (valarray
, (char*)&SIvalue
, 3);
450 valarray
[3] = frvbf_read_mem_QI (current_cpu
, pc
, address
+ 3);
453 abort (); /* can't happen */
455 return T2H_4 (*(SI
*)valarray
);
459 frvbf_read_mem_SI (SIM_CPU
*current_cpu
, IADDR pc
, SI address
)
464 /* Check for access exceptions. */
465 address
= check_data_read_address (current_cpu
, address
, 3);
466 address
= check_readwrite_address (current_cpu
, address
, 3);
469 cache
= CPU_DATA_CACHE (current_cpu
);
470 /* If we need to count cycles, then the cache operation will be
471 initiated from the model profiling functions.
472 See frvbf_model_.... */
475 CPU_LOAD_ADDRESS (current_cpu
) = address
;
476 CPU_LOAD_LENGTH (current_cpu
) = 4;
477 return 0x37111319; /* any random value */
480 if (GET_HSR0_DCE (hsr0
))
483 /* Handle access which crosses cache line boundary */
484 SIM_DESC sd
= CPU_STATE (current_cpu
);
485 if (STATE_ARCHITECTURE (sd
)->mach
== bfd_mach_fr550
)
487 if (DATA_CROSSES_CACHE_LINE (cache
, address
, 4))
488 return read_mem_unaligned_SI (current_cpu
, pc
, address
);
490 cycles
= frv_cache_read (cache
, 0, address
);
492 return CACHE_RETURN_DATA (cache
, 0, address
, SI
, 4);
495 return GETMEMSI (current_cpu
, pc
, address
);
499 frvbf_read_mem_WI (SIM_CPU
*current_cpu
, IADDR pc
, SI address
)
501 return frvbf_read_mem_SI (current_cpu
, pc
, address
);
504 /* Read a SI which spans two cache lines */
506 read_mem_unaligned_DI (SIM_CPU
*current_cpu
, IADDR pc
, SI address
)
508 FRV_CACHE
*cache
= CPU_DATA_CACHE (current_cpu
);
509 unsigned hi_len
= cache
->line_size
- (address
& (cache
->line_size
- 1));
515 value
= frvbf_read_mem_QI (current_cpu
, pc
, address
);
517 value1
= frvbf_read_mem_DI (current_cpu
, pc
, address
+ 1);
518 value1
= H2T_8 (value1
);
519 value
|= value1
& ((DI
)0x00ffffff << 32);
520 value
|= value1
& 0xffffffffu
;
523 value
= frvbf_read_mem_HI (current_cpu
, pc
, address
);
524 value
= H2T_2 (value
);
526 value1
= frvbf_read_mem_DI (current_cpu
, pc
, address
+ 2);
527 value1
= H2T_8 (value1
);
528 value
|= value1
& ((DI
)0x0000ffff << 32);
529 value
|= value1
& 0xffffffffu
;
532 value
= frvbf_read_mem_SI (current_cpu
, pc
, address
- 1);
533 value
= H2T_4 (value
);
535 value1
= frvbf_read_mem_DI (current_cpu
, pc
, address
+ 3);
536 value1
= H2T_8 (value1
);
537 value
|= value1
& ((DI
)0x000000ff << 32);
538 value
|= value1
& 0xffffffffu
;
541 value
= frvbf_read_mem_SI (current_cpu
, pc
, address
);
542 value
= H2T_4 (value
);
544 value1
= frvbf_read_mem_SI (current_cpu
, pc
, address
+ 4);
545 value1
= H2T_4 (value1
);
546 value
|= value1
& 0xffffffffu
;
549 value
= frvbf_read_mem_DI (current_cpu
, pc
, address
- 3);
550 value
= H2T_8 (value
);
552 value1
= frvbf_read_mem_SI (current_cpu
, pc
, address
+ 5);
553 value1
= H2T_4 (value1
);
554 value
|= value1
& 0x00ffffff;
557 value
= frvbf_read_mem_DI (current_cpu
, pc
, address
- 2);
558 value
= H2T_8 (value
);
560 value1
= frvbf_read_mem_HI (current_cpu
, pc
, address
+ 6);
561 value1
= H2T_2 (value1
);
562 value
|= value1
& 0x0000ffff;
565 value
= frvbf_read_mem_DI (current_cpu
, pc
, address
- 1);
566 value
= H2T_8 (value
);
568 value1
= frvbf_read_mem_QI (current_cpu
, pc
, address
+ 7);
569 value
|= value1
& 0x000000ff;
572 abort (); /* can't happen */
574 return T2H_8 (value
);
578 frvbf_read_mem_DI (SIM_CPU
*current_cpu
, IADDR pc
, SI address
)
583 /* Check for access exceptions. */
584 address
= check_data_read_address (current_cpu
, address
, 7);
585 address
= check_readwrite_address (current_cpu
, address
, 7);
587 /* If we need to count cycles, then the cache operation will be
588 initiated from the model profiling functions.
589 See frvbf_model_.... */
591 cache
= CPU_DATA_CACHE (current_cpu
);
594 CPU_LOAD_ADDRESS (current_cpu
) = address
;
595 CPU_LOAD_LENGTH (current_cpu
) = 8;
596 return 0x37111319; /* any random value */
599 if (GET_HSR0_DCE (hsr0
))
602 /* Handle access which crosses cache line boundary */
603 SIM_DESC sd
= CPU_STATE (current_cpu
);
604 if (STATE_ARCHITECTURE (sd
)->mach
== bfd_mach_fr550
)
606 if (DATA_CROSSES_CACHE_LINE (cache
, address
, 8))
607 return read_mem_unaligned_DI (current_cpu
, pc
, address
);
609 cycles
= frv_cache_read (cache
, 0, address
);
611 return CACHE_RETURN_DATA (cache
, 0, address
, DI
, 8);
614 return GETMEMDI (current_cpu
, pc
, address
);
618 frvbf_read_mem_DF (SIM_CPU
*current_cpu
, IADDR pc
, SI address
)
623 /* Check for access exceptions. */
624 address
= check_data_read_address (current_cpu
, address
, 7);
625 address
= check_readwrite_address (current_cpu
, address
, 7);
627 /* If we need to count cycles, then the cache operation will be
628 initiated from the model profiling functions.
629 See frvbf_model_.... */
631 cache
= CPU_DATA_CACHE (current_cpu
);
634 CPU_LOAD_ADDRESS (current_cpu
) = address
;
635 CPU_LOAD_LENGTH (current_cpu
) = 8;
636 return 0x37111319; /* any random value */
639 if (GET_HSR0_DCE (hsr0
))
642 /* Handle access which crosses cache line boundary */
643 SIM_DESC sd
= CPU_STATE (current_cpu
);
644 if (STATE_ARCHITECTURE (sd
)->mach
== bfd_mach_fr550
)
646 if (DATA_CROSSES_CACHE_LINE (cache
, address
, 8))
647 return read_mem_unaligned_DI (current_cpu
, pc
, address
);
649 cycles
= frv_cache_read (cache
, 0, address
);
651 return CACHE_RETURN_DATA (cache
, 0, address
, DF
, 8);
654 return GETMEMDF (current_cpu
, pc
, address
);
658 frvbf_read_imem_USI (SIM_CPU
*current_cpu
, PCADDR vpc
)
661 vpc
= check_insn_read_address (current_cpu
, vpc
, 3);
664 if (GET_HSR0_ICE (hsr0
))
669 /* We don't want this to show up in the cache statistics. That read
670 is done in frvbf_simulate_insn_prefetch. So read the cache or memory
672 cache
= CPU_INSN_CACHE (current_cpu
);
673 if (frv_cache_read_passive_SI (cache
, vpc
, &value
))
676 return sim_core_read_unaligned_4 (current_cpu
, vpc
, read_map
, vpc
);
680 fr400_check_write_address (SIM_CPU
*current_cpu
, SI address
, int align_mask
)
683 && address
>= 0xfe800000 && address
<= 0xfeffffff)
684 frv_queue_program_interrupt (current_cpu
, FRV_DATA_STORE_ERROR
);
690 fr500_check_write_address (SIM_CPU
*current_cpu
, SI address
, int align_mask
)
692 if (address
& align_mask
)
694 struct frv_interrupt_queue_element
*item
=
695 frv_queue_mem_address_not_aligned_interrupt (current_cpu
, address
);
696 /* Record the correct vliw slot with the interrupt. */
698 item
->slot
= frv_interrupt_state
.slot
;
699 address
&= ~align_mask
;
701 if (address
>= 0xfeff0600 && address
<= 0xfeff7fff
702 || address
>= 0xfe800000 && address
<= 0xfefeffff)
703 frv_queue_program_interrupt (current_cpu
, FRV_DATA_STORE_ERROR
);
709 fr550_check_write_address (SIM_CPU
*current_cpu
, SI address
, int align_mask
)
711 if ((USI
)address
>= 0xfe800000 && (USI
)address
<= 0xfefeffff
713 && ((USI
)address
>= 0xfeff0000 && (USI
)address
<= 0xfeffffff)))
714 frv_queue_program_interrupt (current_cpu
, FRV_DATA_STORE_ERROR
);
720 check_write_address (SIM_CPU
*current_cpu
, SI address
, int align_mask
)
722 SIM_DESC sd
= CPU_STATE (current_cpu
);
723 switch (STATE_ARCHITECTURE (sd
)->mach
)
726 address
= fr400_check_write_address (current_cpu
, address
, align_mask
);
728 case bfd_mach_frvtomcat
:
731 address
= fr500_check_write_address (current_cpu
, address
, align_mask
);
734 address
= fr550_check_write_address (current_cpu
, address
, align_mask
);
743 frvbf_write_mem_QI (SIM_CPU
*current_cpu
, IADDR pc
, SI address
, QI value
)
747 if (GET_HSR0_DCE (hsr0
))
748 sim_queue_fn_mem_qi_write (current_cpu
, frvbf_mem_set_QI
, address
, value
);
750 sim_queue_mem_qi_write (current_cpu
, address
, value
);
751 frv_set_write_queue_slot (current_cpu
);
755 frvbf_write_mem_UQI (SIM_CPU
*current_cpu
, IADDR pc
, SI address
, UQI value
)
757 frvbf_write_mem_QI (current_cpu
, pc
, address
, value
);
761 frvbf_write_mem_HI (SIM_CPU
*current_cpu
, IADDR pc
, SI address
, HI value
)
765 if (GET_HSR0_DCE (hsr0
))
766 sim_queue_fn_mem_hi_write (current_cpu
, frvbf_mem_set_HI
, address
, value
);
768 sim_queue_mem_hi_write (current_cpu
, address
, value
);
769 frv_set_write_queue_slot (current_cpu
);
773 frvbf_write_mem_UHI (SIM_CPU
*current_cpu
, IADDR pc
, SI address
, UHI value
)
775 frvbf_write_mem_HI (current_cpu
, pc
, address
, value
);
779 frvbf_write_mem_SI (SIM_CPU
*current_cpu
, IADDR pc
, SI address
, SI value
)
783 if (GET_HSR0_DCE (hsr0
))
784 sim_queue_fn_mem_si_write (current_cpu
, frvbf_mem_set_SI
, address
, value
);
786 sim_queue_mem_si_write (current_cpu
, address
, value
);
787 frv_set_write_queue_slot (current_cpu
);
791 frvbf_write_mem_WI (SIM_CPU
*current_cpu
, IADDR pc
, SI address
, SI value
)
793 frvbf_write_mem_SI (current_cpu
, pc
, address
, value
);
797 frvbf_write_mem_DI (SIM_CPU
*current_cpu
, IADDR pc
, SI address
, DI value
)
801 if (GET_HSR0_DCE (hsr0
))
802 sim_queue_fn_mem_di_write (current_cpu
, frvbf_mem_set_DI
, address
, value
);
804 sim_queue_mem_di_write (current_cpu
, address
, value
);
805 frv_set_write_queue_slot (current_cpu
);
809 frvbf_write_mem_DF (SIM_CPU
*current_cpu
, IADDR pc
, SI address
, DF value
)
813 if (GET_HSR0_DCE (hsr0
))
814 sim_queue_fn_mem_df_write (current_cpu
, frvbf_mem_set_DF
, address
, value
);
816 sim_queue_mem_df_write (current_cpu
, address
, value
);
817 frv_set_write_queue_slot (current_cpu
);
820 /* Memory writes. These do the actual writing through the cache. */
822 frvbf_mem_set_QI (SIM_CPU
*current_cpu
, IADDR pc
, SI address
, QI value
)
824 FRV_CACHE
*cache
= CPU_DATA_CACHE (current_cpu
);
826 /* Check for access errors. */
827 address
= check_write_address (current_cpu
, address
, 0);
828 address
= check_readwrite_address (current_cpu
, address
, 0);
830 /* If we need to count cycles, then submit the write request to the cache
831 and let it prioritize the request. Otherwise perform the write now. */
835 frv_cache_request_store (cache
, address
, slot
, (char *)&value
,
839 frv_cache_write (cache
, address
, (char *)&value
, sizeof (value
));
842 /* Write a HI which spans two cache lines */
844 mem_set_unaligned_HI (SIM_CPU
*current_cpu
, IADDR pc
, SI address
, HI value
)
846 FRV_CACHE
*cache
= CPU_DATA_CACHE (current_cpu
);
847 /* value is already in target byte order */
848 frv_cache_write (cache
, address
, (char *)&value
, 1);
849 frv_cache_write (cache
, address
+ 1, ((char *)&value
+ 1), 1);
853 frvbf_mem_set_HI (SIM_CPU
*current_cpu
, IADDR pc
, SI address
, HI value
)
857 /* Check for access errors. */
858 address
= check_write_address (current_cpu
, address
, 1);
859 address
= check_readwrite_address (current_cpu
, address
, 1);
861 /* If we need to count cycles, then submit the write request to the cache
862 and let it prioritize the request. Otherwise perform the write now. */
863 value
= H2T_2 (value
);
864 cache
= CPU_DATA_CACHE (current_cpu
);
868 frv_cache_request_store (cache
, address
, slot
,
869 (char *)&value
, sizeof (value
));
873 /* Handle access which crosses cache line boundary */
874 SIM_DESC sd
= CPU_STATE (current_cpu
);
875 if (STATE_ARCHITECTURE (sd
)->mach
== bfd_mach_fr550
)
877 if (DATA_CROSSES_CACHE_LINE (cache
, address
, 2))
879 mem_set_unaligned_HI (current_cpu
, pc
, address
, value
);
883 frv_cache_write (cache
, address
, (char *)&value
, sizeof (value
));
887 /* Write a SI which spans two cache lines */
889 mem_set_unaligned_SI (SIM_CPU
*current_cpu
, IADDR pc
, SI address
, SI value
)
891 FRV_CACHE
*cache
= CPU_DATA_CACHE (current_cpu
);
892 unsigned hi_len
= cache
->line_size
- (address
& (cache
->line_size
- 1));
893 /* value is already in target byte order */
894 frv_cache_write (cache
, address
, (char *)&value
, hi_len
);
895 frv_cache_write (cache
, address
+ hi_len
, (char *)&value
+ hi_len
, 4 - hi_len
);
899 frvbf_mem_set_SI (SIM_CPU
*current_cpu
, IADDR pc
, SI address
, SI value
)
903 /* Check for access errors. */
904 address
= check_write_address (current_cpu
, address
, 3);
905 address
= check_readwrite_address (current_cpu
, address
, 3);
907 /* If we need to count cycles, then submit the write request to the cache
908 and let it prioritize the request. Otherwise perform the write now. */
909 cache
= CPU_DATA_CACHE (current_cpu
);
910 value
= H2T_4 (value
);
914 frv_cache_request_store (cache
, address
, slot
,
915 (char *)&value
, sizeof (value
));
919 /* Handle access which crosses cache line boundary */
920 SIM_DESC sd
= CPU_STATE (current_cpu
);
921 if (STATE_ARCHITECTURE (sd
)->mach
== bfd_mach_fr550
)
923 if (DATA_CROSSES_CACHE_LINE (cache
, address
, 4))
925 mem_set_unaligned_SI (current_cpu
, pc
, address
, value
);
929 frv_cache_write (cache
, address
, (char *)&value
, sizeof (value
));
933 /* Write a DI which spans two cache lines */
935 mem_set_unaligned_DI (SIM_CPU
*current_cpu
, IADDR pc
, SI address
, DI value
)
937 FRV_CACHE
*cache
= CPU_DATA_CACHE (current_cpu
);
938 unsigned hi_len
= cache
->line_size
- (address
& (cache
->line_size
- 1));
939 /* value is already in target byte order */
940 frv_cache_write (cache
, address
, (char *)&value
, hi_len
);
941 frv_cache_write (cache
, address
+ hi_len
, (char *)&value
+ hi_len
, 8 - hi_len
);
945 frvbf_mem_set_DI (SIM_CPU
*current_cpu
, IADDR pc
, SI address
, DI value
)
949 /* Check for access errors. */
950 address
= check_write_address (current_cpu
, address
, 7);
951 address
= check_readwrite_address (current_cpu
, address
, 7);
953 /* If we need to count cycles, then submit the write request to the cache
954 and let it prioritize the request. Otherwise perform the write now. */
955 value
= H2T_8 (value
);
956 cache
= CPU_DATA_CACHE (current_cpu
);
960 frv_cache_request_store (cache
, address
, slot
,
961 (char *)&value
, sizeof (value
));
965 /* Handle access which crosses cache line boundary */
966 SIM_DESC sd
= CPU_STATE (current_cpu
);
967 if (STATE_ARCHITECTURE (sd
)->mach
== bfd_mach_fr550
)
969 if (DATA_CROSSES_CACHE_LINE (cache
, address
, 8))
971 mem_set_unaligned_DI (current_cpu
, pc
, address
, value
);
975 frv_cache_write (cache
, address
, (char *)&value
, sizeof (value
));
980 frvbf_mem_set_DF (SIM_CPU
*current_cpu
, IADDR pc
, SI address
, DF value
)
984 /* Check for access errors. */
985 address
= check_write_address (current_cpu
, address
, 7);
986 address
= check_readwrite_address (current_cpu
, address
, 7);
988 /* If we need to count cycles, then submit the write request to the cache
989 and let it prioritize the request. Otherwise perform the write now. */
990 value
= H2T_8 (value
);
991 cache
= CPU_DATA_CACHE (current_cpu
);
995 frv_cache_request_store (cache
, address
, slot
,
996 (char *)&value
, sizeof (value
));
1000 /* Handle access which crosses cache line boundary */
1001 SIM_DESC sd
= CPU_STATE (current_cpu
);
1002 if (STATE_ARCHITECTURE (sd
)->mach
== bfd_mach_fr550
)
1004 if (DATA_CROSSES_CACHE_LINE (cache
, address
, 8))
1006 mem_set_unaligned_DI (current_cpu
, pc
, address
, value
);
1010 frv_cache_write (cache
, address
, (char *)&value
, sizeof (value
));
1015 frvbf_mem_set_XI (SIM_CPU
*current_cpu
, IADDR pc
, SI address
, SI
*value
)
1020 /* Check for access errors. */
1021 address
= check_write_address (current_cpu
, address
, 0xf);
1022 address
= check_readwrite_address (current_cpu
, address
, 0xf);
1024 /* TODO -- reverse word order as well? */
1025 for (i
= 0; i
< 4; ++i
)
1026 value
[i
] = H2T_4 (value
[i
]);
1028 /* If we need to count cycles, then submit the write request to the cache
1029 and let it prioritize the request. Otherwise perform the write now. */
1030 cache
= CPU_DATA_CACHE (current_cpu
);
1034 frv_cache_request_store (cache
, address
, slot
, (char*)value
, 16);
1037 frv_cache_write (cache
, address
, (char*)value
, 16);
1040 /* Record the current VLIW slot on the element at the top of the write queue.
1043 frv_set_write_queue_slot (SIM_CPU
*current_cpu
)
1045 FRV_VLIW
*vliw
= CPU_VLIW (current_cpu
);
1046 int slot
= vliw
->next_slot
- 1;
1047 CGEN_WRITE_QUEUE
*q
= CPU_WRITE_QUEUE (current_cpu
);
1048 int ix
= CGEN_WRITE_QUEUE_INDEX (q
) - 1;
1049 CGEN_WRITE_QUEUE_ELEMENT
*item
= CGEN_WRITE_QUEUE_ELEMENT (q
, ix
);
1050 CGEN_WRITE_QUEUE_ELEMENT_PIPE (item
) = (*vliw
->current_vliw
)[slot
];