sim: Get rid of the IsConforming type trait template.
authorGabe Black <gabe.black@gmail.com>
Wed, 3 Feb 2021 03:03:56 +0000 (19:03 -0800)
committerGabe Black <gabe.black@gmail.com>
Tue, 9 Feb 2021 00:36:00 +0000 (00:36 +0000)
The idea of this template was to distinguish types which should
grow/shrink based on the native size of the ABI in question. Or in other
words, if the ABI was 32 bit, the type should also be 32 bit, or 64 bit
and 64 bit.

Unfortunately, I had intended for Addr to be a conforming type (since
local pointers would be conforming), but uint64_t not to be. Since Addr
is defined as a typedef of uint64_t, the compiler would make *both*
types conforming, giving incorrect behavior on 32 bit systems.

Local pointers will need to be handled in a different way, likely with
the VPtr template, so that they will be treated correctly and not like
an explicitly 64 bit data type.

Change-Id: Idfdd5351260b48bb531a1926b93e0478a297826d
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/40495
Reviewed-by: Gabe Black <gabe.black@gmail.com>
Maintainer: Gabe Black <gabe.black@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/arch/arm/aapcs32.hh
src/arch/arm/reg_abi.hh
src/arch/sparc/se_workload.hh
src/arch/x86/linux/se_workload.hh
src/sim/syscall_abi.hh

index a0f09b87b69cf9d557755e9e0be466fece090f13..a1345bd571191097f9077b119961370a8f17d06d 100644 (file)
@@ -160,9 +160,7 @@ struct Result<Aapcs32, Integer, typename std::enable_if_t<
     static void
     store(ThreadContext *tc, const Integer &i)
     {
-        if (std::is_same<Integer, Addr>::value) {
-            tc->setIntReg(ArmISA::INTREG_R0, (uint32_t)i);
-        } else if (ArmISA::byteOrder(tc) == ByteOrder::little) {
+        if (ArmISA::byteOrder(tc) == ByteOrder::little) {
             tc->setIntReg(ArmISA::INTREG_R0, (uint32_t)(i >> 0));
             tc->setIntReg(ArmISA::INTREG_R1, (uint32_t)(i >> 32));
         } else {
@@ -199,11 +197,6 @@ struct Argument<Aapcs32, Integer, typename std::enable_if_t<
     static Integer
     get(ThreadContext *tc, Aapcs32::State &state)
     {
-        if (std::is_same<Integer, Addr>::value &&
-                state.ncrn <= state.MAX_CRN) {
-            return tc->readIntReg(state.ncrn++);
-        }
-
         if (alignof(Integer) == 8 && (state.ncrn % 2))
             state.ncrn++;
 
index eb87eff776dfd1382ac1c7f0bf336ef60c0e683d..94dea18cf0d6f93f6ef7f4fedd36c9a9c026dba0 100644 (file)
@@ -55,6 +55,7 @@ template <typename ABI, typename Arg>
 struct Argument<ABI, Arg,
     typename std::enable_if_t<
         std::is_base_of<ArmISA::RegABI32, ABI>::value &&
+        std::is_integral<Arg>::value &&
         ABI::template IsWide<Arg>::value>>
 {
     static Arg
index e39261dc5ad064864784b5a786c63c8b9fabda76..7303010d889c5b78c792519c666cca48b9944860 100644 (file)
@@ -105,6 +105,7 @@ struct Result<ABI, SyscallReturn,
 template <typename Arg>
 struct Argument<SparcISA::SEWorkload::SyscallABI32, Arg,
     typename std::enable_if_t<
+        std::is_integral<Arg>::value &&
         SparcISA::SEWorkload::SyscallABI32::IsWide<Arg>::value>>
 {
     using ABI = SparcISA::SEWorkload::SyscallABI32;
index c1cd2341a0c2449adc5bfeae93ec2361b7669198..cd26e04f4689f64573fe8696792bdb4dc36573d3 100644 (file)
@@ -93,7 +93,7 @@ namespace GuestABI
 
 template <typename Arg>
 struct Argument<X86ISA::EmuLinux::SyscallABI32, Arg,
-    typename std::enable_if_t<
+    typename std::enable_if_t<std::is_integral<Arg>::value &&
         X86ISA::EmuLinux::SyscallABI32::IsWide<Arg>::value>>
 {
     using ABI = X86ISA::EmuLinux::SyscallABI32;
index 9d552028f8453955a0af05817f88ab77545579bf..a60af425f887185e03294df9dd37f823c70c6d70 100644 (file)
 
 class SyscallDesc;
 
-namespace GuestABI
-{
-
-// Does this normally 64 bit data type shrink down to 32 bits for 32 bit ABIs?
-template <typename T, typename Enabled=void>
-struct IsConforming : public std::false_type {};
-
-template <>
-struct IsConforming<Addr> : public std::true_type {};
-
-} // namespace GuestABI
-
 struct GenericSyscallABI
 {
     using State = int;
@@ -64,25 +52,12 @@ struct GenericSyscallABI32 : public GenericSyscallABI
 
     // Is this argument too big for a single register?
     template <typename T, typename Enabled=void>
-    struct IsWide;
+    struct IsWide : public std::false_type {};
 
     template <typename T>
-    struct IsWide<T, typename std::enable_if_t<
-        std::is_integral<T>::value &&
-        (sizeof(T) <= sizeof(UintPtr) ||
-         GuestABI::IsConforming<T>::value)>>
-    {
-        static const bool value = false;
-    };
-
-    template <typename T>
-    struct IsWide<T, typename std::enable_if_t<
-        std::is_integral<T>::value &&
-        (sizeof(T) > sizeof(UintPtr)) &&
-        !GuestABI::IsConforming<T>::value>>
-    {
-        static const bool value = true;
-    };
+    struct IsWide<T, std::enable_if_t<(sizeof(T) > sizeof(UintPtr))>> :
+        public std::true_type
+    {};
 
     // Read two registers and merge them into one value.
     static uint64_t
@@ -117,7 +92,8 @@ struct Argument<ABI, Arg,
 // arguments aren't handled generically.
 template <typename ABI, typename Arg>
 struct Argument<ABI, Arg,
-    typename std::enable_if_t<!ABI::template IsWide<Arg>::value>>
+    typename std::enable_if_t<std::is_integral<Arg>::value &&
+        !ABI::template IsWide<Arg>::value>>
 {
     static Arg
     get(ThreadContext *tc, typename ABI::State &state)