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.1.5 christos /* This must come before any other includes. */ 23 1.1.1.5 christos #include "defs.h" 24 1.1.1.5 christos 25 1.1 christos #include "sim-main.h" 26 1.1 christos #include "sim-assert.h" 27 1.1 christos 28 1.1.1.5 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.1.1.5 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.1.1.5 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.1.1.5 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.1.1.5 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.1.1.5 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.1.1.5 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.1.1.5 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.1.1.5 christos 194 1.1 christos dotrace (SD, CPU, tracefh,1,(unsigned int)(pAddr&0xFFFFFFFF),(AccessLength + 1),"store"); 195 1.1.1.5 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.1.1.5 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.1.1.5 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.1.1.5 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.1.1.5 christos } 252 1.1.1.5 christos 253 1.1 christos return; 254 1.1 christos } 255 1.1 christos 256 1.1 christos 257 1.1.1.5 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.1.1.4 christos address_word paddr = vaddr; 270 1.1.1.5 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.1.1.4 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.1.1.5 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.1.1.4 christos address_word paddr = vaddr; 294 1.1.1.5 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.1.1.4 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.1.1.5 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.1.1.5 christos if (PENDING_TRACE) 407 1.1.1.5 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.1.1.5 christos if (PENDING_OUT != PENDING_IN) 409 1.1.1.5 christos { 410 1.1.1.5 christos int loop; 411 1.1.1.5 christos int index = PENDING_OUT; 412 1.1.1.5 christos int total = PENDING_TOTAL; 413 1.1.1.5 christos if (PENDING_TOTAL == 0) 414 1.1.1.5 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.1.1.5 christos { 419 1.1.1.5 christos if (PENDING_SLOT_DEST[index] != NULL) 420 1.1.1.5 christos { 421 1.1.1.5 christos PENDING_SLOT_DELAY[index] -= 1; 422 1.1.1.5 christos if (PENDING_SLOT_DELAY[index] == 0) 423 1.1.1.5 christos { 424 1.1 christos if (PENDING_TRACE) 425 1.1.1.5 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.1.1.5 christos PENDING_SLOT_DEST[index], 428 1.1 christos PENDING_SLOT_BIT[index], 429 1.1.1.5 christos PENDING_SLOT_VALUE[index], 430 1.1 christos PENDING_SLOT_SIZE[index]); 431 1.1.1.5 christos if (PENDING_SLOT_BIT[index] >= 0) 432 1.1.1.5 christos switch (PENDING_SLOT_SIZE[index]) 433 1.1.1.5 christos { 434 1.1 christos case 4: 435 1.1.1.5 christos if (PENDING_SLOT_VALUE[index]) 436 1.1.1.5 christos *(uint32_t*)PENDING_SLOT_DEST[index] |= 437 1.1.1.5 christos BIT32 (PENDING_SLOT_BIT[index]); 438 1.1.1.5 christos else 439 1.1.1.5 christos *(uint32_t*)PENDING_SLOT_DEST[index] &= 440 1.1.1.5 christos BIT32 (PENDING_SLOT_BIT[index]); 441 1.1.1.5 christos break; 442 1.1.1.5 christos case 8: 443 1.1.1.5 christos if (PENDING_SLOT_VALUE[index]) 444 1.1.1.5 christos *(uint64_t*)PENDING_SLOT_DEST[index] |= 445 1.1.1.5 christos BIT64 (PENDING_SLOT_BIT[index]); 446 1.1.1.5 christos else 447 1.1.1.5 christos *(uint64_t*)PENDING_SLOT_DEST[index] &= 448 1.1.1.5 christos BIT64 (PENDING_SLOT_BIT[index]); 449 1.1.1.5 christos break; 450 1.1 christos } 451 1.1 christos else 452 1.1.1.5 christos switch (PENDING_SLOT_SIZE[index]) 453 1.1.1.5 christos { 454 1.1.1.5 christos case 4: 455 1.1.1.5 christos *(uint32_t*)PENDING_SLOT_DEST[index] = 456 1.1.1.5 christos PENDING_SLOT_VALUE[index]; 457 1.1.1.5 christos break; 458 1.1.1.5 christos case 8: 459 1.1.1.5 christos *(uint64_t*)PENDING_SLOT_DEST[index] = 460 1.1.1.5 christos PENDING_SLOT_VALUE[index]; 461 1.1.1.5 christos break; 462 1.1.1.5 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.1.1.5 christos } 470 1.1 christos else if (PENDING_TRACE && PENDING_SLOT_DELAY[index] > 0) 471 1.1.1.5 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.1.1.5 christos PENDING_SLOT_DEST[index], 474 1.1 christos PENDING_SLOT_BIT[index], 475 1.1.1.5 christos PENDING_SLOT_VALUE[index], 476 1.1 christos PENDING_SLOT_SIZE[index]); 477 1.1 christos 478 1.1.1.5 christos } 479 1.1.1.5 christos } 480 1.1.1.5 christos } 481 1.1 christos } 482 1.1 christos 483 1.1 christos 484 1.1 christos #endif 485