diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa index 5ff4f0cead..a3d9c5a706 100644 --- a/src/arch/x86/isa/microops/ldstop.isa +++ b/src/arch/x86/isa/microops/ldstop.isa @@ -99,8 +99,7 @@ def template MicroLoadExecute {{ %(ea_code)s; DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); - fault = readMemAtomic(xc, traceData, EA, Mem, - %(memDataSize)s, memFlags); + fault = readMemAtomic(xc, traceData, EA, Mem, dataSize, memFlags); if (fault == NoFault) { %(code)s; @@ -145,7 +144,7 @@ def template MicroLoadCompleteAcc {{ %(op_decl)s; %(op_rd)s; - getMem(pkt, Mem, %(memDataSize)s, traceData); + getMem(pkt, Mem, dataSize, traceData); %(code)s; @@ -174,12 +173,10 @@ def template MicroStoreExecute {{ %(code)s; - if(fault == NoFault) - { - fault = writeMemAtomic(xc, traceData, Mem, %(memDataSize)s, EA, - memFlags, NULL); - if(fault == NoFault) - { + if (fault == NoFault) { + fault = writeMemAtomic(xc, traceData, Mem, dataSize, EA, + memFlags, NULL); + if (fault == NoFault) { %(op_wb)s; } } @@ -202,10 +199,9 @@ def template MicroStoreInitiateAcc {{ %(code)s; - if(fault == NoFault) - { - fault = writeMemTiming(xc, traceData, Mem, %(memDataSize)s, EA, - memFlags, NULL); + if (fault == NoFault) { + fault = writeMemTiming(xc, traceData, Mem, dataSize, EA, + memFlags, NULL); } return fault; } @@ -561,18 +557,9 @@ let {{ microopClasses[name] = LoadOp code = ''' - switch (dataSize) { - case 4: - DataLow = bits(Mem_u2qw[0], 31, 0); - DataHi = bits(Mem_u2qw[0], 63, 32); - break; - case 8: - DataLow = Mem_u2qw[0]; - DataHi = Mem_u2qw[1]; - break; - default: - panic("Unhandled data size %d in LdSplit.\\n", dataSize); - }''' + DataLow = Mem_u2qw[0]; + DataHi = Mem_u2qw[1]; + ''' defineMicroLoadSplitOp('LdSplit', code, '(StoreCheck << FlagShift)') @@ -683,17 +670,9 @@ let {{ microopClasses[name] = StoreOp code = ''' - switch (dataSize) { - case 4: - Mem_u2qw[0] = (DataHi << 32) | DataLow; - break; - case 8: - Mem_u2qw[0] = DataLow; - Mem_u2qw[1] = DataHi; - break; - default: - panic("Unhandled data size %d in StSplit.\\n", dataSize); - }''' + Mem_u2qw[0] = DataLow; + Mem_u2qw[1] = DataHi; + ''' defineMicroStoreSplitOp('StSplit', code); diff --git a/src/arch/x86/memhelpers.hh b/src/arch/x86/memhelpers.hh index 00a6e9a338..aa3617b43b 100644 --- a/src/arch/x86/memhelpers.hh +++ b/src/arch/x86/memhelpers.hh @@ -74,24 +74,30 @@ getMem(PacketPtr pkt, uint64_t &mem, unsigned dataSize, traceData->setData(mem); } +template +static void +getPackedMem(PacketPtr pkt, std::array &mem, unsigned dataSize) +{ + std::array real_mem = pkt->get >(); + for (int i = 0; i < N; i++) + mem[i] = real_mem[i]; +} template -void +static void getMem(PacketPtr pkt, std::array &mem, unsigned dataSize, Trace::InstRecord *traceData) { - assert(dataSize >= 8); - assert((dataSize % 8) == 0); - - int num_words = dataSize / 8; - assert(num_words <= N); - - auto pkt_data = pkt->getConstPtr(); - for (int i = 0; i < num_words; ++i) - mem[i] = gtoh(pkt_data[i]); - - // traceData record only has space for 64 bits, so we just record - // the first qword + switch (dataSize) { + case 4: + getPackedMem(pkt, mem, dataSize); + break; + case 8: + getPackedMem(pkt, mem, dataSize); + break; + default: + panic("Unhandled element size in getMem.\n"); + } if (traceData) traceData->setData(mem[0]); } @@ -114,62 +120,86 @@ readMemAtomic(ExecContext *xc, Trace::InstRecord *traceData, Addr addr, return fault; } +template +static Fault +readPackedMemAtomic(ExecContext *xc, Addr addr, std::array &mem, + unsigned flags) +{ + std::array real_mem; + Fault fault = xc->readMem(addr, (uint8_t *)&real_mem, + sizeof(T) * N, flags); + if (fault == NoFault) { + real_mem = gtoh(real_mem); + for (int i = 0; i < N; i++) + mem[i] = real_mem[i]; + } + return fault; +} + template -Fault +static Fault readMemAtomic(ExecContext *xc, Trace::InstRecord *traceData, Addr addr, std::array &mem, unsigned dataSize, unsigned flags) { - assert(dataSize >= 8); - assert((dataSize % 8) == 0); + Fault fault = NoFault; - Fault fault = xc->readMem(addr, (uint8_t *)&mem, dataSize, flags); - - if (fault == NoFault) { - int num_words = dataSize / 8; - assert(num_words <= N); - - for (int i = 0; i < num_words; ++i) - mem[i] = gtoh(mem[i]); - - if (traceData) - traceData->setData(mem[0]); + switch (dataSize) { + case 4: + fault = readPackedMemAtomic(xc, addr, mem, flags); + break; + case 8: + fault = readPackedMemAtomic(xc, addr, mem, flags); + break; + default: + panic("Unhandled element size in readMemAtomic\n"); } + if (fault == NoFault && traceData) + traceData->setData(mem[0]); return fault; } +template +static Fault +writePackedMem(ExecContext *xc, std::array &mem, Addr addr, + unsigned flags, uint64_t *res) +{ + std::array real_mem; + for (int i = 0; i < N; i++) + real_mem[i] = mem[i]; + real_mem = htog(real_mem); + return xc->writeMem((uint8_t *)&real_mem, sizeof(T) * N, + addr, flags, res); +} + static Fault writeMemTiming(ExecContext *xc, Trace::InstRecord *traceData, uint64_t mem, unsigned dataSize, Addr addr, Request::Flags flags, uint64_t *res) { - if (traceData) { + if (traceData) traceData->setData(mem); - } mem = TheISA::htog(mem); return xc->writeMem((uint8_t *)&mem, dataSize, addr, flags, res); } template -Fault +static Fault writeMemTiming(ExecContext *xc, Trace::InstRecord *traceData, std::array &mem, unsigned dataSize, Addr addr, unsigned flags, uint64_t *res) { - assert(dataSize >= 8); - assert((dataSize % 8) == 0); - - if (traceData) { + if (traceData) traceData->setData(mem[0]); + + switch (dataSize) { + case 4: + return writePackedMem(xc, mem, addr, flags, res); + case 8: + return writePackedMem(xc, mem, addr, flags, res); + default: + panic("Unhandled element size in writeMemTiming.\n"); } - - int num_words = dataSize / 8; - assert(num_words <= N); - - for (int i = 0; i < num_words; ++i) - mem[i] = htog(mem[i]); - - return xc->writeMem((uint8_t *)&mem, dataSize, addr, flags, res); } static Fault @@ -177,39 +207,39 @@ writeMemAtomic(ExecContext *xc, Trace::InstRecord *traceData, uint64_t mem, unsigned dataSize, Addr addr, Request::Flags flags, uint64_t *res) { - if (traceData) { + if (traceData) traceData->setData(mem); - } uint64_t host_mem = TheISA::htog(mem); Fault fault = xc->writeMem((uint8_t *)&host_mem, dataSize, addr, flags, res); - if (fault == NoFault && res != NULL) { + if (fault == NoFault && res) *res = gtoh(*res); - } return fault; } template -Fault +static Fault writeMemAtomic(ExecContext *xc, Trace::InstRecord *traceData, std::array &mem, unsigned dataSize, Addr addr, unsigned flags, uint64_t *res) { - if (traceData) { + if (traceData) traceData->setData(mem[0]); + + Fault fault; + switch (dataSize) { + case 4: + fault = writePackedMem(xc, mem, addr, flags, res); + break; + case 8: + fault = writePackedMem(xc, mem, addr, flags, res); + break; + default: + panic("Unhandled element size in writeMemAtomic.\n"); } - int num_words = dataSize / 8; - assert(num_words <= N); - - for (int i = 0; i < num_words; ++i) - mem[i] = htog(mem[i]); - - Fault fault = xc->writeMem((uint8_t *)&mem, dataSize, addr, flags, res); - - if (fault == NoFault && res != NULL) { + if (fault == NoFault && res) *res = gtoh(*res); - } return fault; }