]> Git Repo - binutils.git/blob - sim/frv/memory.c
New simulator for Fujitsu frv contributed by Red Hat.
[binutils.git] / sim / frv / memory.c
1 /* frv memory model.
2    Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
3    Contributed by Red Hat.
4
5 This file is part of the GNU simulators.
6
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)
10 any later version.
11
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.
16
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.  */
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  */
30 static SI
31 fr400_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
42 static SI
43 fr500_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
58 static SI
59 check_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
81 static SI
82 fr400_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
99 static SI
100 fr500_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
111 static SI
112 check_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
134 static PCADDR
135 fr400_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
149 static PCADDR
150 fr500_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
177 static PCADDR
178 check_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.  */
201 QI
202 frvbf_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
233 UQI
234 frvbf_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
265 HI
266 frvbf_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
299 UHI
300 frvbf_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
333 SI
334 frvbf_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
366 SI
367 frvbf_read_mem_WI (SIM_CPU *current_cpu, IADDR pc, SI address)
368 {
369   return frvbf_read_mem_SI (current_cpu, pc, address);
370 }
371
372 DI
373 frvbf_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
405 DF
406 frvbf_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
438 USI
439 frvbf_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
460 static SI
461 fr400_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
482 static SI
483 fr500_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
501 static SI
502 check_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
521 void
522 frvbf_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
533 void
534 frvbf_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
539 void
540 frvbf_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
551 void
552 frvbf_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
557 void
558 frvbf_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
569 void
570 frvbf_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
575 void
576 frvbf_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
587 void
588 frvbf_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.  */
600 void
601 frvbf_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
621 void
622 frvbf_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
644 void
645 frvbf_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
667 void
668 frvbf_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
690 void
691 frvbf_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
713 void
714 frvbf_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 */
741 void
742 frv_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.065714 seconds and 4 git commands to generate.