lsq_unit.hh (4284:c8800319ed0c) | lsq_unit.hh (4326:a9277254c1e4) |
---|---|
1/* 2 * Copyright (c) 2004-2006 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 283 unchanged lines hidden (view full) --- 292 /** The pointer to the LSQ unit that issued the store. */ 293 LSQUnit<Impl> *lsqPtr; 294 }; 295 296 public: 297 struct SQEntry { 298 /** Constructs an empty store queue entry. */ 299 SQEntry() | 1/* 2 * Copyright (c) 2004-2006 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 283 unchanged lines hidden (view full) --- 292 /** The pointer to the LSQ unit that issued the store. */ 293 LSQUnit<Impl> *lsqPtr; 294 }; 295 296 public: 297 struct SQEntry { 298 /** Constructs an empty store queue entry. */ 299 SQEntry() |
300 : inst(NULL), req(NULL), size(0), data(0), | 300 : inst(NULL), req(NULL), size(0), |
301 canWB(0), committed(0), completed(0) | 301 canWB(0), committed(0), completed(0) |
302 { } | 302 { 303 bzero(data, sizeof(data)); 304 } |
303 304 /** Constructs a store queue entry for a given instruction. */ 305 SQEntry(DynInstPtr &_inst) | 305 306 /** Constructs a store queue entry for a given instruction. */ 307 SQEntry(DynInstPtr &_inst) |
306 : inst(_inst), req(NULL), size(0), data(0), | 308 : inst(_inst), req(NULL), size(0), |
307 canWB(0), committed(0), completed(0) | 309 canWB(0), committed(0), completed(0) |
308 { } | 310 { 311 bzero(data, sizeof(data)); 312 } |
309 310 /** The store instruction. */ 311 DynInstPtr inst; 312 /** The request for the store. */ 313 RequestPtr req; 314 /** The size of the store. */ 315 int size; 316 /** The store data. */ | 313 314 /** The store instruction. */ 315 DynInstPtr inst; 316 /** The request for the store. */ 317 RequestPtr req; 318 /** The size of the store. */ 319 int size; 320 /** The store data. */ |
317 IntReg data; | 321 char data[sizeof(IntReg)]; |
318 /** Whether or not the store can writeback. */ 319 bool canWB; 320 /** Whether or not the store is committed. */ 321 bool committed; 322 /** Whether or not the store is completed. */ 323 bool completed; 324 }; 325 --- 231 unchanged lines hidden (view full) --- 557 bool upper_load_has_store_part = 558 (req->getVaddr() + req->getSize()) > 559 storeQueue[store_idx].inst->effAddr; 560 561 // If the store's data has all of the data needed, we can forward. 562 if ((store_has_lower_limit && store_has_upper_limit)) { 563 // Get shift amount for offset into the store's data. 564 int shift_amt = req->getVaddr() & (store_size - 1); | 322 /** Whether or not the store can writeback. */ 323 bool canWB; 324 /** Whether or not the store is committed. */ 325 bool committed; 326 /** Whether or not the store is completed. */ 327 bool completed; 328 }; 329 --- 231 unchanged lines hidden (view full) --- 561 bool upper_load_has_store_part = 562 (req->getVaddr() + req->getSize()) > 563 storeQueue[store_idx].inst->effAddr; 564 565 // If the store's data has all of the data needed, we can forward. 566 if ((store_has_lower_limit && store_has_upper_limit)) { 567 // Get shift amount for offset into the store's data. 568 int shift_amt = req->getVaddr() & (store_size - 1); |
565 // @todo: Magic number, assumes byte addressing 566 shift_amt = shift_amt << 3; | |
567 | 569 |
568 // Cast this to type T? 569 data = storeQueue[store_idx].data >> shift_amt; | 570 memcpy(&data, storeQueue[store_idx].data + shift_amt, sizeof(T)); |
570 | 571 |
571 // When the data comes from the store queue entry, it's in host 572 // order. When it gets sent to the load, it needs to be in guest 573 // order so when the load converts it again, it ends up back 574 // in host order like the inst expects. 575 data = TheISA::htog(data); 576 | |
577 assert(!load_inst->memData); 578 load_inst->memData = new uint8_t[64]; 579 | 572 assert(!load_inst->memData); 573 load_inst->memData = new uint8_t[64]; 574 |
580 memcpy(load_inst->memData, &data, req->getSize()); | 575 memcpy(load_inst->memData, 576 storeQueue[store_idx].data + shift_amt, req->getSize()); |
581 582 DPRINTF(LSQUnit, "Forwarding from store idx %i to load to " 583 "addr %#x, data %#x\n", 584 store_idx, req->getVaddr(), data); 585 586 PacketPtr data_pkt = new Packet(req, MemCmd::ReadReq, 587 Packet::Broadcast); 588 data_pkt->dataStatic(load_inst->memData); --- 130 unchanged lines hidden (view full) --- 719 720 DPRINTF(LSQUnit, "Doing write to store idx %i, addr %#x data %#x" 721 " | storeHead:%i [sn:%i]\n", 722 store_idx, req->getPaddr(), data, storeHead, 723 storeQueue[store_idx].inst->seqNum); 724 725 storeQueue[store_idx].req = req; 726 storeQueue[store_idx].size = sizeof(T); | 577 578 DPRINTF(LSQUnit, "Forwarding from store idx %i to load to " 579 "addr %#x, data %#x\n", 580 store_idx, req->getVaddr(), data); 581 582 PacketPtr data_pkt = new Packet(req, MemCmd::ReadReq, 583 Packet::Broadcast); 584 data_pkt->dataStatic(load_inst->memData); --- 130 unchanged lines hidden (view full) --- 715 716 DPRINTF(LSQUnit, "Doing write to store idx %i, addr %#x data %#x" 717 " | storeHead:%i [sn:%i]\n", 718 store_idx, req->getPaddr(), data, storeHead, 719 storeQueue[store_idx].inst->seqNum); 720 721 storeQueue[store_idx].req = req; 722 storeQueue[store_idx].size = sizeof(T); |
727 storeQueue[store_idx].data = data; | 723 assert(sizeof(T) <= sizeof(storeQueue[store_idx].data)); |
728 | 724 |
725 T gData = htog(data); 726 memcpy(storeQueue[store_idx].data, &gData, sizeof(T)); 727 |
|
729 // This function only writes the data to the store queue, so no fault 730 // can happen here. 731 return NoFault; 732} 733 734#endif // __CPU_O3_LSQ_UNIT_HH__ | 728 // This function only writes the data to the store queue, so no fault 729 // can happen here. 730 return NoFault; 731} 732 733#endif // __CPU_O3_LSQ_UNIT_HH__ |