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