lsq_unit.hh (4326:a9277254c1e4) lsq_unit.hh (4329:52057dbec096)
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;

--- 59 unchanged lines hidden (view full) ---

68 typedef typename Impl::CPUPol::LSQ LSQ;
69 typedef typename Impl::CPUPol::IssueStruct IssueStruct;
70
71 public:
72 /** Constructs an LSQ unit. init() must be called prior to use. */
73 LSQUnit();
74
75 /** Initializes the LSQ unit with the specified number of entries. */
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;

--- 59 unchanged lines hidden (view full) ---

68 typedef typename Impl::CPUPol::LSQ LSQ;
69 typedef typename Impl::CPUPol::IssueStruct IssueStruct;
70
71 public:
72 /** Constructs an LSQ unit. init() must be called prior to use. */
73 LSQUnit();
74
75 /** Initializes the LSQ unit with the specified number of entries. */
76 void init(Params *params, LSQ *lsq_ptr, unsigned maxLQEntries,
77 unsigned maxSQEntries, unsigned id);
76 void init(O3CPU *cpu_ptr, IEW *iew_ptr, Params *params, LSQ *lsq_ptr,
77 unsigned maxLQEntries, unsigned maxSQEntries, unsigned id);
78
79 /** Returns the name of the LSQ unit. */
80 std::string name() const;
81
82 /** Registers statistics. */
83 void regStats();
84
78
79 /** Returns the name of the LSQ unit. */
80 std::string name() const;
81
82 /** Registers statistics. */
83 void regStats();
84
85 /** Sets the CPU pointer. */
86 void setCPU(O3CPU *cpu_ptr);
87
88 /** Sets the IEW stage pointer. */
89 void setIEW(IEW *iew_ptr)
90 { iewStage = iew_ptr; }
91
92 /** Sets the pointer to the dcache port. */
85 /** Sets the pointer to the dcache port. */
93 void setDcachePort(Port *dcache_port)
94 { dcachePort = dcache_port; }
86 void setDcachePort(Port *dcache_port);
95
96 /** Switches out LSQ unit. */
97 void switchOut();
98
99 /** Takes over from another CPU's thread. */
100 void takeOverFrom();
101
102 /** Returns if the LSQ is switched out. */

--- 189 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()
87
88 /** Switches out LSQ unit. */
89 void switchOut();
90
91 /** Takes over from another CPU's thread. */
92 void takeOverFrom();
93
94 /** Returns if the LSQ is switched out. */

--- 189 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()
300 : inst(NULL), req(NULL), size(0),
292 : inst(NULL), req(NULL), size(0), data(0),
301 canWB(0), committed(0), completed(0)
293 canWB(0), committed(0), completed(0)
302 {
303 bzero(data, sizeof(data));
304 }
294 { }
305
306 /** Constructs a store queue entry for a given instruction. */
307 SQEntry(DynInstPtr &_inst)
295
296 /** Constructs a store queue entry for a given instruction. */
297 SQEntry(DynInstPtr &_inst)
308 : inst(_inst), req(NULL), size(0),
298 : inst(_inst), req(NULL), size(0), data(0),
309 canWB(0), committed(0), completed(0)
299 canWB(0), committed(0), completed(0)
310 {
311 bzero(data, sizeof(data));
312 }
300 { }
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. */
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. */
321 char data[sizeof(IntReg)];
309 IntReg data;
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);
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);
557 // @todo: Magic number, assumes byte addressing
558 shift_amt = shift_amt << 3;
569
559
570 memcpy(&data, storeQueue[store_idx].data + shift_amt, sizeof(T));
560 // Cast this to type T?
561 data = storeQueue[store_idx].data >> shift_amt;
571
562
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
572 assert(!load_inst->memData);
573 load_inst->memData = new uint8_t[64];
574
569 assert(!load_inst->memData);
570 load_inst->memData = new uint8_t[64];
571
575 memcpy(load_inst->memData,
576 storeQueue[store_idx].data + shift_amt, req->getSize());
572 memcpy(load_inst->memData, &data, req->getSize());
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);
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);
723 assert(sizeof(T) <= sizeof(storeQueue[store_idx].data));
719 storeQueue[store_idx].data = data;
724
720
725 T gData = htog(data);
726 memcpy(storeQueue[store_idx].data, &gData, sizeof(T));
727
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__
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__