2003-10-06 Dave Brolley <brolley@redhat.com>
[deliverable/binutils-gdb.git] / sim / frv / memory.c
CommitLineData
b34f6357
DB
1/* frv memory model.
2 Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
3 Contributed by Red Hat.
4
5This file is part of the GNU simulators.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License along
18with this program; if not, write to the Free Software Foundation, Inc.,
1959 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21#define WANT_CPU frvbf
22#define WANT_CPU_FRVBF
23
24#include "sim-main.h"
25#include "cgen-mem.h"
26#include "bfd.h"
27
28/* Check for alignment and access restrictions. Return the corrected address.
29 */
30static SI
31fr400_check_data_read_address (SIM_CPU *current_cpu, SI address, int align_mask)
32{
33 /* Check access restrictions for double word loads only. */
34 if (align_mask == 7)
35 {
36 if ((USI)address >= 0xfe800000 && (USI)address <= 0xfeffffff)
37 frv_queue_data_access_error_interrupt (current_cpu, address);
38 }
39 return address;
40}
41
42static SI
43fr500_check_data_read_address (SIM_CPU *current_cpu, SI address, int align_mask)
44{
45 if (address & align_mask)
46 {
47 frv_queue_mem_address_not_aligned_interrupt (current_cpu, address);
48 address &= ~align_mask;
49 }
50
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);
54
55 return address;
56}
57
58static SI
59check_data_read_address (SIM_CPU *current_cpu, SI address, int align_mask)
60{
61 SIM_DESC sd = CPU_STATE (current_cpu);
62 switch (STATE_ARCHITECTURE (sd)->mach)
63 {
64 case bfd_mach_fr400:
65 address = fr400_check_data_read_address (current_cpu, address,
66 align_mask);
67 break;
68 case bfd_mach_frvtomcat:
69 case bfd_mach_fr500:
70 case bfd_mach_frv:
71 address = fr500_check_data_read_address (current_cpu, address,
72 align_mask);
73 break;
74 default:
75 break;
76 }
77
78 return address;
79}
80
81static SI
82fr400_check_readwrite_address (SIM_CPU *current_cpu, SI address, int align_mask)
83{
84 if (address & align_mask)
85 {
86 /* Make sure that this exception is not masked. */
87 USI isr = GET_ISR ();
88 if (! GET_ISR_EMAM (isr))
89 {
90 /* Bad alignment causes a data_access_error on fr400. */
91 frv_queue_data_access_error_interrupt (current_cpu, address);
92 }
93 address &= ~align_mask;
94 }
95 /* Nothing to check. */
96 return address;
97}
98
99static SI
100fr500_check_readwrite_address (SIM_CPU *current_cpu, SI address, int align_mask)
101{
102 if ((USI)address >= 0xfe000000 && (USI)address <= 0xfe003fff
103 || (USI)address >= 0xfe004000 && (USI)address <= 0xfe3fffff
104 || (USI)address >= 0xfe400000 && (USI)address <= 0xfe403fff
105 || (USI)address >= 0xfe404000 && (USI)address <= 0xfe7fffff)
106 frv_queue_data_access_exception_interrupt (current_cpu);
107
108 return address;
109}
110
111static SI
112check_readwrite_address (SIM_CPU *current_cpu, SI address, int align_mask)
113{
114 SIM_DESC sd = CPU_STATE (current_cpu);
115 switch (STATE_ARCHITECTURE (sd)->mach)
116 {
117 case bfd_mach_fr400:
118 address = fr400_check_readwrite_address (current_cpu, address,
119 align_mask);
120 break;
121 case bfd_mach_frvtomcat:
122 case bfd_mach_fr500:
123 case bfd_mach_frv:
124 address = fr500_check_readwrite_address (current_cpu, address,
125 align_mask);
126 break;
127 default:
128 break;
129 }
130
131 return address;
132}
133
134static PCADDR
135fr400_check_insn_read_address (SIM_CPU *current_cpu, PCADDR address,
136 int align_mask)
137{
138 if (address & align_mask)
139 {
140 frv_queue_instruction_access_error_interrupt (current_cpu);
141 address &= ~align_mask;
142 }
143 else if ((USI)address >= 0xfe800000 && (USI)address <= 0xfeffffff)
144 frv_queue_instruction_access_error_interrupt (current_cpu);
145
146 return address;
147}
148
149static PCADDR
150fr500_check_insn_read_address (SIM_CPU *current_cpu, PCADDR address,
151 int align_mask)
152{
153 if (address & align_mask)
154 {
155 frv_queue_mem_address_not_aligned_interrupt (current_cpu, address);
156 address &= ~align_mask;
157 }
158
159 if ((USI)address >= 0xfeff0600 && (USI)address <= 0xfeff7fff
160 || (USI)address >= 0xfe800000 && (USI)address <= 0xfefeffff)
161 frv_queue_instruction_access_error_interrupt (current_cpu);
162 else if ((USI)address >= 0xfe004000 && (USI)address <= 0xfe3fffff
163 || (USI)address >= 0xfe400000 && (USI)address <= 0xfe403fff
164 || (USI)address >= 0xfe404000 && (USI)address <= 0xfe7fffff)
165 frv_queue_instruction_access_exception_interrupt (current_cpu);
166 else
167 {
168 USI hsr0 = GET_HSR0 ();
169 if (! GET_HSR0_RME (hsr0)
170 && (USI)address >= 0xfe000000 && (USI)address <= 0xfe003fff)
171 frv_queue_instruction_access_exception_interrupt (current_cpu);
172 }
173
174 return address;
175}
176
177static PCADDR
178check_insn_read_address (SIM_CPU *current_cpu, PCADDR address, int align_mask)
179{
180 SIM_DESC sd = CPU_STATE (current_cpu);
181 switch (STATE_ARCHITECTURE (sd)->mach)
182 {
183 case bfd_mach_fr400:
184 address = fr400_check_insn_read_address (current_cpu, address,
185 align_mask);
186 break;
187 case bfd_mach_frvtomcat:
188 case bfd_mach_fr500:
189 case bfd_mach_frv:
190 address = fr500_check_insn_read_address (current_cpu, address,
191 align_mask);
192 break;
193 default:
194 break;
195 }
196
197 return address;
198}
199
200/* Memory reads. */
201QI
202frvbf_read_mem_QI (SIM_CPU *current_cpu, IADDR pc, SI address)
203{
204 USI hsr0 = GET_HSR0 ();
205 FRV_CACHE *cache = CPU_DATA_CACHE (current_cpu);
206
207 /* Check for access exceptions. */
208 address = check_data_read_address (current_cpu, address, 0);
209 address = check_readwrite_address (current_cpu, address, 0);
210
211 /* If we need to count cycles, then the cache operation will be
212 initiated from the model profiling functions.
213 See frvbf_model_.... */
214 if (model_insn)
215 {
216 CPU_LOAD_ADDRESS (current_cpu) = address;
217 CPU_LOAD_LENGTH (current_cpu) = 1;
218 CPU_LOAD_SIGNED (current_cpu) = 1;
219 return 0xb7; /* any random value */
220 }
221
222 if (GET_HSR0_DCE (hsr0))
223 {
224 int cycles;
225 cycles = frv_cache_read (cache, 0, address);
226 if (cycles != 0)
227 return CACHE_RETURN_DATA (cache, 0, address, QI, 1);
228 }
229
230 return GETMEMQI (current_cpu, pc, address);
231}
232
233UQI
234frvbf_read_mem_UQI (SIM_CPU *current_cpu, IADDR pc, SI address)
235{
236 USI hsr0 = GET_HSR0 ();
237 FRV_CACHE *cache = CPU_DATA_CACHE (current_cpu);
238
239 /* Check for access exceptions. */
240 address = check_data_read_address (current_cpu, address, 0);
241 address = check_readwrite_address (current_cpu, address, 0);
242
243 /* If we need to count cycles, then the cache operation will be
244 initiated from the model profiling functions.
245 See frvbf_model_.... */
246 if (model_insn)
247 {
248 CPU_LOAD_ADDRESS (current_cpu) = address;
249 CPU_LOAD_LENGTH (current_cpu) = 1;
250 CPU_LOAD_SIGNED (current_cpu) = 0;
251 return 0xb7; /* any random value */
252 }
253
254 if (GET_HSR0_DCE (hsr0))
255 {
256 int cycles;
257 cycles = frv_cache_read (cache, 0, address);
258 if (cycles != 0)
259 return CACHE_RETURN_DATA (cache, 0, address, UQI, 1);
260 }
261
262 return GETMEMUQI (current_cpu, pc, address);
263}
264
265HI
266frvbf_read_mem_HI (SIM_CPU *current_cpu, IADDR pc, SI address)
267{
268 USI hsr0;
269 FRV_CACHE *cache;
270
271 /* Check for access exceptions. */
272 address = check_data_read_address (current_cpu, address, 1);
273 address = check_readwrite_address (current_cpu, address, 1);
274
275 /* If we need to count cycles, then the cache operation will be
276 initiated from the model profiling functions.
277 See frvbf_model_.... */
278 hsr0 = GET_HSR0 ();
279 cache = CPU_DATA_CACHE (current_cpu);
280 if (model_insn)
281 {
282 CPU_LOAD_ADDRESS (current_cpu) = address;
283 CPU_LOAD_LENGTH (current_cpu) = 2;
284 CPU_LOAD_SIGNED (current_cpu) = 1;
285 return 0xb711; /* any random value */
286 }
287
288 if (GET_HSR0_DCE (hsr0))
289 {
290 int cycles;
291 cycles = frv_cache_read (cache, 0, address);
292 if (cycles != 0)
293 return CACHE_RETURN_DATA (cache, 0, address, HI, 2);
294 }
295
296 return GETMEMHI (current_cpu, pc, address);
297}
298
299UHI
300frvbf_read_mem_UHI (SIM_CPU *current_cpu, IADDR pc, SI address)
301{
302 USI hsr0;
303 FRV_CACHE *cache;
304
305 /* Check for access exceptions. */
306 address = check_data_read_address (current_cpu, address, 1);
307 address = check_readwrite_address (current_cpu, address, 1);
308
309 /* If we need to count cycles, then the cache operation will be
310 initiated from the model profiling functions.
311 See frvbf_model_.... */
312 hsr0 = GET_HSR0 ();
313 cache = CPU_DATA_CACHE (current_cpu);
314 if (model_insn)
315 {
316 CPU_LOAD_ADDRESS (current_cpu) = address;
317 CPU_LOAD_LENGTH (current_cpu) = 2;
318 CPU_LOAD_SIGNED (current_cpu) = 0;
319 return 0xb711; /* any random value */
320 }
321
322 if (GET_HSR0_DCE (hsr0))
323 {
324 int cycles;
325 cycles = frv_cache_read (cache, 0, address);
326 if (cycles != 0)
327 return CACHE_RETURN_DATA (cache, 0, address, UHI, 2);
328 }
329
330 return GETMEMUHI (current_cpu, pc, address);
331}
332
333SI
334frvbf_read_mem_SI (SIM_CPU *current_cpu, IADDR pc, SI address)
335{
336 FRV_CACHE *cache;
337 USI hsr0;
338
339 /* Check for access exceptions. */
340 address = check_data_read_address (current_cpu, address, 3);
341 address = check_readwrite_address (current_cpu, address, 3);
342
343 hsr0 = GET_HSR0 ();
344 cache = CPU_DATA_CACHE (current_cpu);
345 /* If we need to count cycles, then the cache operation will be
346 initiated from the model profiling functions.
347 See frvbf_model_.... */
348 if (model_insn)
349 {
350 CPU_LOAD_ADDRESS (current_cpu) = address;
351 CPU_LOAD_LENGTH (current_cpu) = 4;
352 return 0x37111319; /* any random value */
353 }
354
355 if (GET_HSR0_DCE (hsr0))
356 {
357 int cycles;
358 cycles = frv_cache_read (cache, 0, address);
359 if (cycles != 0)
360 return CACHE_RETURN_DATA (cache, 0, address, SI, 4);
361 }
362
363 return GETMEMSI (current_cpu, pc, address);
364}
365
366SI
367frvbf_read_mem_WI (SIM_CPU *current_cpu, IADDR pc, SI address)
368{
369 return frvbf_read_mem_SI (current_cpu, pc, address);
370}
371
372DI
373frvbf_read_mem_DI (SIM_CPU *current_cpu, IADDR pc, SI address)
374{
375 USI hsr0;
376 FRV_CACHE *cache;
377
378 /* Check for access exceptions. */
379 address = check_data_read_address (current_cpu, address, 7);
380 address = check_readwrite_address (current_cpu, address, 7);
381
382 /* If we need to count cycles, then the cache operation will be
383 initiated from the model profiling functions.
384 See frvbf_model_.... */
385 hsr0 = GET_HSR0 ();
386 cache = CPU_DATA_CACHE (current_cpu);
387 if (model_insn)
388 {
389 CPU_LOAD_ADDRESS (current_cpu) = address;
390 CPU_LOAD_LENGTH (current_cpu) = 8;
391 return 0x37111319; /* any random value */
392 }
393
394 if (GET_HSR0_DCE (hsr0))
395 {
396 int cycles;
397 cycles = frv_cache_read (cache, 0, address);
398 if (cycles != 0)
399 return CACHE_RETURN_DATA (cache, 0, address, DI, 8);
400 }
401
402 return GETMEMDI (current_cpu, pc, address);
403}
404
405DF
406frvbf_read_mem_DF (SIM_CPU *current_cpu, IADDR pc, SI address)
407{
408 USI hsr0;
409 FRV_CACHE *cache;
410
411 /* Check for access exceptions. */
412 address = check_data_read_address (current_cpu, address, 7);
413 address = check_readwrite_address (current_cpu, address, 7);
414
415 /* If we need to count cycles, then the cache operation will be
416 initiated from the model profiling functions.
417 See frvbf_model_.... */
418 hsr0 = GET_HSR0 ();
419 cache = CPU_DATA_CACHE (current_cpu);
420 if (model_insn)
421 {
422 CPU_LOAD_ADDRESS (current_cpu) = address;
423 CPU_LOAD_LENGTH (current_cpu) = 8;
424 return 0x37111319; /* any random value */
425 }
426
427 if (GET_HSR0_DCE (hsr0))
428 {
429 int cycles;
430 cycles = frv_cache_read (cache, 0, address);
431 if (cycles != 0)
432 return CACHE_RETURN_DATA (cache, 0, address, DF, 8);
433 }
434
435 return GETMEMDF (current_cpu, pc, address);
436}
437
438USI
439frvbf_read_imem_USI (SIM_CPU *current_cpu, PCADDR vpc)
440{
441 USI hsr0;
442 vpc = check_insn_read_address (current_cpu, vpc, 3);
443
444 hsr0 = GET_HSR0 ();
445 if (GET_HSR0_ICE (hsr0))
446 {
447 FRV_CACHE *cache;
448 USI value;
449
450 /* We don't want this to show up in the cache statistics. That read
451 is done in frvbf_simulate_insn_prefetch. So read the cache or memory
452 passively here. */
453 cache = CPU_INSN_CACHE (current_cpu);
454 if (frv_cache_read_passive_SI (cache, vpc, &value))
455 return value;
456 }
457 return sim_core_read_unaligned_4 (current_cpu, vpc, read_map, vpc);
458}
459
460static SI
461fr400_check_write_address (SIM_CPU *current_cpu, SI address, int align_mask)
462{
463 if (address & align_mask)
464 {
465 /* On the fr400, this causes a data_access_error. */
466 /* Make sure that this exception is not masked. */
467 USI isr = GET_ISR ();
468 if (! GET_ISR_EMAM (isr))
469 {
470 /* Bad alignment causes a data_access_error on fr400. */
471 frv_queue_data_access_error_interrupt (current_cpu, address);
472 }
473 address &= ~align_mask;
474 }
475 if (align_mask == 7
476 && address >= 0xfe800000 && address <= 0xfeffffff)
477 frv_queue_program_interrupt (current_cpu, FRV_DATA_STORE_ERROR);
478
479 return address;
480}
481
482static SI
483fr500_check_write_address (SIM_CPU *current_cpu, SI address, int align_mask)
484{
485 if (address & align_mask)
486 {
487 struct frv_interrupt_queue_element *item =
488 frv_queue_mem_address_not_aligned_interrupt (current_cpu, address);
489 /* Record the correct vliw slot with the interrupt. */
490 if (item != NULL)
491 item->slot = frv_interrupt_state.slot;
492 address &= ~align_mask;
493 }
494 if (address >= 0xfeff0600 && address <= 0xfeff7fff
495 || address >= 0xfe800000 && address <= 0xfefeffff)
496 frv_queue_program_interrupt (current_cpu, FRV_DATA_STORE_ERROR);
497
498 return address;
499}
500
501static SI
502check_write_address (SIM_CPU *current_cpu, SI address, int align_mask)
503{
504 SIM_DESC sd = CPU_STATE (current_cpu);
505 switch (STATE_ARCHITECTURE (sd)->mach)
506 {
507 case bfd_mach_fr400:
508 address = fr400_check_write_address (current_cpu, address, align_mask);
509 break;
510 case bfd_mach_frvtomcat:
511 case bfd_mach_fr500:
512 case bfd_mach_frv:
513 address = fr500_check_write_address (current_cpu, address, align_mask);
514 break;
515 default:
516 break;
517 }
518 return address;
519}
520
521void
522frvbf_write_mem_QI (SIM_CPU *current_cpu, IADDR pc, SI address, QI value)
523{
524 USI hsr0;
525 hsr0 = GET_HSR0 ();
526 if (GET_HSR0_DCE (hsr0))
527 sim_queue_fn_mem_qi_write (current_cpu, frvbf_mem_set_QI, address, value);
528 else
529 sim_queue_mem_qi_write (current_cpu, address, value);
530 frv_set_write_queue_slot (current_cpu);
531}
532
533void
534frvbf_write_mem_UQI (SIM_CPU *current_cpu, IADDR pc, SI address, UQI value)
535{
536 frvbf_write_mem_QI (current_cpu, pc, address, value);
537}
538
539void
540frvbf_write_mem_HI (SIM_CPU *current_cpu, IADDR pc, SI address, HI value)
541{
542 USI hsr0;
543 hsr0 = GET_HSR0 ();
544 if (GET_HSR0_DCE (hsr0))
545 sim_queue_fn_mem_hi_write (current_cpu, frvbf_mem_set_HI, address, value);
546 else
547 sim_queue_mem_hi_write (current_cpu, address, value);
548 frv_set_write_queue_slot (current_cpu);
549}
550
551void
552frvbf_write_mem_UHI (SIM_CPU *current_cpu, IADDR pc, SI address, UHI value)
553{
554 frvbf_write_mem_HI (current_cpu, pc, address, value);
555}
556
557void
558frvbf_write_mem_SI (SIM_CPU *current_cpu, IADDR pc, SI address, SI value)
559{
560 USI hsr0;
561 hsr0 = GET_HSR0 ();
562 if (GET_HSR0_DCE (hsr0))
563 sim_queue_fn_mem_si_write (current_cpu, frvbf_mem_set_SI, address, value);
564 else
565 sim_queue_mem_si_write (current_cpu, address, value);
566 frv_set_write_queue_slot (current_cpu);
567}
568
569void
570frvbf_write_mem_WI (SIM_CPU *current_cpu, IADDR pc, SI address, SI value)
571{
572 frvbf_write_mem_SI (current_cpu, pc, address, value);
573}
574
575void
576frvbf_write_mem_DI (SIM_CPU *current_cpu, IADDR pc, SI address, DI value)
577{
578 USI hsr0;
579 hsr0 = GET_HSR0 ();
580 if (GET_HSR0_DCE (hsr0))
581 sim_queue_fn_mem_di_write (current_cpu, frvbf_mem_set_DI, address, value);
582 else
583 sim_queue_mem_di_write (current_cpu, address, value);
584 frv_set_write_queue_slot (current_cpu);
585}
586
587void
588frvbf_write_mem_DF (SIM_CPU *current_cpu, IADDR pc, SI address, DF value)
589{
590 USI hsr0;
591 hsr0 = GET_HSR0 ();
592 if (GET_HSR0_DCE (hsr0))
593 sim_queue_fn_mem_df_write (current_cpu, frvbf_mem_set_DF, address, value);
594 else
595 sim_queue_mem_df_write (current_cpu, address, value);
596 frv_set_write_queue_slot (current_cpu);
597}
598
599/* Memory writes. These do the actual writing through the cache. */
600void
601frvbf_mem_set_QI (SIM_CPU *current_cpu, IADDR pc, SI address, QI value)
602{
603 FRV_CACHE *cache = CPU_DATA_CACHE (current_cpu);
604
605 /* Check for access errors. */
606 address = check_write_address (current_cpu, address, 0);
607 address = check_readwrite_address (current_cpu, address, 0);
608
609 /* If we need to count cycles, then submit the write request to the cache
610 and let it prioritize the request. Otherwise perform the write now. */
611 if (model_insn)
612 {
613 int slot = UNIT_I0;
614 frv_cache_request_store (cache, address, slot, (char *)&value,
615 sizeof (value));
616 }
617 else
618 frv_cache_write (cache, address, (char *)&value, sizeof (value));
619}
620
621void
622frvbf_mem_set_HI (SIM_CPU *current_cpu, IADDR pc, SI address, HI value)
623{
624 FRV_CACHE *cache;
625
626 /* Check for access errors. */
627 address = check_write_address (current_cpu, address, 1);
628 address = check_readwrite_address (current_cpu, address, 1);
629
630 /* If we need to count cycles, then submit the write request to the cache
631 and let it prioritize the request. Otherwise perform the write now. */
632 value = H2T_2 (value);
633 cache = CPU_DATA_CACHE (current_cpu);
634 if (model_insn)
635 {
636 int slot = UNIT_I0;
637 frv_cache_request_store (cache, address, slot,
638 (char *)&value, sizeof (value));
639 }
640 else
641 frv_cache_write (cache, address, (char *)&value, sizeof (value));
642}
643
644void
645frvbf_mem_set_SI (SIM_CPU *current_cpu, IADDR pc, SI address, SI value)
646{
647 FRV_CACHE *cache;
648
649 /* Check for access errors. */
650 address = check_write_address (current_cpu, address, 3);
651 address = check_readwrite_address (current_cpu, address, 3);
652
653 /* If we need to count cycles, then submit the write request to the cache
654 and let it prioritize the request. Otherwise perform the write now. */
655 cache = CPU_DATA_CACHE (current_cpu);
656 value = H2T_4 (value);
657 if (model_insn)
658 {
659 int slot = UNIT_I0;
660 frv_cache_request_store (cache, address, slot,
661 (char *)&value, sizeof (value));
662 }
663 else
664 frv_cache_write (cache, address, (char *)&value, sizeof (value));
665}
666
667void
668frvbf_mem_set_DI (SIM_CPU *current_cpu, IADDR pc, SI address, DI value)
669{
670 FRV_CACHE *cache;
671
672 /* Check for access errors. */
673 address = check_write_address (current_cpu, address, 7);
674 address = check_readwrite_address (current_cpu, address, 7);
675
676 /* If we need to count cycles, then submit the write request to the cache
677 and let it prioritize the request. Otherwise perform the write now. */
678 value = H2T_8 (value);
679 cache = CPU_DATA_CACHE (current_cpu);
680 if (model_insn)
681 {
682 int slot = UNIT_I0;
683 frv_cache_request_store (cache, address, slot,
684 (char *)&value, sizeof (value));
685 }
686 else
687 frv_cache_write (cache, address, (char *)&value, sizeof (value));
688}
689
690void
691frvbf_mem_set_DF (SIM_CPU *current_cpu, IADDR pc, SI address, DF value)
692{
693 FRV_CACHE *cache;
694
695 /* Check for access errors. */
696 address = check_write_address (current_cpu, address, 7);
697 address = check_readwrite_address (current_cpu, address, 7);
698
699 /* If we need to count cycles, then submit the write request to the cache
700 and let it prioritize the request. Otherwise perform the write now. */
701 value = H2T_8 (value);
702 cache = CPU_DATA_CACHE (current_cpu);
703 if (model_insn)
704 {
705 int slot = UNIT_I0;
706 frv_cache_request_store (cache, address, slot,
707 (char *)&value, sizeof (value));
708 }
709 else
710 frv_cache_write (cache, address, (char *)&value, sizeof (value));
711}
712
713void
714frvbf_mem_set_XI (SIM_CPU *current_cpu, IADDR pc, SI address, SI *value)
715{
716 int i;
717 FRV_CACHE *cache;
718
719 /* Check for access errors. */
720 address = check_write_address (current_cpu, address, 0xf);
721 address = check_readwrite_address (current_cpu, address, 0xf);
722
723 /* TODO -- reverse word order as well? */
724 for (i = 0; i < 4; ++i)
725 value[i] = H2T_4 (value[i]);
726
727 /* If we need to count cycles, then submit the write request to the cache
728 and let it prioritize the request. Otherwise perform the write now. */
729 cache = CPU_DATA_CACHE (current_cpu);
730 if (model_insn)
731 {
732 int slot = UNIT_I0;
733 frv_cache_request_store (cache, address, slot, (char*)value, 16);
734 }
735 else
736 frv_cache_write (cache, address, (char*)value, 16);
737}
738
739/* Record the current VLIW slot on the element at the top of the write queue.
740*/
741void
742frv_set_write_queue_slot (SIM_CPU *current_cpu)
743{
744 FRV_VLIW *vliw = CPU_VLIW (current_cpu);
745 int slot = vliw->next_slot - 1;
746 CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (current_cpu);
747 int ix = CGEN_WRITE_QUEUE_INDEX (q) - 1;
748 CGEN_WRITE_QUEUE_ELEMENT *item = CGEN_WRITE_QUEUE_ELEMENT (q, ix);
749 CGEN_WRITE_QUEUE_ELEMENT_PIPE (item) = (*vliw->current_vliw)[slot];
750}
This page took 0.08002 seconds and 4 git commands to generate.