diff options
author | Andreas Sandberg <andreas.sandberg@arm.com> | 2018-03-06 15:36:33 +0000 |
---|---|---|
committer | Andreas Sandberg <andreas.sandberg@arm.com> | 2018-04-17 08:45:12 +0000 |
commit | 7c21795304e6ec79ed8c35873c4419a6342eb1e3 (patch) | |
tree | 9377024c6fad1d4eb05c1e3be4557c5dd031b950 | |
parent | 8e7fdf4ac460cbfbb373c951a6c7cdae93446241 (diff) | |
download | gem5-7c21795304e6ec79ed8c35873c4419a6342eb1e3.tar.xz |
mem: Add a helper function to get a word of variable length
There are many devices that need to handle reads/writes of different
word sizes. A common pattern is a switch statement that check for the
size of a packet and then calls the corresponding
Packet::(get|set)<uintXX_t> methods. Simplify this by implementing
Packet::(get|set)UintX helper functions.
The getter reads a word of the size specified in the packet and the
specified endianness. The word is then zero-extended to 64
bits. Conversely, the setter truncates the word down to the size
required in the packet and then byte-swaps it to the desired
endianness.
Change-Id: I2f0c27fe3903abf3859bea13b07c7f5f0fb0809f
Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/9761
Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com>
-rw-r--r-- | src/mem/packet.cc | 42 | ||||
-rw-r--r-- | src/mem/packet.hh | 16 |
2 files changed, 56 insertions, 2 deletions
diff --git a/src/mem/packet.cc b/src/mem/packet.cc index ffda3d5af..7a81cdbb7 100644 --- a/src/mem/packet.cc +++ b/src/mem/packet.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2017 ARM Limited + * Copyright (c) 2011-2018 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -56,6 +56,7 @@ #include "base/cprintf.hh" #include "base/logging.hh" #include "base/trace.hh" +#include "mem/packet_access.hh" using namespace std; @@ -364,6 +365,45 @@ Packet::popSenderState() return sender_state; } +uint64_t +Packet::getUintX(ByteOrder endian) const +{ + switch(getSize()) { + case 1: + return (uint64_t)get<uint8_t>(endian); + case 2: + return (uint64_t)get<uint16_t>(endian); + case 4: + return (uint64_t)get<uint32_t>(endian); + case 8: + return (uint64_t)get<uint64_t>(endian); + default: + panic("%i isn't a supported word size.\n", getSize()); + } +} + +void +Packet::setUintX(uint64_t w, ByteOrder endian) +{ + switch(getSize()) { + case 1: + set<uint8_t>((uint8_t)w, endian); + break; + case 2: + set<uint16_t>((uint16_t)w, endian); + break; + case 4: + set<uint32_t>((uint32_t)w, endian); + break; + case 8: + set<uint64_t>((uint64_t)w, endian); + break; + default: + panic("%i isn't a supported word size.\n", getSize()); + } + +} + void Packet::print(ostream &o, const int verbosity, const string &prefix) const { diff --git a/src/mem/packet.hh b/src/mem/packet.hh index b5b882c91..a4eeabe29 100644 --- a/src/mem/packet.hh +++ b/src/mem/packet.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017 ARM Limited + * Copyright (c) 2012-2018 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -1068,6 +1068,20 @@ class Packet : public Printable template <typename T> void set(T v); + + /** + * Get the data in the packet byte swapped from the specified + * endianness and zero-extended to 64 bits. + */ + uint64_t getUintX(ByteOrder endian) const; + + /** + * Set the value in the word w after truncating it to the length + * of the packet and then byteswapping it to the desired + * endianness. + */ + void setUintX(uint64_t w, ByteOrder endian); + /** * Copy data into the packet from the provided pointer. */ |