Made sure the constructor for insts use ExtMachInst rather than MachInst, since other...
[gem5.git] / src / sim / byteswap.hh
index c7abc4bff313f925eac8ec518e4fae0f810bc62a..7648b8fcd23ffec32515541a1fc056ca4cf99e76 100644 (file)
@@ -25,7 +25,8 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * Authors: Ali Saidi
+ * Authors: Gabe Black
+ *          Ali Saidi
  *          Nathan Binkert
  */
 
@@ -36,6 +37,7 @@
 #ifndef __SIM_BYTE_SWAP_HH__
 #define __SIM_BYTE_SWAP_HH__
 
+#include "base/misc.hh"
 #include "sim/host.hh"
 
 // This lets us figure out what the byte order of the host system is
 #include <machine/endian.h>
 #endif
 
+#if defined(__APPLE__)
+#include <libkern/OSByteOrder.h>
+#endif
+
 //These functions actually perform the swapping for parameters
 //of various bit lengths
 static inline uint64_t
@@ -56,6 +62,8 @@ swap_byte64(uint64_t x)
 {
 #if defined(linux)
     return bswap_64(x);
+#elif defined(__APPLE__)
+    return OSSwapInt64(x);
 #else
     return  (uint64_t)((((uint64_t)(x) & 0xff) << 56) |
             ((uint64_t)(x) & 0xff00ULL) << 40 |
@@ -73,6 +81,8 @@ swap_byte32(uint32_t x)
 {
 #if defined(linux)
     return bswap_32(x);
+#elif defined(__APPLE__)
+    return OSSwapInt32(x);
 #else
     return  (uint32_t)(((uint32_t)(x) & 0xff) << 24 |
             ((uint32_t)(x) & 0xff00) << 8 | ((uint32_t)(x) & 0xff0000) >> 8 |
@@ -85,31 +95,31 @@ swap_byte16(uint16_t x)
 {
 #if defined(linux)
     return bswap_16(x);
+#elif defined(__APPLE__)
+    return OSSwapInt16(x);
 #else
     return (uint16_t)(((uint16_t)(x) & 0xff) << 8 |
                       ((uint16_t)(x) & 0xff00) >> 8);
 #endif
 }
 
-//This lets the compiler figure out how to call the swap_byte functions above
-//for different data types.
-static inline uint64_t swap_byte(uint64_t x) {return swap_byte64(x);}
-static inline int64_t swap_byte(int64_t x) {return swap_byte64((uint64_t)x);}
-static inline uint32_t swap_byte(uint32_t x) {return swap_byte32(x);}
-static inline int32_t swap_byte(int32_t x) {return swap_byte32((uint32_t)x);}
-//This is to prevent the following two functions from compiling on
-//64bit machines. It won't detect everything, so it should be changed.
-#ifndef __x86_64__
-static inline long swap_byte(long x) {return swap_byte32((long)x);}
-static inline unsigned long swap_byte(unsigned long x)
-                                { return swap_byte32((unsigned long)x);}
-#endif
-static inline uint16_t swap_byte(uint16_t x) {return swap_byte32(x);}
-static inline int16_t swap_byte(int16_t x) {return swap_byte16((uint16_t)x);}
-static inline uint8_t swap_byte(uint8_t x) {return x;}
-static inline int8_t swap_byte(int8_t x) {return x;}
-static inline double swap_byte(double x) {return swap_byte64((uint64_t)x);}
-static inline float swap_byte(float x) {return swap_byte32((uint32_t)x);}
+// This function lets the compiler figure out how to call the
+// swap_byte functions above for different data types.  Since the
+// sizeof() values are known at compiel time, it should inline to a
+// direct call to the right swap_byteNN() function.
+template <typename T>
+static inline T swap_byte(T x) {
+    if (sizeof(T) == 8)
+        return swap_byte64((uint64_t)x);
+    else if (sizeof(T) == 4)
+        return swap_byte32((uint32_t)x);
+    else if (sizeof(T) == 2)
+        return swap_byte16((uint16_t)x);
+    else if (sizeof(T) == 1)
+        return x;
+    else
+        panic("Can't byte-swap values larger than 64 bits");
+}
 
 //The conversion functions with fixed endianness on both ends don't need to
 //be in a namespace