lsq_unit.hh (4329:52057dbec096) | lsq_unit.hh (4332:548ef28989b8) |
---|---|
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; --- 275 unchanged lines hidden (view full) --- 284 /** The pointer to the LSQ unit that issued the store. */ 285 LSQUnit<Impl> *lsqPtr; 286 }; 287 288 public: 289 struct SQEntry { 290 /** Constructs an empty store queue entry. */ 291 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; --- 275 unchanged lines hidden (view full) --- 284 /** The pointer to the LSQ unit that issued the store. */ 285 LSQUnit<Impl> *lsqPtr; 286 }; 287 288 public: 289 struct SQEntry { 290 /** Constructs an empty store queue entry. */ 291 SQEntry() |
292 : inst(NULL), req(NULL), size(0), data(0), | 292 : inst(NULL), req(NULL), size(0), |
293 canWB(0), committed(0), completed(0) | 293 canWB(0), committed(0), completed(0) |
294 { } | 294 { 295 bzero(data, sizeof(data)); 296 } |
295 296 /** Constructs a store queue entry for a given instruction. */ 297 SQEntry(DynInstPtr &_inst) | 297 298 /** Constructs a store queue entry for a given instruction. */ 299 SQEntry(DynInstPtr &_inst) |
298 : inst(_inst), req(NULL), size(0), data(0), | 300 : inst(_inst), req(NULL), size(0), |
299 canWB(0), committed(0), completed(0) | 301 canWB(0), committed(0), completed(0) |
300 { } | 302 { 303 bzero(data, sizeof(data)); 304 } |
301 302 /** The store instruction. */ 303 DynInstPtr inst; 304 /** The request for the store. */ 305 RequestPtr req; 306 /** The size of the store. */ 307 int size; 308 /** The store data. */ | 305 306 /** The store instruction. */ 307 DynInstPtr inst; 308 /** The request for the store. */ 309 RequestPtr req; 310 /** The size of the store. */ 311 int size; 312 /** The store data. */ |
309 IntReg data; | 313 char data[sizeof(IntReg)]; |
310 /** Whether or not the store can writeback. */ 311 bool canWB; 312 /** Whether or not the store is committed. */ 313 bool committed; 314 /** Whether or not the store is completed. */ 315 bool completed; 316 }; 317 --- 231 unchanged lines hidden (view full) --- 549 bool upper_load_has_store_part = 550 (req->getVaddr() + req->getSize()) > 551 storeQueue[store_idx].inst->effAddr; 552 553 // If the store's data has all of the data needed, we can forward. 554 if ((store_has_lower_limit && store_has_upper_limit)) { 555 // Get shift amount for offset into the store's data. 556 int shift_amt = req->getVaddr() & (store_size - 1); | 314 /** Whether or not the store can writeback. */ 315 bool canWB; 316 /** Whether or not the store is committed. */ 317 bool committed; 318 /** Whether or not the store is completed. */ 319 bool completed; 320 }; 321 --- 231 unchanged lines hidden (view full) --- 553 bool upper_load_has_store_part = 554 (req->getVaddr() + req->getSize()) > 555 storeQueue[store_idx].inst->effAddr; 556 557 // If the store's data has all of the data needed, we can forward. 558 if ((store_has_lower_limit && store_has_upper_limit)) { 559 // Get shift amount for offset into the store's data. 560 int shift_amt = req->getVaddr() & (store_size - 1); |
557 // @todo: Magic number, assumes byte addressing 558 shift_amt = shift_amt << 3; | |
559 | 561 |
560 // Cast this to type T? 561 data = storeQueue[store_idx].data >> shift_amt; | 562 memcpy(&data, storeQueue[store_idx].data + shift_amt, sizeof(T)); |
562 | 563 |
563 // When the data comes from the store queue entry, it's in host 564 // order. When it gets sent to the load, it needs to be in guest 565 // order so when the load converts it again, it ends up back 566 // in host order like the inst expects. 567 data = TheISA::htog(data); 568 | |
569 assert(!load_inst->memData); 570 load_inst->memData = new uint8_t[64]; 571 | 564 assert(!load_inst->memData); 565 load_inst->memData = new uint8_t[64]; 566 |
572 memcpy(load_inst->memData, &data, req->getSize()); | 567 memcpy(load_inst->memData, 568 storeQueue[store_idx].data + shift_amt, req->getSize()); |
573 574 DPRINTF(LSQUnit, "Forwarding from store idx %i to load to " 575 "addr %#x, data %#x\n", 576 store_idx, req->getVaddr(), data); 577 578 PacketPtr data_pkt = new Packet(req, MemCmd::ReadReq, 579 Packet::Broadcast); 580 data_pkt->dataStatic(load_inst->memData); --- 130 unchanged lines hidden (view full) --- 711 712 DPRINTF(LSQUnit, "Doing write to store idx %i, addr %#x data %#x" 713 " | storeHead:%i [sn:%i]\n", 714 store_idx, req->getPaddr(), data, storeHead, 715 storeQueue[store_idx].inst->seqNum); 716 717 storeQueue[store_idx].req = req; 718 storeQueue[store_idx].size = sizeof(T); | 569 570 DPRINTF(LSQUnit, "Forwarding from store idx %i to load to " 571 "addr %#x, data %#x\n", 572 store_idx, req->getVaddr(), data); 573 574 PacketPtr data_pkt = new Packet(req, MemCmd::ReadReq, 575 Packet::Broadcast); 576 data_pkt->dataStatic(load_inst->memData); --- 130 unchanged lines hidden (view full) --- 707 708 DPRINTF(LSQUnit, "Doing write to store idx %i, addr %#x data %#x" 709 " | storeHead:%i [sn:%i]\n", 710 store_idx, req->getPaddr(), data, storeHead, 711 storeQueue[store_idx].inst->seqNum); 712 713 storeQueue[store_idx].req = req; 714 storeQueue[store_idx].size = sizeof(T); |
719 storeQueue[store_idx].data = data; | 715 assert(sizeof(T) <= sizeof(storeQueue[store_idx].data)); |
720 | 716 |
717 T gData = htog(data); 718 memcpy(storeQueue[store_idx].data, &gData, sizeof(T)); 719 |
|
721 // This function only writes the data to the store queue, so no fault 722 // can happen here. 723 return NoFault; 724} 725 726#endif // __CPU_O3_LSQ_UNIT_HH__ | 720 // This function only writes the data to the store queue, so no fault 721 // can happen here. 722 return NoFault; 723} 724 725#endif // __CPU_O3_LSQ_UNIT_HH__ |