xref: /netbsd/external/gpl3/gdb.old/dist/sim/frv/memory.c (revision 184b2d41)
1a1ba9ba4Schristos /* frv memory model.
2*184b2d41Schristos    Copyright (C) 1999-2020 Free Software Foundation, Inc.
3a1ba9ba4Schristos    Contributed by Red Hat
4a1ba9ba4Schristos 
5a1ba9ba4Schristos This file is part of the GNU simulators.
6a1ba9ba4Schristos 
7a1ba9ba4Schristos This program is free software; you can redistribute it and/or modify
8a1ba9ba4Schristos it under the terms of the GNU General Public License as published by
9a1ba9ba4Schristos the Free Software Foundation; either version 3 of the License, or
10a1ba9ba4Schristos (at your option) any later version.
11a1ba9ba4Schristos 
12a1ba9ba4Schristos This program is distributed in the hope that it will be useful,
13a1ba9ba4Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of
14a1ba9ba4Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15a1ba9ba4Schristos GNU General Public License for more details.
16a1ba9ba4Schristos 
17a1ba9ba4Schristos You should have received a copy of the GNU General Public License
18a1ba9ba4Schristos along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19a1ba9ba4Schristos 
20a1ba9ba4Schristos #define WANT_CPU frvbf
21a1ba9ba4Schristos #define WANT_CPU_FRVBF
22a1ba9ba4Schristos 
23a1ba9ba4Schristos #include "sim-main.h"
24a1ba9ba4Schristos #include "cgen-mem.h"
25a1ba9ba4Schristos #include "bfd.h"
26a1ba9ba4Schristos 
27a1ba9ba4Schristos /* Check for alignment and access restrictions.  Return the corrected address.
28a1ba9ba4Schristos  */
29a1ba9ba4Schristos static SI
fr400_check_data_read_address(SIM_CPU * current_cpu,SI address,int align_mask)30a1ba9ba4Schristos fr400_check_data_read_address (SIM_CPU *current_cpu, SI address, int align_mask)
31a1ba9ba4Schristos {
32a1ba9ba4Schristos   /* Check access restrictions for double word loads only.  */
33a1ba9ba4Schristos   if (align_mask == 7)
34a1ba9ba4Schristos     {
35a1ba9ba4Schristos       if ((USI)address >= 0xfe800000 && (USI)address <= 0xfeffffff)
36a1ba9ba4Schristos 	frv_queue_data_access_error_interrupt (current_cpu, address);
37a1ba9ba4Schristos     }
38a1ba9ba4Schristos   return address;
39a1ba9ba4Schristos }
40a1ba9ba4Schristos 
41a1ba9ba4Schristos static SI
fr500_check_data_read_address(SIM_CPU * current_cpu,SI address,int align_mask)42a1ba9ba4Schristos fr500_check_data_read_address (SIM_CPU *current_cpu, SI address, int align_mask)
43a1ba9ba4Schristos {
44a1ba9ba4Schristos   if (address & align_mask)
45a1ba9ba4Schristos     {
46a1ba9ba4Schristos       frv_queue_mem_address_not_aligned_interrupt (current_cpu, address);
47a1ba9ba4Schristos       address &= ~align_mask;
48a1ba9ba4Schristos     }
49a1ba9ba4Schristos 
50a1ba9ba4Schristos   if ((USI)address >= 0xfeff0600 && (USI)address <= 0xfeff7fff
51a1ba9ba4Schristos       || (USI)address >= 0xfe800000 && (USI)address <= 0xfefeffff)
52a1ba9ba4Schristos     frv_queue_data_access_error_interrupt (current_cpu, address);
53a1ba9ba4Schristos 
54a1ba9ba4Schristos   return address;
55a1ba9ba4Schristos }
56a1ba9ba4Schristos 
57a1ba9ba4Schristos static SI
fr550_check_data_read_address(SIM_CPU * current_cpu,SI address,int align_mask)58a1ba9ba4Schristos fr550_check_data_read_address (SIM_CPU *current_cpu, SI address, int align_mask)
59a1ba9ba4Schristos {
60a1ba9ba4Schristos   if ((USI)address >= 0xfe800000 && (USI)address <= 0xfefeffff
61a1ba9ba4Schristos       || (align_mask > 0x3
62a1ba9ba4Schristos 	  && ((USI)address >= 0xfeff0000 && (USI)address <= 0xfeffffff)))
63a1ba9ba4Schristos     frv_queue_data_access_error_interrupt (current_cpu, address);
64a1ba9ba4Schristos 
65a1ba9ba4Schristos   return address;
66a1ba9ba4Schristos }
67a1ba9ba4Schristos 
68a1ba9ba4Schristos static SI
check_data_read_address(SIM_CPU * current_cpu,SI address,int align_mask)69a1ba9ba4Schristos check_data_read_address (SIM_CPU *current_cpu, SI address, int align_mask)
70a1ba9ba4Schristos {
71a1ba9ba4Schristos   SIM_DESC sd = CPU_STATE (current_cpu);
72a1ba9ba4Schristos   switch (STATE_ARCHITECTURE (sd)->mach)
73a1ba9ba4Schristos     {
74a1ba9ba4Schristos     case bfd_mach_fr400:
75a1ba9ba4Schristos     case bfd_mach_fr450:
76a1ba9ba4Schristos       address = fr400_check_data_read_address (current_cpu, address,
77a1ba9ba4Schristos 					       align_mask);
78a1ba9ba4Schristos       break;
79a1ba9ba4Schristos     case bfd_mach_frvtomcat:
80a1ba9ba4Schristos     case bfd_mach_fr500:
81a1ba9ba4Schristos     case bfd_mach_frv:
82a1ba9ba4Schristos       address = fr500_check_data_read_address (current_cpu, address,
83a1ba9ba4Schristos 					       align_mask);
84a1ba9ba4Schristos       break;
85a1ba9ba4Schristos     case bfd_mach_fr550:
86a1ba9ba4Schristos       address = fr550_check_data_read_address (current_cpu, address,
87a1ba9ba4Schristos 					       align_mask);
88a1ba9ba4Schristos       break;
89a1ba9ba4Schristos     default:
90a1ba9ba4Schristos       break;
91a1ba9ba4Schristos     }
92a1ba9ba4Schristos 
93a1ba9ba4Schristos   return address;
94a1ba9ba4Schristos }
95a1ba9ba4Schristos 
96a1ba9ba4Schristos static SI
fr400_check_readwrite_address(SIM_CPU * current_cpu,SI address,int align_mask)97a1ba9ba4Schristos fr400_check_readwrite_address (SIM_CPU *current_cpu, SI address, int align_mask)
98a1ba9ba4Schristos {
99a1ba9ba4Schristos   if (address & align_mask)
100a1ba9ba4Schristos     {
101a1ba9ba4Schristos       /* Make sure that this exception is not masked.  */
102a1ba9ba4Schristos       USI isr = GET_ISR ();
103a1ba9ba4Schristos       if (! GET_ISR_EMAM (isr))
104a1ba9ba4Schristos 	{
105a1ba9ba4Schristos 	  /* Bad alignment causes a data_access_error on fr400.  */
106a1ba9ba4Schristos 	  frv_queue_data_access_error_interrupt (current_cpu, address);
107a1ba9ba4Schristos 	}
108a1ba9ba4Schristos       address &= ~align_mask;
109a1ba9ba4Schristos     }
110a1ba9ba4Schristos   /* Nothing to check.  */
111a1ba9ba4Schristos   return address;
112a1ba9ba4Schristos }
113a1ba9ba4Schristos 
114a1ba9ba4Schristos static SI
fr500_check_readwrite_address(SIM_CPU * current_cpu,SI address,int align_mask)115a1ba9ba4Schristos fr500_check_readwrite_address (SIM_CPU *current_cpu, SI address, int align_mask)
116a1ba9ba4Schristos {
117a1ba9ba4Schristos   if ((USI)address >= 0xfe000000 && (USI)address <= 0xfe003fff
118a1ba9ba4Schristos       || (USI)address >= 0xfe004000 && (USI)address <= 0xfe3fffff
119a1ba9ba4Schristos       || (USI)address >= 0xfe400000 && (USI)address <= 0xfe403fff
120a1ba9ba4Schristos       || (USI)address >= 0xfe404000 && (USI)address <= 0xfe7fffff)
121a1ba9ba4Schristos     frv_queue_data_access_exception_interrupt (current_cpu);
122a1ba9ba4Schristos 
123a1ba9ba4Schristos   return address;
124a1ba9ba4Schristos }
125a1ba9ba4Schristos 
126a1ba9ba4Schristos static SI
fr550_check_readwrite_address(SIM_CPU * current_cpu,SI address,int align_mask)127a1ba9ba4Schristos fr550_check_readwrite_address (SIM_CPU *current_cpu, SI address, int align_mask)
128a1ba9ba4Schristos {
129a1ba9ba4Schristos   /* No alignment restrictions on fr550 */
130a1ba9ba4Schristos 
131a1ba9ba4Schristos   if ((USI)address >= 0xfe000000 && (USI)address <= 0xfe3fffff
132a1ba9ba4Schristos       || (USI)address >= 0xfe408000 && (USI)address <= 0xfe7fffff)
133a1ba9ba4Schristos     frv_queue_data_access_exception_interrupt (current_cpu);
134a1ba9ba4Schristos   else
135a1ba9ba4Schristos     {
136a1ba9ba4Schristos       USI hsr0 = GET_HSR0 ();
137a1ba9ba4Schristos       if (! GET_HSR0_RME (hsr0)
138a1ba9ba4Schristos 	  && (USI)address >= 0xfe400000 && (USI)address <= 0xfe407fff)
139a1ba9ba4Schristos 	frv_queue_data_access_exception_interrupt (current_cpu);
140a1ba9ba4Schristos     }
141a1ba9ba4Schristos 
142a1ba9ba4Schristos   return address;
143a1ba9ba4Schristos }
144a1ba9ba4Schristos 
145a1ba9ba4Schristos static SI
check_readwrite_address(SIM_CPU * current_cpu,SI address,int align_mask)146a1ba9ba4Schristos check_readwrite_address (SIM_CPU *current_cpu, SI address, int align_mask)
147a1ba9ba4Schristos {
148a1ba9ba4Schristos   SIM_DESC sd = CPU_STATE (current_cpu);
149a1ba9ba4Schristos   switch (STATE_ARCHITECTURE (sd)->mach)
150a1ba9ba4Schristos     {
151a1ba9ba4Schristos     case bfd_mach_fr400:
152a1ba9ba4Schristos     case bfd_mach_fr450:
153a1ba9ba4Schristos       address = fr400_check_readwrite_address (current_cpu, address,
154a1ba9ba4Schristos 						    align_mask);
155a1ba9ba4Schristos       break;
156a1ba9ba4Schristos     case bfd_mach_frvtomcat:
157a1ba9ba4Schristos     case bfd_mach_fr500:
158a1ba9ba4Schristos     case bfd_mach_frv:
159a1ba9ba4Schristos       address = fr500_check_readwrite_address (current_cpu, address,
160a1ba9ba4Schristos 						    align_mask);
161a1ba9ba4Schristos       break;
162a1ba9ba4Schristos     case bfd_mach_fr550:
163a1ba9ba4Schristos       address = fr550_check_readwrite_address (current_cpu, address,
164a1ba9ba4Schristos 					       align_mask);
165a1ba9ba4Schristos       break;
166a1ba9ba4Schristos     default:
167a1ba9ba4Schristos       break;
168a1ba9ba4Schristos     }
169a1ba9ba4Schristos 
170a1ba9ba4Schristos   return address;
171a1ba9ba4Schristos }
172a1ba9ba4Schristos 
173a1ba9ba4Schristos static PCADDR
fr400_check_insn_read_address(SIM_CPU * current_cpu,PCADDR address,int align_mask)174a1ba9ba4Schristos fr400_check_insn_read_address (SIM_CPU *current_cpu, PCADDR address,
175a1ba9ba4Schristos 			       int align_mask)
176a1ba9ba4Schristos {
177a1ba9ba4Schristos   if (address & align_mask)
178a1ba9ba4Schristos     {
179a1ba9ba4Schristos       frv_queue_instruction_access_error_interrupt (current_cpu);
180a1ba9ba4Schristos       address &= ~align_mask;
181a1ba9ba4Schristos     }
182a1ba9ba4Schristos   else if ((USI)address >= 0xfe800000 && (USI)address <= 0xfeffffff)
183a1ba9ba4Schristos     frv_queue_instruction_access_error_interrupt (current_cpu);
184a1ba9ba4Schristos 
185a1ba9ba4Schristos   return address;
186a1ba9ba4Schristos }
187a1ba9ba4Schristos 
188a1ba9ba4Schristos static PCADDR
fr500_check_insn_read_address(SIM_CPU * current_cpu,PCADDR address,int align_mask)189a1ba9ba4Schristos fr500_check_insn_read_address (SIM_CPU *current_cpu, PCADDR address,
190a1ba9ba4Schristos 			       int align_mask)
191a1ba9ba4Schristos {
192a1ba9ba4Schristos   if (address & align_mask)
193a1ba9ba4Schristos     {
194a1ba9ba4Schristos       frv_queue_mem_address_not_aligned_interrupt (current_cpu, address);
195a1ba9ba4Schristos       address &= ~align_mask;
196a1ba9ba4Schristos     }
197a1ba9ba4Schristos 
198a1ba9ba4Schristos   if ((USI)address >= 0xfeff0600 && (USI)address <= 0xfeff7fff
199a1ba9ba4Schristos       || (USI)address >= 0xfe800000 && (USI)address <= 0xfefeffff)
200a1ba9ba4Schristos     frv_queue_instruction_access_error_interrupt (current_cpu);
201a1ba9ba4Schristos   else if ((USI)address >= 0xfe004000 && (USI)address <= 0xfe3fffff
202a1ba9ba4Schristos 	   || (USI)address >= 0xfe400000 && (USI)address <= 0xfe403fff
203a1ba9ba4Schristos 	   || (USI)address >= 0xfe404000 && (USI)address <= 0xfe7fffff)
204a1ba9ba4Schristos     frv_queue_instruction_access_exception_interrupt (current_cpu);
205a1ba9ba4Schristos   else
206a1ba9ba4Schristos     {
207a1ba9ba4Schristos       USI hsr0 = GET_HSR0 ();
208a1ba9ba4Schristos       if (! GET_HSR0_RME (hsr0)
209a1ba9ba4Schristos 	  && (USI)address >= 0xfe000000 && (USI)address <= 0xfe003fff)
210a1ba9ba4Schristos 	frv_queue_instruction_access_exception_interrupt (current_cpu);
211a1ba9ba4Schristos     }
212a1ba9ba4Schristos 
213a1ba9ba4Schristos   return address;
214a1ba9ba4Schristos }
215a1ba9ba4Schristos 
216a1ba9ba4Schristos static PCADDR
fr550_check_insn_read_address(SIM_CPU * current_cpu,PCADDR address,int align_mask)217a1ba9ba4Schristos fr550_check_insn_read_address (SIM_CPU *current_cpu, PCADDR address,
218a1ba9ba4Schristos 			       int align_mask)
219a1ba9ba4Schristos {
220a1ba9ba4Schristos   address &= ~align_mask;
221a1ba9ba4Schristos 
222a1ba9ba4Schristos   if ((USI)address >= 0xfe800000 && (USI)address <= 0xfeffffff)
223a1ba9ba4Schristos     frv_queue_instruction_access_error_interrupt (current_cpu);
224a1ba9ba4Schristos   else if ((USI)address >= 0xfe008000 && (USI)address <= 0xfe7fffff)
225a1ba9ba4Schristos     frv_queue_instruction_access_exception_interrupt (current_cpu);
226a1ba9ba4Schristos   else
227a1ba9ba4Schristos     {
228a1ba9ba4Schristos       USI hsr0 = GET_HSR0 ();
229a1ba9ba4Schristos       if (! GET_HSR0_RME (hsr0)
230a1ba9ba4Schristos 	  && (USI)address >= 0xfe000000 && (USI)address <= 0xfe007fff)
231a1ba9ba4Schristos 	frv_queue_instruction_access_exception_interrupt (current_cpu);
232a1ba9ba4Schristos     }
233a1ba9ba4Schristos 
234a1ba9ba4Schristos   return address;
235a1ba9ba4Schristos }
236a1ba9ba4Schristos 
237a1ba9ba4Schristos static PCADDR
check_insn_read_address(SIM_CPU * current_cpu,PCADDR address,int align_mask)238a1ba9ba4Schristos check_insn_read_address (SIM_CPU *current_cpu, PCADDR address, int align_mask)
239a1ba9ba4Schristos {
240a1ba9ba4Schristos   SIM_DESC sd = CPU_STATE (current_cpu);
241a1ba9ba4Schristos   switch (STATE_ARCHITECTURE (sd)->mach)
242a1ba9ba4Schristos     {
243a1ba9ba4Schristos     case bfd_mach_fr400:
244a1ba9ba4Schristos     case bfd_mach_fr450:
245a1ba9ba4Schristos       address = fr400_check_insn_read_address (current_cpu, address,
246a1ba9ba4Schristos 					       align_mask);
247a1ba9ba4Schristos       break;
248a1ba9ba4Schristos     case bfd_mach_frvtomcat:
249a1ba9ba4Schristos     case bfd_mach_fr500:
250a1ba9ba4Schristos     case bfd_mach_frv:
251a1ba9ba4Schristos       address = fr500_check_insn_read_address (current_cpu, address,
252a1ba9ba4Schristos 					       align_mask);
253a1ba9ba4Schristos       break;
254a1ba9ba4Schristos     case bfd_mach_fr550:
255a1ba9ba4Schristos       address = fr550_check_insn_read_address (current_cpu, address,
256a1ba9ba4Schristos 					       align_mask);
257a1ba9ba4Schristos       break;
258a1ba9ba4Schristos     default:
259a1ba9ba4Schristos       break;
260a1ba9ba4Schristos     }
261a1ba9ba4Schristos 
262a1ba9ba4Schristos   return address;
263a1ba9ba4Schristos }
264a1ba9ba4Schristos 
265a1ba9ba4Schristos /* Memory reads.  */
266a1ba9ba4Schristos QI
frvbf_read_mem_QI(SIM_CPU * current_cpu,IADDR pc,SI address)267a1ba9ba4Schristos frvbf_read_mem_QI (SIM_CPU *current_cpu, IADDR pc, SI address)
268a1ba9ba4Schristos {
269a1ba9ba4Schristos   USI hsr0 = GET_HSR0 ();
270a1ba9ba4Schristos   FRV_CACHE *cache = CPU_DATA_CACHE (current_cpu);
271a1ba9ba4Schristos 
272a1ba9ba4Schristos   /* Check for access exceptions.  */
273a1ba9ba4Schristos   address = check_data_read_address (current_cpu, address, 0);
274a1ba9ba4Schristos   address = check_readwrite_address (current_cpu, address, 0);
275a1ba9ba4Schristos 
276a1ba9ba4Schristos   /* If we need to count cycles, then the cache operation will be
277a1ba9ba4Schristos      initiated from the model profiling functions.
278a1ba9ba4Schristos      See frvbf_model_....  */
279a1ba9ba4Schristos   if (model_insn)
280a1ba9ba4Schristos     {
281a1ba9ba4Schristos       CPU_LOAD_ADDRESS (current_cpu) = address;
282a1ba9ba4Schristos       CPU_LOAD_LENGTH (current_cpu) = 1;
283a1ba9ba4Schristos       CPU_LOAD_SIGNED (current_cpu) = 1;
284a1ba9ba4Schristos       return 0xb7; /* any random value */
285a1ba9ba4Schristos     }
286a1ba9ba4Schristos 
287a1ba9ba4Schristos   if (GET_HSR0_DCE (hsr0))
288a1ba9ba4Schristos     {
289a1ba9ba4Schristos       int cycles;
290a1ba9ba4Schristos       cycles = frv_cache_read (cache, 0, address);
291a1ba9ba4Schristos       if (cycles != 0)
292a1ba9ba4Schristos 	return CACHE_RETURN_DATA (cache, 0, address, QI, 1);
293a1ba9ba4Schristos     }
294a1ba9ba4Schristos 
295a1ba9ba4Schristos   return GETMEMQI (current_cpu, pc, address);
296a1ba9ba4Schristos }
297a1ba9ba4Schristos 
298a1ba9ba4Schristos UQI
frvbf_read_mem_UQI(SIM_CPU * current_cpu,IADDR pc,SI address)299a1ba9ba4Schristos frvbf_read_mem_UQI (SIM_CPU *current_cpu, IADDR pc, SI address)
300a1ba9ba4Schristos {
301a1ba9ba4Schristos   USI hsr0 = GET_HSR0 ();
302a1ba9ba4Schristos   FRV_CACHE *cache = CPU_DATA_CACHE (current_cpu);
303a1ba9ba4Schristos 
304a1ba9ba4Schristos   /* Check for access exceptions.  */
305a1ba9ba4Schristos   address = check_data_read_address (current_cpu, address, 0);
306a1ba9ba4Schristos   address = check_readwrite_address (current_cpu, address, 0);
307a1ba9ba4Schristos 
308a1ba9ba4Schristos   /* If we need to count cycles, then the cache operation will be
309a1ba9ba4Schristos      initiated from the model profiling functions.
310a1ba9ba4Schristos      See frvbf_model_....  */
311a1ba9ba4Schristos   if (model_insn)
312a1ba9ba4Schristos     {
313a1ba9ba4Schristos       CPU_LOAD_ADDRESS (current_cpu) = address;
314a1ba9ba4Schristos       CPU_LOAD_LENGTH (current_cpu) = 1;
315a1ba9ba4Schristos       CPU_LOAD_SIGNED (current_cpu) = 0;
316a1ba9ba4Schristos       return 0xb7; /* any random value */
317a1ba9ba4Schristos     }
318a1ba9ba4Schristos 
319a1ba9ba4Schristos   if (GET_HSR0_DCE (hsr0))
320a1ba9ba4Schristos     {
321a1ba9ba4Schristos       int cycles;
322a1ba9ba4Schristos       cycles = frv_cache_read (cache, 0, address);
323a1ba9ba4Schristos       if (cycles != 0)
324a1ba9ba4Schristos 	return CACHE_RETURN_DATA (cache, 0, address, UQI, 1);
325a1ba9ba4Schristos     }
326a1ba9ba4Schristos 
327a1ba9ba4Schristos   return GETMEMUQI (current_cpu, pc, address);
328a1ba9ba4Schristos }
329a1ba9ba4Schristos 
330a1ba9ba4Schristos /* Read a HI which spans two cache lines */
331a1ba9ba4Schristos static HI
read_mem_unaligned_HI(SIM_CPU * current_cpu,IADDR pc,SI address)332a1ba9ba4Schristos read_mem_unaligned_HI (SIM_CPU *current_cpu, IADDR pc, SI address)
333a1ba9ba4Schristos {
334a1ba9ba4Schristos   HI value = frvbf_read_mem_QI (current_cpu, pc, address);
335a1ba9ba4Schristos   value <<= 8;
336a1ba9ba4Schristos   value |= frvbf_read_mem_UQI (current_cpu, pc, address + 1);
337a1ba9ba4Schristos   return T2H_2 (value);
338a1ba9ba4Schristos }
339a1ba9ba4Schristos 
340a1ba9ba4Schristos HI
frvbf_read_mem_HI(SIM_CPU * current_cpu,IADDR pc,SI address)341a1ba9ba4Schristos frvbf_read_mem_HI (SIM_CPU *current_cpu, IADDR pc, SI address)
342a1ba9ba4Schristos {
343a1ba9ba4Schristos   USI hsr0;
344a1ba9ba4Schristos   FRV_CACHE *cache;
345a1ba9ba4Schristos 
346a1ba9ba4Schristos   /* Check for access exceptions.  */
347a1ba9ba4Schristos   address = check_data_read_address (current_cpu, address, 1);
348a1ba9ba4Schristos   address = check_readwrite_address (current_cpu, address, 1);
349a1ba9ba4Schristos 
350a1ba9ba4Schristos   /* If we need to count cycles, then the cache operation will be
351a1ba9ba4Schristos      initiated from the model profiling functions.
352a1ba9ba4Schristos      See frvbf_model_....  */
353a1ba9ba4Schristos   hsr0 = GET_HSR0 ();
354a1ba9ba4Schristos   cache = CPU_DATA_CACHE (current_cpu);
355a1ba9ba4Schristos   if (model_insn)
356a1ba9ba4Schristos     {
357a1ba9ba4Schristos       CPU_LOAD_ADDRESS (current_cpu) = address;
358a1ba9ba4Schristos       CPU_LOAD_LENGTH (current_cpu) = 2;
359a1ba9ba4Schristos       CPU_LOAD_SIGNED (current_cpu) = 1;
360a1ba9ba4Schristos       return 0xb711; /* any random value */
361a1ba9ba4Schristos     }
362a1ba9ba4Schristos 
363a1ba9ba4Schristos   if (GET_HSR0_DCE (hsr0))
364a1ba9ba4Schristos     {
365a1ba9ba4Schristos       int cycles;
366a1ba9ba4Schristos       /* Handle access which crosses cache line boundary */
367a1ba9ba4Schristos       SIM_DESC sd = CPU_STATE (current_cpu);
368a1ba9ba4Schristos       if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr550)
369a1ba9ba4Schristos 	{
370a1ba9ba4Schristos 	  if (DATA_CROSSES_CACHE_LINE (cache, address, 2))
371a1ba9ba4Schristos 	    return read_mem_unaligned_HI (current_cpu, pc, address);
372a1ba9ba4Schristos 	}
373a1ba9ba4Schristos       cycles = frv_cache_read (cache, 0, address);
374a1ba9ba4Schristos       if (cycles != 0)
375a1ba9ba4Schristos 	return CACHE_RETURN_DATA (cache, 0, address, HI, 2);
376a1ba9ba4Schristos     }
377a1ba9ba4Schristos 
378a1ba9ba4Schristos   return GETMEMHI (current_cpu, pc, address);
379a1ba9ba4Schristos }
380a1ba9ba4Schristos 
381a1ba9ba4Schristos UHI
frvbf_read_mem_UHI(SIM_CPU * current_cpu,IADDR pc,SI address)382a1ba9ba4Schristos frvbf_read_mem_UHI (SIM_CPU *current_cpu, IADDR pc, SI address)
383a1ba9ba4Schristos {
384a1ba9ba4Schristos   USI hsr0;
385a1ba9ba4Schristos   FRV_CACHE *cache;
386a1ba9ba4Schristos 
387a1ba9ba4Schristos   /* Check for access exceptions.  */
388a1ba9ba4Schristos   address = check_data_read_address (current_cpu, address, 1);
389a1ba9ba4Schristos   address = check_readwrite_address (current_cpu, address, 1);
390a1ba9ba4Schristos 
391a1ba9ba4Schristos   /* If we need to count cycles, then the cache operation will be
392a1ba9ba4Schristos      initiated from the model profiling functions.
393a1ba9ba4Schristos      See frvbf_model_....  */
394a1ba9ba4Schristos   hsr0 = GET_HSR0 ();
395a1ba9ba4Schristos   cache = CPU_DATA_CACHE (current_cpu);
396a1ba9ba4Schristos   if (model_insn)
397a1ba9ba4Schristos     {
398a1ba9ba4Schristos       CPU_LOAD_ADDRESS (current_cpu) = address;
399a1ba9ba4Schristos       CPU_LOAD_LENGTH (current_cpu) = 2;
400a1ba9ba4Schristos       CPU_LOAD_SIGNED (current_cpu) = 0;
401a1ba9ba4Schristos       return 0xb711; /* any random value */
402a1ba9ba4Schristos     }
403a1ba9ba4Schristos 
404a1ba9ba4Schristos   if (GET_HSR0_DCE (hsr0))
405a1ba9ba4Schristos     {
406a1ba9ba4Schristos       int cycles;
407a1ba9ba4Schristos       /* Handle access which crosses cache line boundary */
408a1ba9ba4Schristos       SIM_DESC sd = CPU_STATE (current_cpu);
409a1ba9ba4Schristos       if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr550)
410a1ba9ba4Schristos 	{
411a1ba9ba4Schristos 	  if (DATA_CROSSES_CACHE_LINE (cache, address, 2))
412a1ba9ba4Schristos 	    return read_mem_unaligned_HI (current_cpu, pc, address);
413a1ba9ba4Schristos 	}
414a1ba9ba4Schristos       cycles = frv_cache_read (cache, 0, address);
415a1ba9ba4Schristos       if (cycles != 0)
416a1ba9ba4Schristos 	return CACHE_RETURN_DATA (cache, 0, address, UHI, 2);
417a1ba9ba4Schristos     }
418a1ba9ba4Schristos 
419a1ba9ba4Schristos   return GETMEMUHI (current_cpu, pc, address);
420a1ba9ba4Schristos }
421a1ba9ba4Schristos 
422a1ba9ba4Schristos /* Read a SI which spans two cache lines */
423a1ba9ba4Schristos static SI
read_mem_unaligned_SI(SIM_CPU * current_cpu,IADDR pc,SI address)424a1ba9ba4Schristos read_mem_unaligned_SI (SIM_CPU *current_cpu, IADDR pc, SI address)
425a1ba9ba4Schristos {
426a1ba9ba4Schristos   FRV_CACHE *cache = CPU_DATA_CACHE (current_cpu);
427a1ba9ba4Schristos   unsigned hi_len = cache->line_size - (address & (cache->line_size - 1));
428a1ba9ba4Schristos   char valarray[4];
429a1ba9ba4Schristos   SI SIvalue;
430a1ba9ba4Schristos   HI HIvalue;
431a1ba9ba4Schristos 
432a1ba9ba4Schristos   switch (hi_len)
433a1ba9ba4Schristos     {
434a1ba9ba4Schristos     case 1:
435a1ba9ba4Schristos       valarray[0] = frvbf_read_mem_QI (current_cpu, pc, address);
436a1ba9ba4Schristos       SIvalue = frvbf_read_mem_SI (current_cpu, pc, address + 1);
437a1ba9ba4Schristos       SIvalue = H2T_4 (SIvalue);
438a1ba9ba4Schristos       memcpy (valarray + 1, (char*)&SIvalue, 3);
439a1ba9ba4Schristos       break;
440a1ba9ba4Schristos     case 2:
441a1ba9ba4Schristos       HIvalue = frvbf_read_mem_HI (current_cpu, pc, address);
442a1ba9ba4Schristos       HIvalue = H2T_2 (HIvalue);
443a1ba9ba4Schristos       memcpy (valarray, (char*)&HIvalue, 2);
444a1ba9ba4Schristos       HIvalue = frvbf_read_mem_HI (current_cpu, pc, address + 2);
445a1ba9ba4Schristos       HIvalue = H2T_2 (HIvalue);
446a1ba9ba4Schristos       memcpy (valarray + 2, (char*)&HIvalue, 2);
447a1ba9ba4Schristos       break;
448a1ba9ba4Schristos     case 3:
449a1ba9ba4Schristos       SIvalue = frvbf_read_mem_SI (current_cpu, pc, address - 1);
450a1ba9ba4Schristos       SIvalue = H2T_4 (SIvalue);
451a1ba9ba4Schristos       memcpy (valarray, (char*)&SIvalue, 3);
452a1ba9ba4Schristos       valarray[3] = frvbf_read_mem_QI (current_cpu, pc, address + 3);
453a1ba9ba4Schristos       break;
454a1ba9ba4Schristos     default:
455a1ba9ba4Schristos       abort (); /* can't happen */
456a1ba9ba4Schristos     }
457a1ba9ba4Schristos   return T2H_4 (*(SI*)valarray);
458a1ba9ba4Schristos }
459a1ba9ba4Schristos 
460a1ba9ba4Schristos SI
frvbf_read_mem_SI(SIM_CPU * current_cpu,IADDR pc,SI address)461a1ba9ba4Schristos frvbf_read_mem_SI (SIM_CPU *current_cpu, IADDR pc, SI address)
462a1ba9ba4Schristos {
463a1ba9ba4Schristos   FRV_CACHE *cache;
464a1ba9ba4Schristos   USI hsr0;
465a1ba9ba4Schristos 
466a1ba9ba4Schristos   /* Check for access exceptions.  */
467a1ba9ba4Schristos   address = check_data_read_address (current_cpu, address, 3);
468a1ba9ba4Schristos   address = check_readwrite_address (current_cpu, address, 3);
469a1ba9ba4Schristos 
470a1ba9ba4Schristos   hsr0 = GET_HSR0 ();
471a1ba9ba4Schristos   cache = CPU_DATA_CACHE (current_cpu);
472a1ba9ba4Schristos   /* If we need to count cycles, then the cache operation will be
473a1ba9ba4Schristos      initiated from the model profiling functions.
474a1ba9ba4Schristos      See frvbf_model_....  */
475a1ba9ba4Schristos   if (model_insn)
476a1ba9ba4Schristos     {
477a1ba9ba4Schristos       CPU_LOAD_ADDRESS (current_cpu) = address;
478a1ba9ba4Schristos       CPU_LOAD_LENGTH (current_cpu) = 4;
479a1ba9ba4Schristos       return 0x37111319; /* any random value */
480a1ba9ba4Schristos     }
481a1ba9ba4Schristos 
482a1ba9ba4Schristos   if (GET_HSR0_DCE (hsr0))
483a1ba9ba4Schristos     {
484a1ba9ba4Schristos       int cycles;
485a1ba9ba4Schristos       /* Handle access which crosses cache line boundary */
486a1ba9ba4Schristos       SIM_DESC sd = CPU_STATE (current_cpu);
487a1ba9ba4Schristos       if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr550)
488a1ba9ba4Schristos 	{
489a1ba9ba4Schristos 	  if (DATA_CROSSES_CACHE_LINE (cache, address, 4))
490a1ba9ba4Schristos 	    return read_mem_unaligned_SI (current_cpu, pc, address);
491a1ba9ba4Schristos 	}
492a1ba9ba4Schristos       cycles = frv_cache_read (cache, 0, address);
493a1ba9ba4Schristos       if (cycles != 0)
494a1ba9ba4Schristos 	return CACHE_RETURN_DATA (cache, 0, address, SI, 4);
495a1ba9ba4Schristos     }
496a1ba9ba4Schristos 
497a1ba9ba4Schristos   return GETMEMSI (current_cpu, pc, address);
498a1ba9ba4Schristos }
499a1ba9ba4Schristos 
500a1ba9ba4Schristos SI
frvbf_read_mem_WI(SIM_CPU * current_cpu,IADDR pc,SI address)501a1ba9ba4Schristos frvbf_read_mem_WI (SIM_CPU *current_cpu, IADDR pc, SI address)
502a1ba9ba4Schristos {
503a1ba9ba4Schristos   return frvbf_read_mem_SI (current_cpu, pc, address);
504a1ba9ba4Schristos }
505a1ba9ba4Schristos 
506a1ba9ba4Schristos /* Read a SI which spans two cache lines */
507a1ba9ba4Schristos static DI
read_mem_unaligned_DI(SIM_CPU * current_cpu,IADDR pc,SI address)508a1ba9ba4Schristos read_mem_unaligned_DI (SIM_CPU *current_cpu, IADDR pc, SI address)
509a1ba9ba4Schristos {
510a1ba9ba4Schristos   FRV_CACHE *cache = CPU_DATA_CACHE (current_cpu);
511a1ba9ba4Schristos   unsigned hi_len = cache->line_size - (address & (cache->line_size - 1));
512a1ba9ba4Schristos   DI value, value1;
513a1ba9ba4Schristos 
514a1ba9ba4Schristos   switch (hi_len)
515a1ba9ba4Schristos     {
516a1ba9ba4Schristos     case 1:
517a1ba9ba4Schristos       value = frvbf_read_mem_QI (current_cpu, pc, address);
518a1ba9ba4Schristos       value <<= 56;
519a1ba9ba4Schristos       value1 = frvbf_read_mem_DI (current_cpu, pc, address + 1);
520a1ba9ba4Schristos       value1 = H2T_8 (value1);
521a1ba9ba4Schristos       value |= value1 & ((DI)0x00ffffff << 32);
522a1ba9ba4Schristos       value |= value1 & 0xffffffffu;
523a1ba9ba4Schristos       break;
524a1ba9ba4Schristos     case 2:
525a1ba9ba4Schristos       value = frvbf_read_mem_HI (current_cpu, pc, address);
526a1ba9ba4Schristos       value = H2T_2 (value);
527a1ba9ba4Schristos       value <<= 48;
528a1ba9ba4Schristos       value1 = frvbf_read_mem_DI (current_cpu, pc, address + 2);
529a1ba9ba4Schristos       value1 = H2T_8 (value1);
530a1ba9ba4Schristos       value |= value1 & ((DI)0x0000ffff << 32);
531a1ba9ba4Schristos       value |= value1 & 0xffffffffu;
532a1ba9ba4Schristos       break;
533a1ba9ba4Schristos     case 3:
534a1ba9ba4Schristos       value = frvbf_read_mem_SI (current_cpu, pc, address - 1);
535a1ba9ba4Schristos       value = H2T_4 (value);
536a1ba9ba4Schristos       value <<= 40;
537a1ba9ba4Schristos       value1 = frvbf_read_mem_DI (current_cpu, pc, address + 3);
538a1ba9ba4Schristos       value1 = H2T_8 (value1);
539a1ba9ba4Schristos       value |= value1 & ((DI)0x000000ff << 32);
540a1ba9ba4Schristos       value |= value1 & 0xffffffffu;
541a1ba9ba4Schristos       break;
542a1ba9ba4Schristos     case 4:
543a1ba9ba4Schristos       value = frvbf_read_mem_SI (current_cpu, pc, address);
544a1ba9ba4Schristos       value = H2T_4 (value);
545a1ba9ba4Schristos       value <<= 32;
546a1ba9ba4Schristos       value1 = frvbf_read_mem_SI (current_cpu, pc, address + 4);
547a1ba9ba4Schristos       value1 = H2T_4 (value1);
548a1ba9ba4Schristos       value |= value1 & 0xffffffffu;
549a1ba9ba4Schristos       break;
550a1ba9ba4Schristos     case 5:
551a1ba9ba4Schristos       value = frvbf_read_mem_DI (current_cpu, pc, address - 3);
552a1ba9ba4Schristos       value = H2T_8 (value);
553a1ba9ba4Schristos       value <<= 24;
554a1ba9ba4Schristos       value1 = frvbf_read_mem_SI (current_cpu, pc, address + 5);
555a1ba9ba4Schristos       value1 = H2T_4 (value1);
556a1ba9ba4Schristos       value |= value1 & 0x00ffffff;
557a1ba9ba4Schristos       break;
558a1ba9ba4Schristos     case 6:
559a1ba9ba4Schristos       value = frvbf_read_mem_DI (current_cpu, pc, address - 2);
560a1ba9ba4Schristos       value = H2T_8 (value);
561a1ba9ba4Schristos       value <<= 16;
562a1ba9ba4Schristos       value1 = frvbf_read_mem_HI (current_cpu, pc, address + 6);
563a1ba9ba4Schristos       value1 = H2T_2 (value1);
564a1ba9ba4Schristos       value |= value1 & 0x0000ffff;
565a1ba9ba4Schristos       break;
566a1ba9ba4Schristos     case 7:
567a1ba9ba4Schristos       value = frvbf_read_mem_DI (current_cpu, pc, address - 1);
568a1ba9ba4Schristos       value = H2T_8 (value);
569a1ba9ba4Schristos       value <<= 8;
570a1ba9ba4Schristos       value1 = frvbf_read_mem_QI (current_cpu, pc, address + 7);
571a1ba9ba4Schristos       value |= value1 & 0x000000ff;
572a1ba9ba4Schristos       break;
573a1ba9ba4Schristos     default:
574a1ba9ba4Schristos       abort (); /* can't happen */
575a1ba9ba4Schristos     }
576a1ba9ba4Schristos   return T2H_8 (value);
577a1ba9ba4Schristos }
578a1ba9ba4Schristos 
579a1ba9ba4Schristos DI
frvbf_read_mem_DI(SIM_CPU * current_cpu,IADDR pc,SI address)580a1ba9ba4Schristos frvbf_read_mem_DI (SIM_CPU *current_cpu, IADDR pc, SI address)
581a1ba9ba4Schristos {
582a1ba9ba4Schristos   USI hsr0;
583a1ba9ba4Schristos   FRV_CACHE *cache;
584a1ba9ba4Schristos 
585a1ba9ba4Schristos   /* Check for access exceptions.  */
586a1ba9ba4Schristos   address = check_data_read_address (current_cpu, address, 7);
587a1ba9ba4Schristos   address = check_readwrite_address (current_cpu, address, 7);
588a1ba9ba4Schristos 
589a1ba9ba4Schristos   /* If we need to count cycles, then the cache operation will be
590a1ba9ba4Schristos      initiated from the model profiling functions.
591a1ba9ba4Schristos      See frvbf_model_....  */
592a1ba9ba4Schristos   hsr0 = GET_HSR0 ();
593a1ba9ba4Schristos   cache = CPU_DATA_CACHE (current_cpu);
594a1ba9ba4Schristos   if (model_insn)
595a1ba9ba4Schristos     {
596a1ba9ba4Schristos       CPU_LOAD_ADDRESS (current_cpu) = address;
597a1ba9ba4Schristos       CPU_LOAD_LENGTH (current_cpu) = 8;
598a1ba9ba4Schristos       return 0x37111319; /* any random value */
599a1ba9ba4Schristos     }
600a1ba9ba4Schristos 
601a1ba9ba4Schristos   if (GET_HSR0_DCE (hsr0))
602a1ba9ba4Schristos     {
603a1ba9ba4Schristos       int cycles;
604a1ba9ba4Schristos       /* Handle access which crosses cache line boundary */
605a1ba9ba4Schristos       SIM_DESC sd = CPU_STATE (current_cpu);
606a1ba9ba4Schristos       if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr550)
607a1ba9ba4Schristos 	{
608a1ba9ba4Schristos 	  if (DATA_CROSSES_CACHE_LINE (cache, address, 8))
609a1ba9ba4Schristos 	    return read_mem_unaligned_DI (current_cpu, pc, address);
610a1ba9ba4Schristos 	}
611a1ba9ba4Schristos       cycles = frv_cache_read (cache, 0, address);
612a1ba9ba4Schristos       if (cycles != 0)
613a1ba9ba4Schristos 	return CACHE_RETURN_DATA (cache, 0, address, DI, 8);
614a1ba9ba4Schristos     }
615a1ba9ba4Schristos 
616a1ba9ba4Schristos   return GETMEMDI (current_cpu, pc, address);
617a1ba9ba4Schristos }
618a1ba9ba4Schristos 
619a1ba9ba4Schristos DF
frvbf_read_mem_DF(SIM_CPU * current_cpu,IADDR pc,SI address)620a1ba9ba4Schristos frvbf_read_mem_DF (SIM_CPU *current_cpu, IADDR pc, SI address)
621a1ba9ba4Schristos {
622a1ba9ba4Schristos   USI hsr0;
623a1ba9ba4Schristos   FRV_CACHE *cache;
624a1ba9ba4Schristos 
625a1ba9ba4Schristos   /* Check for access exceptions.  */
626a1ba9ba4Schristos   address = check_data_read_address (current_cpu, address, 7);
627a1ba9ba4Schristos   address = check_readwrite_address (current_cpu, address, 7);
628a1ba9ba4Schristos 
629a1ba9ba4Schristos   /* If we need to count cycles, then the cache operation will be
630a1ba9ba4Schristos      initiated from the model profiling functions.
631a1ba9ba4Schristos      See frvbf_model_....  */
632a1ba9ba4Schristos   hsr0 = GET_HSR0 ();
633a1ba9ba4Schristos   cache = CPU_DATA_CACHE (current_cpu);
634a1ba9ba4Schristos   if (model_insn)
635a1ba9ba4Schristos     {
636a1ba9ba4Schristos       CPU_LOAD_ADDRESS (current_cpu) = address;
637a1ba9ba4Schristos       CPU_LOAD_LENGTH (current_cpu) = 8;
638a1ba9ba4Schristos       return 0x37111319; /* any random value */
639a1ba9ba4Schristos     }
640a1ba9ba4Schristos 
641a1ba9ba4Schristos   if (GET_HSR0_DCE (hsr0))
642a1ba9ba4Schristos     {
643a1ba9ba4Schristos       int cycles;
644a1ba9ba4Schristos       /* Handle access which crosses cache line boundary */
645a1ba9ba4Schristos       SIM_DESC sd = CPU_STATE (current_cpu);
646a1ba9ba4Schristos       if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr550)
647a1ba9ba4Schristos 	{
648a1ba9ba4Schristos 	  if (DATA_CROSSES_CACHE_LINE (cache, address, 8))
649a1ba9ba4Schristos 	    return read_mem_unaligned_DI (current_cpu, pc, address);
650a1ba9ba4Schristos 	}
651a1ba9ba4Schristos       cycles = frv_cache_read (cache, 0, address);
652a1ba9ba4Schristos       if (cycles != 0)
653a1ba9ba4Schristos 	return CACHE_RETURN_DATA (cache, 0, address, DF, 8);
654a1ba9ba4Schristos     }
655a1ba9ba4Schristos 
656a1ba9ba4Schristos   return GETMEMDF (current_cpu, pc, address);
657a1ba9ba4Schristos }
658a1ba9ba4Schristos 
659a1ba9ba4Schristos USI
frvbf_read_imem_USI(SIM_CPU * current_cpu,PCADDR vpc)660a1ba9ba4Schristos frvbf_read_imem_USI (SIM_CPU *current_cpu, PCADDR vpc)
661a1ba9ba4Schristos {
662a1ba9ba4Schristos   USI hsr0;
663a1ba9ba4Schristos   vpc = check_insn_read_address (current_cpu, vpc, 3);
664a1ba9ba4Schristos 
665a1ba9ba4Schristos   hsr0 = GET_HSR0 ();
666a1ba9ba4Schristos   if (GET_HSR0_ICE (hsr0))
667a1ba9ba4Schristos     {
668a1ba9ba4Schristos       FRV_CACHE *cache;
669a1ba9ba4Schristos       USI value;
670a1ba9ba4Schristos 
671a1ba9ba4Schristos       /* We don't want this to show up in the cache statistics.  That read
672a1ba9ba4Schristos 	 is done in frvbf_simulate_insn_prefetch.  So read the cache or memory
673a1ba9ba4Schristos 	 passively here.  */
674a1ba9ba4Schristos       cache = CPU_INSN_CACHE (current_cpu);
675a1ba9ba4Schristos       if (frv_cache_read_passive_SI (cache, vpc, &value))
676a1ba9ba4Schristos 	return value;
677a1ba9ba4Schristos     }
678a1ba9ba4Schristos   return sim_core_read_unaligned_4 (current_cpu, vpc, read_map, vpc);
679a1ba9ba4Schristos }
680a1ba9ba4Schristos 
681a1ba9ba4Schristos static SI
fr400_check_write_address(SIM_CPU * current_cpu,SI address,int align_mask)682a1ba9ba4Schristos fr400_check_write_address (SIM_CPU *current_cpu, SI address, int align_mask)
683a1ba9ba4Schristos {
684a1ba9ba4Schristos   if (align_mask == 7
685a1ba9ba4Schristos       && address >= 0xfe800000 && address <= 0xfeffffff)
686a1ba9ba4Schristos     frv_queue_program_interrupt (current_cpu, FRV_DATA_STORE_ERROR);
687a1ba9ba4Schristos 
688a1ba9ba4Schristos   return address;
689a1ba9ba4Schristos }
690a1ba9ba4Schristos 
691a1ba9ba4Schristos static SI
fr500_check_write_address(SIM_CPU * current_cpu,SI address,int align_mask)692a1ba9ba4Schristos fr500_check_write_address (SIM_CPU *current_cpu, SI address, int align_mask)
693a1ba9ba4Schristos {
694a1ba9ba4Schristos   if (address & align_mask)
695a1ba9ba4Schristos     {
696a1ba9ba4Schristos       struct frv_interrupt_queue_element *item =
697a1ba9ba4Schristos 	frv_queue_mem_address_not_aligned_interrupt (current_cpu, address);
698a1ba9ba4Schristos       /* Record the correct vliw slot with the interrupt.  */
699a1ba9ba4Schristos       if (item != NULL)
700a1ba9ba4Schristos 	item->slot = frv_interrupt_state.slot;
701a1ba9ba4Schristos       address &= ~align_mask;
702a1ba9ba4Schristos     }
703a1ba9ba4Schristos   if (address >= 0xfeff0600 && address <= 0xfeff7fff
704a1ba9ba4Schristos       || address >= 0xfe800000 && address <= 0xfefeffff)
705a1ba9ba4Schristos     frv_queue_program_interrupt (current_cpu, FRV_DATA_STORE_ERROR);
706a1ba9ba4Schristos 
707a1ba9ba4Schristos   return address;
708a1ba9ba4Schristos }
709a1ba9ba4Schristos 
710a1ba9ba4Schristos static SI
fr550_check_write_address(SIM_CPU * current_cpu,SI address,int align_mask)711a1ba9ba4Schristos fr550_check_write_address (SIM_CPU *current_cpu, SI address, int align_mask)
712a1ba9ba4Schristos {
713a1ba9ba4Schristos   if ((USI)address >= 0xfe800000 && (USI)address <= 0xfefeffff
714a1ba9ba4Schristos       || (align_mask > 0x3
715a1ba9ba4Schristos 	  && ((USI)address >= 0xfeff0000 && (USI)address <= 0xfeffffff)))
716a1ba9ba4Schristos     frv_queue_program_interrupt (current_cpu, FRV_DATA_STORE_ERROR);
717a1ba9ba4Schristos 
718a1ba9ba4Schristos   return address;
719a1ba9ba4Schristos }
720a1ba9ba4Schristos 
721a1ba9ba4Schristos static SI
check_write_address(SIM_CPU * current_cpu,SI address,int align_mask)722a1ba9ba4Schristos check_write_address (SIM_CPU *current_cpu, SI address, int align_mask)
723a1ba9ba4Schristos {
724a1ba9ba4Schristos   SIM_DESC sd = CPU_STATE (current_cpu);
725a1ba9ba4Schristos   switch (STATE_ARCHITECTURE (sd)->mach)
726a1ba9ba4Schristos     {
727a1ba9ba4Schristos     case bfd_mach_fr400:
728a1ba9ba4Schristos     case bfd_mach_fr450:
729a1ba9ba4Schristos       address = fr400_check_write_address (current_cpu, address, align_mask);
730a1ba9ba4Schristos       break;
731a1ba9ba4Schristos     case bfd_mach_frvtomcat:
732a1ba9ba4Schristos     case bfd_mach_fr500:
733a1ba9ba4Schristos     case bfd_mach_frv:
734a1ba9ba4Schristos       address = fr500_check_write_address (current_cpu, address, align_mask);
735a1ba9ba4Schristos       break;
736a1ba9ba4Schristos     case bfd_mach_fr550:
737a1ba9ba4Schristos       address = fr550_check_write_address (current_cpu, address, align_mask);
738a1ba9ba4Schristos       break;
739a1ba9ba4Schristos     default:
740a1ba9ba4Schristos       break;
741a1ba9ba4Schristos     }
742a1ba9ba4Schristos   return address;
743a1ba9ba4Schristos }
744a1ba9ba4Schristos 
745a1ba9ba4Schristos void
frvbf_write_mem_QI(SIM_CPU * current_cpu,IADDR pc,SI address,QI value)746a1ba9ba4Schristos frvbf_write_mem_QI (SIM_CPU *current_cpu, IADDR pc, SI address, QI value)
747a1ba9ba4Schristos {
748a1ba9ba4Schristos   USI hsr0;
749a1ba9ba4Schristos   hsr0 = GET_HSR0 ();
750a1ba9ba4Schristos   if (GET_HSR0_DCE (hsr0))
751a1ba9ba4Schristos     sim_queue_fn_mem_qi_write (current_cpu, frvbf_mem_set_QI, address, value);
752a1ba9ba4Schristos   else
753a1ba9ba4Schristos     sim_queue_mem_qi_write (current_cpu, address, value);
754a1ba9ba4Schristos   frv_set_write_queue_slot (current_cpu);
755a1ba9ba4Schristos }
756a1ba9ba4Schristos 
757a1ba9ba4Schristos void
frvbf_write_mem_UQI(SIM_CPU * current_cpu,IADDR pc,SI address,UQI value)758a1ba9ba4Schristos frvbf_write_mem_UQI (SIM_CPU *current_cpu, IADDR pc, SI address, UQI value)
759a1ba9ba4Schristos {
760a1ba9ba4Schristos   frvbf_write_mem_QI (current_cpu, pc, address, value);
761a1ba9ba4Schristos }
762a1ba9ba4Schristos 
763a1ba9ba4Schristos void
frvbf_write_mem_HI(SIM_CPU * current_cpu,IADDR pc,SI address,HI value)764a1ba9ba4Schristos frvbf_write_mem_HI (SIM_CPU *current_cpu, IADDR pc, SI address, HI value)
765a1ba9ba4Schristos {
766a1ba9ba4Schristos   USI hsr0;
767a1ba9ba4Schristos   hsr0 = GET_HSR0 ();
768a1ba9ba4Schristos   if (GET_HSR0_DCE (hsr0))
769a1ba9ba4Schristos     sim_queue_fn_mem_hi_write (current_cpu, frvbf_mem_set_HI, address, value);
770a1ba9ba4Schristos   else
771a1ba9ba4Schristos     sim_queue_mem_hi_write (current_cpu, address, value);
772a1ba9ba4Schristos   frv_set_write_queue_slot (current_cpu);
773a1ba9ba4Schristos }
774a1ba9ba4Schristos 
775a1ba9ba4Schristos void
frvbf_write_mem_UHI(SIM_CPU * current_cpu,IADDR pc,SI address,UHI value)776a1ba9ba4Schristos frvbf_write_mem_UHI (SIM_CPU *current_cpu, IADDR pc, SI address, UHI value)
777a1ba9ba4Schristos {
778a1ba9ba4Schristos   frvbf_write_mem_HI (current_cpu, pc, address, value);
779a1ba9ba4Schristos }
780a1ba9ba4Schristos 
781a1ba9ba4Schristos void
frvbf_write_mem_SI(SIM_CPU * current_cpu,IADDR pc,SI address,SI value)782a1ba9ba4Schristos frvbf_write_mem_SI (SIM_CPU *current_cpu, IADDR pc, SI address, SI value)
783a1ba9ba4Schristos {
784a1ba9ba4Schristos   USI hsr0;
785a1ba9ba4Schristos   hsr0 = GET_HSR0 ();
786a1ba9ba4Schristos   if (GET_HSR0_DCE (hsr0))
787a1ba9ba4Schristos     sim_queue_fn_mem_si_write (current_cpu, frvbf_mem_set_SI, address, value);
788a1ba9ba4Schristos   else
789a1ba9ba4Schristos     sim_queue_mem_si_write (current_cpu, address, value);
790a1ba9ba4Schristos   frv_set_write_queue_slot (current_cpu);
791a1ba9ba4Schristos }
792a1ba9ba4Schristos 
793a1ba9ba4Schristos void
frvbf_write_mem_WI(SIM_CPU * current_cpu,IADDR pc,SI address,SI value)794a1ba9ba4Schristos frvbf_write_mem_WI (SIM_CPU *current_cpu, IADDR pc, SI address, SI value)
795a1ba9ba4Schristos {
796a1ba9ba4Schristos   frvbf_write_mem_SI (current_cpu, pc, address, value);
797a1ba9ba4Schristos }
798a1ba9ba4Schristos 
799a1ba9ba4Schristos void
frvbf_write_mem_DI(SIM_CPU * current_cpu,IADDR pc,SI address,DI value)800a1ba9ba4Schristos frvbf_write_mem_DI (SIM_CPU *current_cpu, IADDR pc, SI address, DI value)
801a1ba9ba4Schristos {
802a1ba9ba4Schristos   USI hsr0;
803a1ba9ba4Schristos   hsr0 = GET_HSR0 ();
804a1ba9ba4Schristos   if (GET_HSR0_DCE (hsr0))
805a1ba9ba4Schristos     sim_queue_fn_mem_di_write (current_cpu, frvbf_mem_set_DI, address, value);
806a1ba9ba4Schristos   else
807a1ba9ba4Schristos     sim_queue_mem_di_write (current_cpu, address, value);
808a1ba9ba4Schristos   frv_set_write_queue_slot (current_cpu);
809a1ba9ba4Schristos }
810a1ba9ba4Schristos 
811a1ba9ba4Schristos void
frvbf_write_mem_DF(SIM_CPU * current_cpu,IADDR pc,SI address,DF value)812a1ba9ba4Schristos frvbf_write_mem_DF (SIM_CPU *current_cpu, IADDR pc, SI address, DF value)
813a1ba9ba4Schristos {
814a1ba9ba4Schristos   USI hsr0;
815a1ba9ba4Schristos   hsr0 = GET_HSR0 ();
816a1ba9ba4Schristos   if (GET_HSR0_DCE (hsr0))
817a1ba9ba4Schristos     sim_queue_fn_mem_df_write (current_cpu, frvbf_mem_set_DF, address, value);
818a1ba9ba4Schristos   else
819a1ba9ba4Schristos     sim_queue_mem_df_write (current_cpu, address, value);
820a1ba9ba4Schristos   frv_set_write_queue_slot (current_cpu);
821a1ba9ba4Schristos }
822a1ba9ba4Schristos 
823a1ba9ba4Schristos /* Memory writes.  These do the actual writing through the cache.  */
824a1ba9ba4Schristos void
frvbf_mem_set_QI(SIM_CPU * current_cpu,IADDR pc,SI address,QI value)825a1ba9ba4Schristos frvbf_mem_set_QI (SIM_CPU *current_cpu, IADDR pc, SI address, QI value)
826a1ba9ba4Schristos {
827a1ba9ba4Schristos   FRV_CACHE *cache = CPU_DATA_CACHE (current_cpu);
828a1ba9ba4Schristos 
829a1ba9ba4Schristos   /* Check for access errors.  */
830a1ba9ba4Schristos   address = check_write_address (current_cpu, address, 0);
831a1ba9ba4Schristos   address = check_readwrite_address (current_cpu, address, 0);
832a1ba9ba4Schristos 
833a1ba9ba4Schristos   /* If we need to count cycles, then submit the write request to the cache
834a1ba9ba4Schristos      and let it prioritize the request.  Otherwise perform the write now.  */
835a1ba9ba4Schristos   if (model_insn)
836a1ba9ba4Schristos     {
837a1ba9ba4Schristos       int slot = UNIT_I0;
838a1ba9ba4Schristos       frv_cache_request_store (cache, address, slot, (char *)&value,
839a1ba9ba4Schristos 			       sizeof (value));
840a1ba9ba4Schristos     }
841a1ba9ba4Schristos   else
842a1ba9ba4Schristos     frv_cache_write (cache, address, (char *)&value, sizeof (value));
843a1ba9ba4Schristos }
844a1ba9ba4Schristos 
845a1ba9ba4Schristos /* Write a HI which spans two cache lines */
846a1ba9ba4Schristos static void
mem_set_unaligned_HI(SIM_CPU * current_cpu,IADDR pc,SI address,HI value)847a1ba9ba4Schristos mem_set_unaligned_HI (SIM_CPU *current_cpu, IADDR pc, SI address, HI value)
848a1ba9ba4Schristos {
849a1ba9ba4Schristos   FRV_CACHE *cache = CPU_DATA_CACHE (current_cpu);
850a1ba9ba4Schristos   /* value is already in target byte order */
851a1ba9ba4Schristos   frv_cache_write (cache, address, (char *)&value, 1);
852a1ba9ba4Schristos   frv_cache_write (cache, address + 1, ((char *)&value + 1), 1);
853a1ba9ba4Schristos }
854a1ba9ba4Schristos 
855a1ba9ba4Schristos void
frvbf_mem_set_HI(SIM_CPU * current_cpu,IADDR pc,SI address,HI value)856a1ba9ba4Schristos frvbf_mem_set_HI (SIM_CPU *current_cpu, IADDR pc, SI address, HI value)
857a1ba9ba4Schristos {
858a1ba9ba4Schristos   FRV_CACHE *cache;
859a1ba9ba4Schristos 
860a1ba9ba4Schristos   /* Check for access errors.  */
861a1ba9ba4Schristos   address = check_write_address (current_cpu, address, 1);
862a1ba9ba4Schristos   address = check_readwrite_address (current_cpu, address, 1);
863a1ba9ba4Schristos 
864a1ba9ba4Schristos   /* If we need to count cycles, then submit the write request to the cache
865a1ba9ba4Schristos      and let it prioritize the request.  Otherwise perform the write now.  */
866a1ba9ba4Schristos   value = H2T_2 (value);
867a1ba9ba4Schristos   cache = CPU_DATA_CACHE (current_cpu);
868a1ba9ba4Schristos   if (model_insn)
869a1ba9ba4Schristos     {
870a1ba9ba4Schristos       int slot = UNIT_I0;
871a1ba9ba4Schristos       frv_cache_request_store (cache, address, slot,
872a1ba9ba4Schristos 			       (char *)&value, sizeof (value));
873a1ba9ba4Schristos     }
874a1ba9ba4Schristos   else
875a1ba9ba4Schristos     {
876a1ba9ba4Schristos       /* Handle access which crosses cache line boundary */
877a1ba9ba4Schristos       SIM_DESC sd = CPU_STATE (current_cpu);
878a1ba9ba4Schristos       if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr550)
879a1ba9ba4Schristos 	{
880a1ba9ba4Schristos 	  if (DATA_CROSSES_CACHE_LINE (cache, address, 2))
881a1ba9ba4Schristos 	    {
882a1ba9ba4Schristos 	      mem_set_unaligned_HI (current_cpu, pc, address, value);
883a1ba9ba4Schristos 	      return;
884a1ba9ba4Schristos 	    }
885a1ba9ba4Schristos 	}
886a1ba9ba4Schristos       frv_cache_write (cache, address, (char *)&value, sizeof (value));
887a1ba9ba4Schristos     }
888a1ba9ba4Schristos }
889a1ba9ba4Schristos 
890a1ba9ba4Schristos /* Write a SI which spans two cache lines */
891a1ba9ba4Schristos static void
mem_set_unaligned_SI(SIM_CPU * current_cpu,IADDR pc,SI address,SI value)892a1ba9ba4Schristos mem_set_unaligned_SI (SIM_CPU *current_cpu, IADDR pc, SI address, SI value)
893a1ba9ba4Schristos {
894a1ba9ba4Schristos   FRV_CACHE *cache = CPU_DATA_CACHE (current_cpu);
895a1ba9ba4Schristos   unsigned hi_len = cache->line_size - (address & (cache->line_size - 1));
896a1ba9ba4Schristos   /* value is already in target byte order */
897a1ba9ba4Schristos   frv_cache_write (cache, address, (char *)&value, hi_len);
898a1ba9ba4Schristos   frv_cache_write (cache, address + hi_len, (char *)&value + hi_len, 4 - hi_len);
899a1ba9ba4Schristos }
900a1ba9ba4Schristos 
901a1ba9ba4Schristos void
frvbf_mem_set_SI(SIM_CPU * current_cpu,IADDR pc,SI address,SI value)902a1ba9ba4Schristos frvbf_mem_set_SI (SIM_CPU *current_cpu, IADDR pc, SI address, SI value)
903a1ba9ba4Schristos {
904a1ba9ba4Schristos   FRV_CACHE *cache;
905a1ba9ba4Schristos 
906a1ba9ba4Schristos   /* Check for access errors.  */
907a1ba9ba4Schristos   address = check_write_address (current_cpu, address, 3);
908a1ba9ba4Schristos   address = check_readwrite_address (current_cpu, address, 3);
909a1ba9ba4Schristos 
910a1ba9ba4Schristos   /* If we need to count cycles, then submit the write request to the cache
911a1ba9ba4Schristos      and let it prioritize the request.  Otherwise perform the write now.  */
912a1ba9ba4Schristos   cache = CPU_DATA_CACHE (current_cpu);
913a1ba9ba4Schristos   value = H2T_4 (value);
914a1ba9ba4Schristos   if (model_insn)
915a1ba9ba4Schristos     {
916a1ba9ba4Schristos       int slot = UNIT_I0;
917a1ba9ba4Schristos       frv_cache_request_store (cache, address, slot,
918a1ba9ba4Schristos 			       (char *)&value, sizeof (value));
919a1ba9ba4Schristos     }
920a1ba9ba4Schristos   else
921a1ba9ba4Schristos     {
922a1ba9ba4Schristos       /* Handle access which crosses cache line boundary */
923a1ba9ba4Schristos       SIM_DESC sd = CPU_STATE (current_cpu);
924a1ba9ba4Schristos       if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr550)
925a1ba9ba4Schristos 	{
926a1ba9ba4Schristos 	  if (DATA_CROSSES_CACHE_LINE (cache, address, 4))
927a1ba9ba4Schristos 	    {
928a1ba9ba4Schristos 	      mem_set_unaligned_SI (current_cpu, pc, address, value);
929a1ba9ba4Schristos 	      return;
930a1ba9ba4Schristos 	    }
931a1ba9ba4Schristos 	}
932a1ba9ba4Schristos       frv_cache_write (cache, address, (char *)&value, sizeof (value));
933a1ba9ba4Schristos     }
934a1ba9ba4Schristos }
935a1ba9ba4Schristos 
936a1ba9ba4Schristos /* Write a DI which spans two cache lines */
937a1ba9ba4Schristos static void
mem_set_unaligned_DI(SIM_CPU * current_cpu,IADDR pc,SI address,DI value)938a1ba9ba4Schristos mem_set_unaligned_DI (SIM_CPU *current_cpu, IADDR pc, SI address, DI value)
939a1ba9ba4Schristos {
940a1ba9ba4Schristos   FRV_CACHE *cache = CPU_DATA_CACHE (current_cpu);
941a1ba9ba4Schristos   unsigned hi_len = cache->line_size - (address & (cache->line_size - 1));
942a1ba9ba4Schristos   /* value is already in target byte order */
943a1ba9ba4Schristos   frv_cache_write (cache, address, (char *)&value, hi_len);
944a1ba9ba4Schristos   frv_cache_write (cache, address + hi_len, (char *)&value + hi_len, 8 - hi_len);
945a1ba9ba4Schristos }
946a1ba9ba4Schristos 
947a1ba9ba4Schristos void
frvbf_mem_set_DI(SIM_CPU * current_cpu,IADDR pc,SI address,DI value)948a1ba9ba4Schristos frvbf_mem_set_DI (SIM_CPU *current_cpu, IADDR pc, SI address, DI value)
949a1ba9ba4Schristos {
950a1ba9ba4Schristos   FRV_CACHE *cache;
951a1ba9ba4Schristos 
952a1ba9ba4Schristos   /* Check for access errors.  */
953a1ba9ba4Schristos   address = check_write_address (current_cpu, address, 7);
954a1ba9ba4Schristos   address = check_readwrite_address (current_cpu, address, 7);
955a1ba9ba4Schristos 
956a1ba9ba4Schristos   /* If we need to count cycles, then submit the write request to the cache
957a1ba9ba4Schristos      and let it prioritize the request.  Otherwise perform the write now.  */
958a1ba9ba4Schristos   value = H2T_8 (value);
959a1ba9ba4Schristos   cache = CPU_DATA_CACHE (current_cpu);
960a1ba9ba4Schristos   if (model_insn)
961a1ba9ba4Schristos     {
962a1ba9ba4Schristos       int slot = UNIT_I0;
963a1ba9ba4Schristos       frv_cache_request_store (cache, address, slot,
964a1ba9ba4Schristos 			       (char *)&value, sizeof (value));
965a1ba9ba4Schristos     }
966a1ba9ba4Schristos   else
967a1ba9ba4Schristos     {
968a1ba9ba4Schristos       /* Handle access which crosses cache line boundary */
969a1ba9ba4Schristos       SIM_DESC sd = CPU_STATE (current_cpu);
970a1ba9ba4Schristos       if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr550)
971a1ba9ba4Schristos 	{
972a1ba9ba4Schristos 	  if (DATA_CROSSES_CACHE_LINE (cache, address, 8))
973a1ba9ba4Schristos 	    {
974a1ba9ba4Schristos 	      mem_set_unaligned_DI (current_cpu, pc, address, value);
975a1ba9ba4Schristos 	      return;
976a1ba9ba4Schristos 	    }
977a1ba9ba4Schristos 	}
978a1ba9ba4Schristos       frv_cache_write (cache, address, (char *)&value, sizeof (value));
979a1ba9ba4Schristos     }
980a1ba9ba4Schristos }
981a1ba9ba4Schristos 
982a1ba9ba4Schristos void
frvbf_mem_set_DF(SIM_CPU * current_cpu,IADDR pc,SI address,DF value)983a1ba9ba4Schristos frvbf_mem_set_DF (SIM_CPU *current_cpu, IADDR pc, SI address, DF value)
984a1ba9ba4Schristos {
985a1ba9ba4Schristos   FRV_CACHE *cache;
986a1ba9ba4Schristos 
987a1ba9ba4Schristos   /* Check for access errors.  */
988a1ba9ba4Schristos   address = check_write_address (current_cpu, address, 7);
989a1ba9ba4Schristos   address = check_readwrite_address (current_cpu, address, 7);
990a1ba9ba4Schristos 
991a1ba9ba4Schristos   /* If we need to count cycles, then submit the write request to the cache
992a1ba9ba4Schristos      and let it prioritize the request.  Otherwise perform the write now.  */
993a1ba9ba4Schristos   value = H2T_8 (value);
994a1ba9ba4Schristos   cache = CPU_DATA_CACHE (current_cpu);
995a1ba9ba4Schristos   if (model_insn)
996a1ba9ba4Schristos     {
997a1ba9ba4Schristos       int slot = UNIT_I0;
998a1ba9ba4Schristos       frv_cache_request_store (cache, address, slot,
999a1ba9ba4Schristos 			       (char *)&value, sizeof (value));
1000a1ba9ba4Schristos     }
1001a1ba9ba4Schristos   else
1002a1ba9ba4Schristos     {
1003a1ba9ba4Schristos       /* Handle access which crosses cache line boundary */
1004a1ba9ba4Schristos       SIM_DESC sd = CPU_STATE (current_cpu);
1005a1ba9ba4Schristos       if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr550)
1006a1ba9ba4Schristos 	{
1007a1ba9ba4Schristos 	  if (DATA_CROSSES_CACHE_LINE (cache, address, 8))
1008a1ba9ba4Schristos 	    {
1009a1ba9ba4Schristos 	      mem_set_unaligned_DI (current_cpu, pc, address, value);
1010a1ba9ba4Schristos 	      return;
1011a1ba9ba4Schristos 	    }
1012a1ba9ba4Schristos 	}
1013a1ba9ba4Schristos       frv_cache_write (cache, address, (char *)&value, sizeof (value));
1014a1ba9ba4Schristos     }
1015a1ba9ba4Schristos }
1016a1ba9ba4Schristos 
1017a1ba9ba4Schristos void
frvbf_mem_set_XI(SIM_CPU * current_cpu,IADDR pc,SI address,SI * value)1018a1ba9ba4Schristos frvbf_mem_set_XI (SIM_CPU *current_cpu, IADDR pc, SI address, SI *value)
1019a1ba9ba4Schristos {
1020a1ba9ba4Schristos   int i;
1021a1ba9ba4Schristos   FRV_CACHE *cache;
1022a1ba9ba4Schristos 
1023a1ba9ba4Schristos   /* Check for access errors.  */
1024a1ba9ba4Schristos   address = check_write_address (current_cpu, address, 0xf);
1025a1ba9ba4Schristos   address = check_readwrite_address (current_cpu, address, 0xf);
1026a1ba9ba4Schristos 
1027a1ba9ba4Schristos   /* TODO -- reverse word order as well?  */
1028a1ba9ba4Schristos   for (i = 0; i < 4; ++i)
1029a1ba9ba4Schristos     value[i] = H2T_4 (value[i]);
1030a1ba9ba4Schristos 
1031a1ba9ba4Schristos   /* If we need to count cycles, then submit the write request to the cache
1032a1ba9ba4Schristos      and let it prioritize the request.  Otherwise perform the write now.  */
1033a1ba9ba4Schristos   cache = CPU_DATA_CACHE (current_cpu);
1034a1ba9ba4Schristos   if (model_insn)
1035a1ba9ba4Schristos     {
1036a1ba9ba4Schristos       int slot = UNIT_I0;
1037a1ba9ba4Schristos       frv_cache_request_store (cache, address, slot, (char*)value, 16);
1038a1ba9ba4Schristos     }
1039a1ba9ba4Schristos   else
1040a1ba9ba4Schristos     frv_cache_write (cache, address, (char*)value, 16);
1041a1ba9ba4Schristos }
1042a1ba9ba4Schristos 
1043a1ba9ba4Schristos /* Record the current VLIW slot on the element at the top of the write queue.
1044a1ba9ba4Schristos */
1045a1ba9ba4Schristos void
frv_set_write_queue_slot(SIM_CPU * current_cpu)1046a1ba9ba4Schristos frv_set_write_queue_slot (SIM_CPU *current_cpu)
1047a1ba9ba4Schristos {
1048a1ba9ba4Schristos   FRV_VLIW *vliw = CPU_VLIW (current_cpu);
1049a1ba9ba4Schristos   int slot = vliw->next_slot - 1;
1050a1ba9ba4Schristos   CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (current_cpu);
1051a1ba9ba4Schristos   int ix = CGEN_WRITE_QUEUE_INDEX (q) - 1;
1052a1ba9ba4Schristos   CGEN_WRITE_QUEUE_ELEMENT *item = CGEN_WRITE_QUEUE_ELEMENT (q, ix);
1053a1ba9ba4Schristos   CGEN_WRITE_QUEUE_ELEMENT_PIPE (item) = (*vliw->current_vliw)[slot];
1054a1ba9ba4Schristos }
1055