sim-main.c revision 1.7 1 1.1 christos /* Copyright (C) 1998, Cygnus Solutions
2 1.1 christos
3 1.1 christos This program is free software; you can redistribute it and/or modify
4 1.1 christos it under the terms of the GNU General Public License as published by
5 1.1 christos the Free Software Foundation; either version 3 of the License, or
6 1.1 christos (at your option) any later version.
7 1.1 christos
8 1.1 christos This program is distributed in the hope that it will be useful,
9 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
10 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 1.1 christos GNU General Public License for more details.
12 1.1 christos
13 1.1 christos You should have received a copy of the GNU General Public License
14 1.1 christos along with this program; if not, see <http://www.gnu.org/licenses/>.
15 1.1 christos
16 1.1 christos */
17 1.1 christos
18 1.1 christos
19 1.1 christos #ifndef SIM_MAIN_C
20 1.1 christos #define SIM_MAIN_C
21 1.1 christos
22 1.7 christos /* This must come before any other includes. */
23 1.7 christos #include "defs.h"
24 1.7 christos
25 1.1 christos #include "sim-main.h"
26 1.1 christos #include "sim-assert.h"
27 1.1 christos
28 1.7 christos #include <stdlib.h>
29 1.1 christos
30 1.1 christos /*---------------------------------------------------------------------------*/
31 1.1 christos /*-- simulator engine -------------------------------------------------------*/
32 1.1 christos /*---------------------------------------------------------------------------*/
33 1.1 christos
34 1.1 christos
35 1.1 christos /* Description from page A-22 of the "MIPS IV Instruction Set" manual
36 1.1 christos (revision 3.1) */
37 1.1 christos /* Load a value from memory. Use the cache and main memory as
38 1.1 christos specified in the Cache Coherence Algorithm (CCA) and the sort of
39 1.1 christos access (IorD) to find the contents of AccessLength memory bytes
40 1.1 christos starting at physical location pAddr. The data is returned in the
41 1.1 christos fixed width naturally-aligned memory element (MemElem). The
42 1.1 christos low-order two (or three) bits of the address and the AccessLength
43 1.1 christos indicate which of the bytes within MemElem needs to be given to the
44 1.1 christos processor. If the memory access type of the reference is uncached
45 1.1 christos then only the referenced bytes are read from memory and valid
46 1.1 christos within the memory element. If the access type is cached, and the
47 1.1 christos data is not present in cache, an implementation specific size and
48 1.1 christos alignment block of memory is read and loaded into the cache to
49 1.1 christos satisfy a load reference. At a minimum, the block is the entire
50 1.1 christos memory element. */
51 1.1 christos INLINE_SIM_MAIN (void)
52 1.1 christos load_memory (SIM_DESC SD,
53 1.1 christos sim_cpu *CPU,
54 1.1 christos address_word cia,
55 1.1 christos uword64* memvalp,
56 1.1 christos uword64* memval1p,
57 1.1 christos int CCA,
58 1.1 christos unsigned int AccessLength,
59 1.1 christos address_word pAddr,
60 1.1 christos address_word vAddr,
61 1.1 christos int IorD)
62 1.1 christos {
63 1.1 christos uword64 value = 0;
64 1.1 christos uword64 value1 = 0;
65 1.1 christos
66 1.1 christos #ifdef DEBUG
67 1.1 christos sim_io_printf(sd,"DBG: LoadMemory(%p,%p,%d,%d,0x%s,0x%s,%s)\n",memvalp,memval1p,CCA,AccessLength,pr_addr(pAddr),pr_addr(vAddr),(IorD ? "isDATA" : "isINSTRUCTION"));
68 1.1 christos #endif /* DEBUG */
69 1.1 christos
70 1.1 christos #if defined(WARN_MEM)
71 1.1 christos if (CCA != uncached)
72 1.1 christos sim_io_eprintf(sd,"LoadMemory CCA (%d) is not uncached (currently all accesses treated as cached)\n",CCA);
73 1.1 christos #endif /* WARN_MEM */
74 1.1 christos
75 1.1 christos if (((pAddr & LOADDRMASK) + AccessLength) > LOADDRMASK)
76 1.1 christos {
77 1.1 christos /* In reality this should be a Bus Error */
78 1.1 christos sim_io_error (SD, "LOAD AccessLength of %d would extend over %d bit aligned boundary for physical address 0x%s\n",
79 1.1 christos AccessLength,
80 1.1 christos (LOADDRMASK + 1) << 3,
81 1.1 christos pr_addr (pAddr));
82 1.1 christos }
83 1.1 christos
84 1.1 christos dotrace (SD, CPU, tracefh,((IorD == isDATA) ? 0 : 2),(unsigned int)(pAddr&0xFFFFFFFF),(AccessLength + 1),"load%s",((IorD == isDATA) ? "" : " instruction"));
85 1.7 christos
86 1.1 christos /* Read the specified number of bytes from memory. Adjust for
87 1.1 christos host/target byte ordering/ Align the least significant byte
88 1.1 christos read. */
89 1.1 christos
90 1.1 christos switch (AccessLength)
91 1.1 christos {
92 1.1 christos case AccessLength_QUADWORD:
93 1.1 christos {
94 1.1 christos unsigned_16 val = sim_core_read_aligned_16 (CPU, cia, read_map, pAddr);
95 1.1 christos value1 = VH8_16 (val);
96 1.1 christos value = VL8_16 (val);
97 1.1 christos break;
98 1.1 christos }
99 1.1 christos case AccessLength_DOUBLEWORD:
100 1.1 christos value = sim_core_read_aligned_8 (CPU, cia, read_map, pAddr);
101 1.1 christos break;
102 1.1 christos case AccessLength_SEPTIBYTE:
103 1.1 christos value = sim_core_read_misaligned_7 (CPU, cia, read_map, pAddr);
104 1.1 christos break;
105 1.1 christos case AccessLength_SEXTIBYTE:
106 1.1 christos value = sim_core_read_misaligned_6 (CPU, cia, read_map, pAddr);
107 1.1 christos break;
108 1.1 christos case AccessLength_QUINTIBYTE:
109 1.1 christos value = sim_core_read_misaligned_5 (CPU, cia, read_map, pAddr);
110 1.1 christos break;
111 1.1 christos case AccessLength_WORD:
112 1.1 christos value = sim_core_read_aligned_4 (CPU, cia, read_map, pAddr);
113 1.1 christos break;
114 1.1 christos case AccessLength_TRIPLEBYTE:
115 1.1 christos value = sim_core_read_misaligned_3 (CPU, cia, read_map, pAddr);
116 1.1 christos break;
117 1.1 christos case AccessLength_HALFWORD:
118 1.1 christos value = sim_core_read_aligned_2 (CPU, cia, read_map, pAddr);
119 1.1 christos break;
120 1.1 christos case AccessLength_BYTE:
121 1.1 christos value = sim_core_read_aligned_1 (CPU, cia, read_map, pAddr);
122 1.1 christos break;
123 1.1 christos default:
124 1.1 christos abort ();
125 1.1 christos }
126 1.7 christos
127 1.1 christos #ifdef DEBUG
128 1.1 christos printf("DBG: LoadMemory() : (offset %d) : value = 0x%s%s\n",
129 1.1 christos (int)(pAddr & LOADDRMASK),pr_uword64(value1),pr_uword64(value));
130 1.1 christos #endif /* DEBUG */
131 1.7 christos
132 1.1 christos /* See also store_memory. Position data in correct byte lanes. */
133 1.1 christos if (AccessLength <= LOADDRMASK)
134 1.1 christos {
135 1.1 christos if (BigEndianMem)
136 1.1 christos /* for big endian target, byte (pAddr&LOADDRMASK == 0) is
137 1.1 christos shifted to the most significant byte position. */
138 1.1 christos value <<= (((LOADDRMASK - (pAddr & LOADDRMASK)) - AccessLength) * 8);
139 1.1 christos else
140 1.1 christos /* For little endian target, byte (pAddr&LOADDRMASK == 0)
141 1.1 christos is already in the correct postition. */
142 1.1 christos value <<= ((pAddr & LOADDRMASK) * 8);
143 1.1 christos }
144 1.7 christos
145 1.1 christos #ifdef DEBUG
146 1.1 christos printf("DBG: LoadMemory() : shifted value = 0x%s%s\n",
147 1.1 christos pr_uword64(value1),pr_uword64(value));
148 1.1 christos #endif /* DEBUG */
149 1.7 christos
150 1.1 christos *memvalp = value;
151 1.1 christos if (memval1p) *memval1p = value1;
152 1.1 christos }
153 1.1 christos
154 1.1 christos
155 1.1 christos /* Description from page A-23 of the "MIPS IV Instruction Set" manual
156 1.1 christos (revision 3.1) */
157 1.1 christos /* Store a value to memory. The specified data is stored into the
158 1.1 christos physical location pAddr using the memory hierarchy (data caches and
159 1.1 christos main memory) as specified by the Cache Coherence Algorithm
160 1.1 christos (CCA). The MemElem contains the data for an aligned, fixed-width
161 1.1 christos memory element (word for 32-bit processors, doubleword for 64-bit
162 1.1 christos processors), though only the bytes that will actually be stored to
163 1.1 christos memory need to be valid. The low-order two (or three) bits of pAddr
164 1.1 christos and the AccessLength field indicates which of the bytes within the
165 1.1 christos MemElem data should actually be stored; only these bytes in memory
166 1.1 christos will be changed. */
167 1.1 christos
168 1.1 christos INLINE_SIM_MAIN (void)
169 1.1 christos store_memory (SIM_DESC SD,
170 1.1 christos sim_cpu *CPU,
171 1.1 christos address_word cia,
172 1.1 christos int CCA,
173 1.1 christos unsigned int AccessLength,
174 1.1 christos uword64 MemElem,
175 1.1 christos uword64 MemElem1, /* High order 64 bits */
176 1.1 christos address_word pAddr,
177 1.1 christos address_word vAddr)
178 1.1 christos {
179 1.1 christos #ifdef DEBUG
180 1.1 christos sim_io_printf(sd,"DBG: StoreMemory(%d,%d,0x%s,0x%s,0x%s,0x%s)\n",CCA,AccessLength,pr_uword64(MemElem),pr_uword64(MemElem1),pr_addr(pAddr),pr_addr(vAddr));
181 1.1 christos #endif /* DEBUG */
182 1.7 christos
183 1.1 christos #if defined(WARN_MEM)
184 1.1 christos if (CCA != uncached)
185 1.1 christos sim_io_eprintf(sd,"StoreMemory CCA (%d) is not uncached (currently all accesses treated as cached)\n",CCA);
186 1.1 christos #endif /* WARN_MEM */
187 1.7 christos
188 1.1 christos if (((pAddr & LOADDRMASK) + AccessLength) > LOADDRMASK)
189 1.1 christos sim_io_error (SD, "STORE AccessLength of %d would extend over %d bit aligned boundary for physical address 0x%s\n",
190 1.1 christos AccessLength,
191 1.1 christos (LOADDRMASK + 1) << 3,
192 1.1 christos pr_addr(pAddr));
193 1.7 christos
194 1.1 christos dotrace (SD, CPU, tracefh,1,(unsigned int)(pAddr&0xFFFFFFFF),(AccessLength + 1),"store");
195 1.7 christos
196 1.1 christos #ifdef DEBUG
197 1.1 christos printf("DBG: StoreMemory: offset = %d MemElem = 0x%s%s\n",(unsigned int)(pAddr & LOADDRMASK),pr_uword64(MemElem1),pr_uword64(MemElem));
198 1.1 christos #endif /* DEBUG */
199 1.7 christos
200 1.1 christos /* See also load_memory. Position data in correct byte lanes. */
201 1.1 christos if (AccessLength <= LOADDRMASK)
202 1.1 christos {
203 1.1 christos if (BigEndianMem)
204 1.1 christos /* for big endian target, byte (pAddr&LOADDRMASK == 0) is
205 1.1 christos shifted to the most significant byte position. */
206 1.1 christos MemElem >>= (((LOADDRMASK - (pAddr & LOADDRMASK)) - AccessLength) * 8);
207 1.1 christos else
208 1.1 christos /* For little endian target, byte (pAddr&LOADDRMASK == 0)
209 1.1 christos is already in the correct postition. */
210 1.1 christos MemElem >>= ((pAddr & LOADDRMASK) * 8);
211 1.1 christos }
212 1.7 christos
213 1.1 christos #ifdef DEBUG
214 1.1 christos printf("DBG: StoreMemory: shift = %d MemElem = 0x%s%s\n",shift,pr_uword64(MemElem1),pr_uword64(MemElem));
215 1.1 christos #endif /* DEBUG */
216 1.7 christos
217 1.1 christos switch (AccessLength)
218 1.1 christos {
219 1.1 christos case AccessLength_QUADWORD:
220 1.1 christos {
221 1.1 christos unsigned_16 val = U16_8 (MemElem1, MemElem);
222 1.1 christos sim_core_write_aligned_16 (CPU, cia, write_map, pAddr, val);
223 1.1 christos break;
224 1.1 christos }
225 1.1 christos case AccessLength_DOUBLEWORD:
226 1.1 christos sim_core_write_aligned_8 (CPU, cia, write_map, pAddr, MemElem);
227 1.1 christos break;
228 1.1 christos case AccessLength_SEPTIBYTE:
229 1.1 christos sim_core_write_misaligned_7 (CPU, cia, write_map, pAddr, MemElem);
230 1.1 christos break;
231 1.1 christos case AccessLength_SEXTIBYTE:
232 1.1 christos sim_core_write_misaligned_6 (CPU, cia, write_map, pAddr, MemElem);
233 1.1 christos break;
234 1.1 christos case AccessLength_QUINTIBYTE:
235 1.1 christos sim_core_write_misaligned_5 (CPU, cia, write_map, pAddr, MemElem);
236 1.1 christos break;
237 1.1 christos case AccessLength_WORD:
238 1.1 christos sim_core_write_aligned_4 (CPU, cia, write_map, pAddr, MemElem);
239 1.1 christos break;
240 1.1 christos case AccessLength_TRIPLEBYTE:
241 1.1 christos sim_core_write_misaligned_3 (CPU, cia, write_map, pAddr, MemElem);
242 1.1 christos break;
243 1.1 christos case AccessLength_HALFWORD:
244 1.1 christos sim_core_write_aligned_2 (CPU, cia, write_map, pAddr, MemElem);
245 1.1 christos break;
246 1.1 christos case AccessLength_BYTE:
247 1.1 christos sim_core_write_aligned_1 (CPU, cia, write_map, pAddr, MemElem);
248 1.1 christos break;
249 1.1 christos default:
250 1.1 christos abort ();
251 1.7 christos }
252 1.7 christos
253 1.1 christos return;
254 1.1 christos }
255 1.1 christos
256 1.1 christos
257 1.7 christos INLINE_SIM_MAIN (uint32_t)
258 1.1 christos ifetch32 (SIM_DESC SD,
259 1.1 christos sim_cpu *CPU,
260 1.1 christos address_word cia,
261 1.1 christos address_word vaddr)
262 1.1 christos {
263 1.1 christos /* Copy the action of the LW instruction */
264 1.1 christos address_word mask = LOADDRMASK;
265 1.1 christos address_word access = AccessLength_WORD;
266 1.1 christos address_word reverseendian = (ReverseEndian ? (mask ^ access) : 0);
267 1.1 christos address_word bigendiancpu = (BigEndianCPU ? (mask ^ access) : 0);
268 1.1 christos unsigned int byte;
269 1.6 christos address_word paddr = vaddr;
270 1.7 christos uint64_t memval;
271 1.1 christos
272 1.1 christos if ((vaddr & access) != 0)
273 1.1 christos SignalExceptionInstructionFetch ();
274 1.1 christos paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
275 1.6 christos LoadMemory (&memval, NULL, access, paddr, vaddr, isINSTRUCTION, isREAL);
276 1.1 christos byte = ((vaddr & mask) ^ bigendiancpu);
277 1.1 christos return (memval >> (8 * byte));
278 1.1 christos }
279 1.1 christos
280 1.1 christos
281 1.7 christos INLINE_SIM_MAIN (uint16_t)
282 1.1 christos ifetch16 (SIM_DESC SD,
283 1.1 christos sim_cpu *CPU,
284 1.1 christos address_word cia,
285 1.1 christos address_word vaddr)
286 1.1 christos {
287 1.1 christos /* Copy the action of the LH instruction */
288 1.1 christos address_word mask = LOADDRMASK;
289 1.1 christos address_word access = AccessLength_HALFWORD;
290 1.1 christos address_word reverseendian = (ReverseEndian ? (mask ^ access) : 0);
291 1.1 christos address_word bigendiancpu = (BigEndianCPU ? (mask ^ access) : 0);
292 1.1 christos unsigned int byte;
293 1.6 christos address_word paddr = vaddr;
294 1.7 christos uint64_t memval;
295 1.1 christos
296 1.1 christos if ((vaddr & access) != 0)
297 1.1 christos SignalExceptionInstructionFetch ();
298 1.1 christos paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
299 1.6 christos LoadMemory (&memval, NULL, access, paddr, vaddr, isINSTRUCTION, isREAL);
300 1.1 christos byte = ((vaddr & mask) ^ bigendiancpu);
301 1.1 christos return (memval >> (8 * byte));
302 1.1 christos }
303 1.1 christos
304 1.1 christos
305 1.1 christos
306 1.1 christos /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
307 1.1 christos /* Order loads and stores to synchronise shared memory. Perform the
308 1.1 christos action necessary to make the effects of groups of synchronizable
309 1.1 christos loads and stores indicated by stype occur in the same order for all
310 1.1 christos processors. */
311 1.1 christos INLINE_SIM_MAIN (void)
312 1.1 christos sync_operation (SIM_DESC sd,
313 1.1 christos sim_cpu *cpu,
314 1.1 christos address_word cia,
315 1.1 christos int stype)
316 1.1 christos {
317 1.1 christos #ifdef DEBUG
318 1.1 christos sim_io_printf(sd,"SyncOperation(%d) : TODO\n",stype);
319 1.1 christos #endif /* DEBUG */
320 1.1 christos return;
321 1.1 christos }
322 1.1 christos
323 1.1 christos INLINE_SIM_MAIN (void)
324 1.1 christos cache_op (SIM_DESC SD,
325 1.1 christos sim_cpu *CPU,
326 1.1 christos address_word cia,
327 1.1 christos int op,
328 1.1 christos address_word pAddr,
329 1.1 christos address_word vAddr,
330 1.1 christos unsigned int instruction)
331 1.1 christos {
332 1.1 christos #if 1 /* stop warning message being displayed (we should really just remove the code) */
333 1.1 christos static int icache_warning = 1;
334 1.1 christos static int dcache_warning = 1;
335 1.1 christos #else
336 1.1 christos static int icache_warning = 0;
337 1.1 christos static int dcache_warning = 0;
338 1.1 christos #endif
339 1.1 christos
340 1.1 christos /* If CP0 is not useable (User or Supervisor mode) and the CP0
341 1.1 christos enable bit in the Status Register is clear - a coprocessor
342 1.1 christos unusable exception is taken. */
343 1.1 christos #if 0
344 1.1 christos sim_io_printf(SD,"TODO: Cache availability checking (PC = 0x%s)\n",pr_addr(cia));
345 1.1 christos #endif
346 1.1 christos
347 1.1 christos switch (op & 0x3) {
348 1.1 christos case 0: /* instruction cache */
349 1.1 christos switch (op >> 2) {
350 1.1 christos case 0: /* Index Invalidate */
351 1.1 christos case 1: /* Index Load Tag */
352 1.1 christos case 2: /* Index Store Tag */
353 1.1 christos case 4: /* Hit Invalidate */
354 1.1 christos case 5: /* Fill */
355 1.1 christos case 6: /* Hit Writeback */
356 1.1 christos if (!icache_warning)
357 1.1 christos {
358 1.1 christos sim_io_eprintf(SD,"Instruction CACHE operation %d to be coded\n",(op >> 2));
359 1.1 christos icache_warning = 1;
360 1.1 christos }
361 1.1 christos break;
362 1.1 christos
363 1.1 christos default:
364 1.1 christos SignalException(ReservedInstruction,instruction);
365 1.1 christos break;
366 1.1 christos }
367 1.1 christos break;
368 1.1 christos
369 1.1 christos case 1: /* data cache */
370 1.1 christos case 3: /* secondary data cache */
371 1.1 christos switch (op >> 2) {
372 1.1 christos case 0: /* Index Writeback Invalidate */
373 1.1 christos case 1: /* Index Load Tag */
374 1.1 christos case 2: /* Index Store Tag */
375 1.1 christos case 3: /* Create Dirty */
376 1.1 christos case 4: /* Hit Invalidate */
377 1.1 christos case 5: /* Hit Writeback Invalidate */
378 1.7 christos case 6: /* Hit Writeback */
379 1.1 christos if (!dcache_warning)
380 1.1 christos {
381 1.1 christos sim_io_eprintf(SD,"Data CACHE operation %d to be coded\n",(op >> 2));
382 1.1 christos dcache_warning = 1;
383 1.1 christos }
384 1.1 christos break;
385 1.1 christos
386 1.1 christos default:
387 1.1 christos SignalException(ReservedInstruction,instruction);
388 1.1 christos break;
389 1.1 christos }
390 1.1 christos break;
391 1.1 christos
392 1.1 christos default: /* unrecognised cache ID */
393 1.1 christos SignalException(ReservedInstruction,instruction);
394 1.1 christos break;
395 1.1 christos }
396 1.1 christos
397 1.1 christos return;
398 1.1 christos }
399 1.1 christos
400 1.1 christos
401 1.1 christos INLINE_SIM_MAIN (void)
402 1.1 christos pending_tick (SIM_DESC SD,
403 1.1 christos sim_cpu *CPU,
404 1.1 christos address_word cia)
405 1.1 christos {
406 1.7 christos if (PENDING_TRACE)
407 1.7 christos sim_io_eprintf (SD, "PENDING_DRAIN - 0x%lx - pending_in = %d, pending_out = %d, pending_total = %d\n", (unsigned long) cia, PENDING_IN, PENDING_OUT, PENDING_TOTAL);
408 1.7 christos if (PENDING_OUT != PENDING_IN)
409 1.7 christos {
410 1.7 christos int loop;
411 1.7 christos int index = PENDING_OUT;
412 1.7 christos int total = PENDING_TOTAL;
413 1.7 christos if (PENDING_TOTAL == 0)
414 1.7 christos sim_engine_abort (SD, CPU, cia, "PENDING_DRAIN - Mis-match on pending update pointers\n");
415 1.1 christos for (loop = 0, index = PENDING_OUT;
416 1.1 christos (loop < total);
417 1.1 christos loop++, index = (index + 1) % PSLOTS)
418 1.7 christos {
419 1.7 christos if (PENDING_SLOT_DEST[index] != NULL)
420 1.7 christos {
421 1.7 christos PENDING_SLOT_DELAY[index] -= 1;
422 1.7 christos if (PENDING_SLOT_DELAY[index] == 0)
423 1.7 christos {
424 1.1 christos if (PENDING_TRACE)
425 1.7 christos sim_io_eprintf (SD, "PENDING_DRAIN - drained - index %d, dest %p, bit %d, val %" PRIx64 ", size %d\n",
426 1.1 christos index,
427 1.7 christos PENDING_SLOT_DEST[index],
428 1.1 christos PENDING_SLOT_BIT[index],
429 1.7 christos PENDING_SLOT_VALUE[index],
430 1.1 christos PENDING_SLOT_SIZE[index]);
431 1.7 christos if (PENDING_SLOT_BIT[index] >= 0)
432 1.7 christos switch (PENDING_SLOT_SIZE[index])
433 1.7 christos {
434 1.1 christos case 4:
435 1.7 christos if (PENDING_SLOT_VALUE[index])
436 1.7 christos *(uint32_t*)PENDING_SLOT_DEST[index] |=
437 1.7 christos BIT32 (PENDING_SLOT_BIT[index]);
438 1.7 christos else
439 1.7 christos *(uint32_t*)PENDING_SLOT_DEST[index] &=
440 1.7 christos BIT32 (PENDING_SLOT_BIT[index]);
441 1.7 christos break;
442 1.7 christos case 8:
443 1.7 christos if (PENDING_SLOT_VALUE[index])
444 1.7 christos *(uint64_t*)PENDING_SLOT_DEST[index] |=
445 1.7 christos BIT64 (PENDING_SLOT_BIT[index]);
446 1.7 christos else
447 1.7 christos *(uint64_t*)PENDING_SLOT_DEST[index] &=
448 1.7 christos BIT64 (PENDING_SLOT_BIT[index]);
449 1.7 christos break;
450 1.1 christos }
451 1.1 christos else
452 1.7 christos switch (PENDING_SLOT_SIZE[index])
453 1.7 christos {
454 1.7 christos case 4:
455 1.7 christos *(uint32_t*)PENDING_SLOT_DEST[index] =
456 1.7 christos PENDING_SLOT_VALUE[index];
457 1.7 christos break;
458 1.7 christos case 8:
459 1.7 christos *(uint64_t*)PENDING_SLOT_DEST[index] =
460 1.7 christos PENDING_SLOT_VALUE[index];
461 1.7 christos break;
462 1.7 christos }
463 1.1 christos if (PENDING_OUT == index)
464 1.1 christos {
465 1.1 christos PENDING_SLOT_DEST[index] = NULL;
466 1.1 christos PENDING_OUT = (PENDING_OUT + 1) % PSLOTS;
467 1.1 christos PENDING_TOTAL--;
468 1.1 christos }
469 1.7 christos }
470 1.1 christos else if (PENDING_TRACE && PENDING_SLOT_DELAY[index] > 0)
471 1.7 christos sim_io_eprintf (SD, "PENDING_DRAIN - queued - index %d, delay %d, dest %p, bit %d, val %" PRIx64 ", size %d\n",
472 1.1 christos index, PENDING_SLOT_DELAY[index],
473 1.7 christos PENDING_SLOT_DEST[index],
474 1.1 christos PENDING_SLOT_BIT[index],
475 1.7 christos PENDING_SLOT_VALUE[index],
476 1.1 christos PENDING_SLOT_SIZE[index]);
477 1.1 christos
478 1.7 christos }
479 1.7 christos }
480 1.7 christos }
481 1.1 christos }
482 1.1 christos
483 1.1 christos
484 1.1 christos #endif
485