[gem5-dev] Change in gem5/gem5[develop]: tests: Add unit tests for Virtual Memory Areas

2020-03-24 Thread Matthew Poremba (Gerrit)
Matthew Poremba has uploaded this change for review. (  
https://gem5-review.googlesource.com/c/public/gem5/+/27063 )



Change subject: tests: Add unit tests for Virtual Memory Areas
..

tests: Add unit tests for Virtual Memory Areas

Adds simple unit tests for Virtual Memory Areas and removes DPRINTFs
in order for the unit test to build.

Change-Id: I7702b9fd78af7d03ab5475c9b9e8b69e6a4bc918
---
M src/sim/SConscript
M src/sim/vma.cc
M src/sim/vma.hh
A src/sim/vma.test.cc
4 files changed, 96 insertions(+), 12 deletions(-)



diff --git a/src/sim/SConscript b/src/sim/SConscript
index 53239b8..7e3c381 100644
--- a/src/sim/SConscript
+++ b/src/sim/SConscript
@@ -78,6 +78,7 @@

 GTest('byteswap.test', 'byteswap.test.cc', '../base/types.cc')
 GTest('guest_abi.test', 'guest_abi.test.cc')
+GTest('vma.test', 'vma.test.cc', 'vma.cc')

 if env['TARGET_ISA'] != 'null':
 SimObject('InstTracer.py')
diff --git a/src/sim/vma.cc b/src/sim/vma.cc
index 6f6306c..88c8f59 100644
--- a/src/sim/vma.cc
+++ b/src/sim/vma.cc
@@ -64,9 +64,6 @@

 _addrRange = AddrRange(_addrRange.start(), slice_addr);

-DPRINTF(Vma, "slice right vma start %#x end %#x\n", _addrRange.start(),
-_addrRange.end());
-
 sanityCheck();
 }

@@ -89,9 +86,6 @@

 _addrRange = AddrRange(slice_addr, _addrRange.end());

-DPRINTF(Vma, "slice left vma start %#x end %#x\n", _addrRange.start(),
-_addrRange.end());
-
 sanityCheck();
 }

diff --git a/src/sim/vma.hh b/src/sim/vma.hh
index 3d5d104..a886a03 100644
--- a/src/sim/vma.hh
+++ b/src/sim/vma.hh
@@ -46,9 +46,6 @@
 int fd=-1, off_t off=0)
 : _addrRange(r), _pageBytes(page_bytes), _vmaName(vma_name)
 {
-DPRINTF(Vma, "Creating vma start %#x len %llu end %#x\n",
-r.start(), r.size(), r.end());
-
 if (fd != -1) {
 _origHostBuf =
 std::make_shared(fd, r.size(), off);
@@ -67,9 +64,6 @@
 {
 _addrRange = AddrRange(new_start, new_start + _addrRange.size());

-DPRINTF(Vma, "Remapping vma start %#x end %#x\n",  
_addrRange.start(),

-_addrRange.end());
-
 sanityCheck();
 }

diff --git a/src/sim/vma.test.cc b/src/sim/vma.test.cc
new file mode 100644
index 000..598f6b2
--- /dev/null
+++ b/src/sim/vma.test.cc
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2020 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include 
+
+#include "sim/vma.hh"
+
+/**
+ * The following tests check the VMA class.
+ * VMA objects hold information about process address space mappings.
+ * These objects are used in the syscall emulation source code.
+ */
+
+TEST(VMATest, EmptyVMADeath)
+{
+ASSERT_DEATH(VMA vma(AddrRange(0x0, 0x0), 4096), "");
+}
+
+TEST(VMATest, UnalignedRegionDeath)
+{
+ASSERT_DEATH(VMA vma(AddrRange(0x0D00, 0x7482), 4096), "");
+}
+
+TEST(VMATest, ExpandRightByPage)
+{
+VMA vma(AddrRange(0x1000, 0x2000), 4096);
+EXPECT_EQ(vma.size(), 0x1000);
+vma.sliceRegionRight(0x3000);
+EXPECT_EQ(vma.size(), 0x2000);
+}
+
+TEST(VMATest, ExpandLeftByPage)
+{
+VMA vma(AddrRange(0x1000, 0x2000), 4096);
+EXPECT_EQ(vma.size(), 0x1000);
+vma.sliceRegionLeft(0x0);
+EXPECT_EQ(vma.size(), 0x2000);
+}
+
+TEST(VMATest, ContractRightDeath)
+{
+VMA vma(AddrRange(0x1000, 0x2000), 4096);
+EXPECT_EQ(vma.size(), 0x1000);
+EXPECT_DEATH(vma.sliceRegionRight(0x1000), "");
+}
+
+TEST(

[gem5-dev] Change in gem5/gem5[develop]: power: Add the AT_RANDOM aux vector to the initial stack.

2020-03-24 Thread Gabe Black (Gerrit)
Gabe Black has submitted this change. (  
https://gem5-review.googlesource.com/c/public/gem5/+/26829 )


Change subject: power: Add the AT_RANDOM aux vector to the initial stack.
..

power: Add the AT_RANDOM aux vector to the initial stack.

This is blindly used by at least modern glibc-s

Change-Id: I8ee7872c8072ee8aa1b3718e988679968ac172d0
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/26829
Reviewed-by: Gabe Black 
Maintainer: Gabe Black 
Tested-by: kokoro 
---
M src/arch/power/process.cc
1 file changed, 8 insertions(+), 1 deletion(-)

Approvals:
  Gabe Black: Looks good to me, approved; Looks good to me, approved
  kokoro: Regressions pass



diff --git a/src/arch/power/process.cc b/src/arch/power/process.cc
index 6ebdd6f..9bb3b19 100644
--- a/src/arch/power/process.cc
+++ b/src/arch/power/process.cc
@@ -131,6 +131,8 @@
 auxv.emplace_back(M5_AT_EGID, egid());
 //Whether to enable "secure mode" in the executable
 auxv.emplace_back(M5_AT_SECURE, 0);
+//The address of 16 "random" bytes
+auxv.emplace_back(M5_AT_RANDOM, 0);
 //The filename of the program
 auxv.emplace_back(M5_AT_EXECFN, 0);
 //The string "v51" with unknown meaning
@@ -151,6 +153,9 @@
 // string.
 int aux_data_size = filename.size() + 1;

+const int numRandomBytes = 16;
+aux_data_size += numRandomBytes;
+
 int env_data_size = 0;
 for (int i = 0; i < envp.size(); ++i) {
 env_data_size += envp[i].size() + 1;
@@ -235,8 +240,10 @@
 auxv[i].val = platform_base;
 initVirtMem->writeString(platform_base, platform.c_str());
 } else if (auxv[i].type == M5_AT_EXECFN) {
-auxv[i].val = aux_data_base;
+auxv[i].val = aux_data_base + numRandomBytes;
 initVirtMem->writeString(aux_data_base, filename.c_str());
+} else if (auxv[i].type == M5_AT_RANDOM) {
+auxv[i].val = aux_data_base;
 }
 }


--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/26829
To unsubscribe, or for help writing mail filters, visit  
https://gem5-review.googlesource.com/settings


Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I8ee7872c8072ee8aa1b3718e988679968ac172d0
Gerrit-Change-Number: 26829
Gerrit-PatchSet: 4
Gerrit-Owner: Gabe Black 
Gerrit-Reviewer: Bobby R. Bruce 
Gerrit-Reviewer: Boris Shingarov 
Gerrit-Reviewer: Brandon Potter 
Gerrit-Reviewer: Gabe Black 
Gerrit-Reviewer: kokoro 
Gerrit-MessageType: merged
___
gem5-dev mailing list
gem5-dev@gem5.org
http://m5sim.org/mailman/listinfo/gem5-dev

[gem5-dev] Change in gem5/gem5[develop]: power: Hook up the readlink system call.

2020-03-24 Thread Gabe Black (Gerrit)
Gabe Black has submitted this change. (  
https://gem5-review.googlesource.com/c/public/gem5/+/26830 )


Change subject: power: Hook up the readlink system call.
..

power: Hook up the readlink system call.

Change-Id: I28dcbd6fb3c54479eefea26d810d10c00195cc08
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/26830
Tested-by: Gem5 Cloud Project GCB service account  
<345032938...@cloudbuild.gserviceaccount.com>

Reviewed-by: Gabe Black 
Maintainer: Gabe Black 
---
M src/arch/power/linux/process.cc
1 file changed, 1 insertion(+), 1 deletion(-)

Approvals:
  Gabe Black: Looks good to me, approved; Looks good to me, approved
  Gem5 Cloud Project GCB service account: Regressions pass



diff --git a/src/arch/power/linux/process.cc  
b/src/arch/power/linux/process.cc

index 710f88d..79c0a5e 100644
--- a/src/arch/power/linux/process.cc
+++ b/src/arch/power/linux/process.cc
@@ -177,7 +177,7 @@
 { 82, "reserved#82" },
 { 83, "symlink" },
 { 84, "unused#84" },
-{ 85, "readlink" },
+{ 85, "readlink", readlinkFunc },
 { 86, "uselib" },
 { 87, "swapon", gethostnameFunc },
 { 88, "reboot" },

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/26830
To unsubscribe, or for help writing mail filters, visit  
https://gem5-review.googlesource.com/settings


Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I28dcbd6fb3c54479eefea26d810d10c00195cc08
Gerrit-Change-Number: 26830
Gerrit-PatchSet: 4
Gerrit-Owner: Gabe Black 
Gerrit-Reviewer: Bobby R. Bruce 
Gerrit-Reviewer: Boris Shingarov 
Gerrit-Reviewer: Brandon Potter 
Gerrit-Reviewer: Gabe Black 
Gerrit-Reviewer: Gem5 Cloud Project GCB service account  
<345032938...@cloudbuild.gserviceaccount.com>

Gerrit-MessageType: merged
___
gem5-dev mailing list
gem5-dev@gem5.org
http://m5sim.org/mailman/listinfo/gem5-dev

[gem5-dev] Change in gem5/gem5[develop]: arm: Make the semihosting implementation use GuestABI.

2020-03-24 Thread Gabe Black (Gerrit)
Gabe Black has submitted this change. (  
https://gem5-review.googlesource.com/c/public/gem5/+/25946 )


Change subject: arm: Make the semihosting implementation use GuestABI.
..

arm: Make the semihosting implementation use GuestABI.

Remove the ability to not have an implementation for a semihosting call
in 32 or 64 bit mode since that was not actually being used. It can be
reintroduced if needed in the future.

Turn the physProxy helper function into a static function which
maintains a single secure port proxy. That makes the proxy available
outside of the ArmSemihosting class itself.

Change-Id: Ie99e7d79c08c039384250fab0c98117554c93128
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/25946
Tested-by: Gem5 Cloud Project GCB service account  
<345032938...@cloudbuild.gserviceaccount.com>

Tested-by: kokoro 
Reviewed-by: Giacomo Travaglini 
Maintainer: Giacomo Travaglini 
---
M src/arch/arm/isa/insts/misc.isa
M src/arch/arm/isa/insts/misc64.isa
M src/arch/arm/semihosting.cc
M src/arch/arm/semihosting.hh
M src/arch/arm/system.cc
M src/arch/arm/system.hh
6 files changed, 518 insertions(+), 327 deletions(-)

Approvals:
  Giacomo Travaglini: Looks good to me, approved; Looks good to me, approved
  kokoro: Regressions pass
  Gem5 Cloud Project GCB service account: Regressions pass



diff --git a/src/arch/arm/isa/insts/misc.isa  
b/src/arch/arm/isa/insts/misc.isa

index 396930f..88c473d 100644
--- a/src/arch/arm/isa/insts/misc.isa
+++ b/src/arch/arm/isa/insts/misc.isa
@@ -43,7 +43,7 @@
 const auto semihost_imm = Thumb? 0xAB : 0x123456;

 if (ArmSystem::haveSemihosting(tc) && imm == semihost_imm) {
-R0 = ArmSystem::callSemihosting32(tc, R0, R1);
+ArmSystem::callSemihosting32(tc);
 } else {
 fault = std::make_shared(machInst, imm);
 }
@@ -66,7 +66,7 @@
 const auto semihost_imm = Thumb? 0x3C : 0xF000;

 if (ArmSystem::haveSemihosting(tc) && imm == semihost_imm) {
-R0 = ArmSystem::callSemihosting32(tc, R0, R1);
+ArmSystem::callSemihosting32(tc);
 } else {
 // HLT instructions aren't implemented, so treat them as undefined
 // instructions.
@@ -80,7 +80,7 @@
  "predicate_test": predicateTest,
  "thumb_semihost": '0x3C',
  "arm_semihost": '0xF000' },
-   ["IsNonSpeculative"])
+   ["IsNonSpeculative", "IsSerializeAfter"])
 header_output += ImmOpDeclare.subst(hltIop)
 decoder_output += SemihostConstructor.subst(hltIop)
 exec_output += PredOpExecute.subst(hltIop)
diff --git a/src/arch/arm/isa/insts/misc64.isa  
b/src/arch/arm/isa/insts/misc64.isa

index 88c68e6..e2cfb41 100644
--- a/src/arch/arm/isa/insts/misc64.isa
+++ b/src/arch/arm/isa/insts/misc64.isa
@@ -186,7 +186,7 @@
 hltCode = '''
 ThreadContext *tc = xc->tcBase();
 if (ArmSystem::haveSemihosting(tc) && imm == 0xF000) {
-X0 = ArmSystem::callSemihosting64(tc, X0 & mask(32), X1);
+ArmSystem::callSemihosting64(tc);
 } else {
 // HLT instructions aren't implemented, so treat them as undefined
 // instructions.
@@ -197,7 +197,7 @@
 '''

 hltIop = InstObjParams("hlt", "Hlt64", "ImmOp64",
-   hltCode, ["IsNonSpeculative"])
+   hltCode,  
["IsNonSpeculative", "IsSerializeAfter"])

 header_output += ImmOp64Declare.subst(hltIop)
 decoder_output += SemihostConstructor64.subst(hltIop)
 exec_output += BasicExecute.subst(hltIop)
diff --git a/src/arch/arm/semihosting.cc b/src/arch/arm/semihosting.cc
index 4f897e2..5ea894a 100644
--- a/src/arch/arm/semihosting.cc
+++ b/src/arch/arm/semihosting.cc
@@ -52,39 +52,37 @@
 #include "sim/system.hh"

 const std::map ArmSemihosting::calls{
-{ SYS_OPEN, { "SYS_OPEN", &ArmSemihosting::callOpen, 3, 3 } },
-{ SYS_CLOSE,{ "SYS_CLOSE", &ArmSemihosting::callClose, 1, 1 } },
-
-// Write(C|0) are special since we want to read the character
-// manually. We therefore declare them as having 0 params.
-{ SYS_WRITEC,   { "SYS_WRITEC", &ArmSemihosting::callWriteC, 0, 0 } },
-{ SYS_WRITE0,   { "SYS_WRITE0", &ArmSemihosting::callWrite0, 1, 1 } },
-
-{ SYS_WRITE,{ "SYS_WRITE", &ArmSemihosting::callWrite, 3, 3 } },
-{ SYS_READ, { "SYS_READ", &ArmSemihosting::callRead, 3, 3 } },
-{ SYS_READC,{ "SYS_READC", &ArmSemihosting::callReadC, 0, 0 } },
-{ SYS_ISERROR,  { "SYS_ISERROR", &ArmSemihosting::callIsError, 1, 1 }  
},

-{ SYS_ISTTY,{ "SYS_ISTTY", &ArmSemihosting::callIsTTY, 1, 1 } },
-{ SYS_SEEK, { "SYS_SEEK", &ArmSemihosting::callSeek, 2, 2 } },
-{ SYS_FLEN, { "SYS_FLEN", &ArmSemihosting::callFLen, 1, 1 } },
-{ SYS_TMPNAM,   { "SYS_TMPNAM", &ArmSemihosting::callTmpNam, 3, 3 } },
-{ SYS_REMOVE,   { "SYS_REMOVE", &ArmSemihosting::callRemove, 

[gem5-dev] Change in gem5/gem5[develop]: arch-arm: Make load_addr_mask=0 for ArmFsLinux only

2020-03-24 Thread Giacomo Travaglini (Gerrit)
Giacomo Travaglini has submitted this change. (  
https://gem5-review.googlesource.com/c/public/gem5/+/27024 )


Change subject: arch-arm: Make load_addr_mask=0 for ArmFsLinux only
..

arch-arm: Make load_addr_mask=0 for ArmFsLinux only

This is restoring the situaton pre:

https://gem5-review.googlesource.com/c/public/gem5/+/26466

Where load_addr_mask was set to 0 (forcing the loader to discard
the kernel entry point) for LinuxArmSystem only.

With this patch the masking is done for ArmFsLinux workloads
only and it is using the default 0x (no masking)
for common ArmFsWorkload

Change-Id: I68970edcac61ad0de79433ffd84fef580a94b480
Signed-off-by: Giacomo Travaglini 
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/27024
Tested-by: Gem5 Cloud Project GCB service account  
<345032938...@cloudbuild.gserviceaccount.com>

Tested-by: kokoro 
Reviewed-by: Gabe Black 
---
M src/arch/arm/ArmFsWorkload.py
1 file changed, 2 insertions(+), 2 deletions(-)

Approvals:
  Gabe Black: Looks good to me, approved
  Giacomo Travaglini: Looks good to me, approved
  kokoro: Regressions pass
  Gem5 Cloud Project GCB service account: Regressions pass



diff --git a/src/arch/arm/ArmFsWorkload.py b/src/arch/arm/ArmFsWorkload.py
index 6064d81..459f830 100644
--- a/src/arch/arm/ArmFsWorkload.py
+++ b/src/arch/arm/ArmFsWorkload.py
@@ -50,8 +50,6 @@
 cxx_header = "arch/arm/fs_workload.hh"
 cxx_class = "ArmISA::FsWorkload"

-load_addr_mask = 0
-
 boot_loader = VectorParam.String([],
 "File that contains the boot loader code. Zero or more files may  
be "

 "specified. The first boot loader that matches the kernel's "
@@ -79,6 +77,8 @@
 cxx_header = "arch/arm/linux/fs_workload.hh"
 cxx_class = "ArmISA::FsLinux"

+load_addr_mask = 0
+
 @cxxMethod
 def dumpDmesg(self):
 """Dump dmesg from the simulated kernel to standard out"""

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/27024
To unsubscribe, or for help writing mail filters, visit  
https://gem5-review.googlesource.com/settings


Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I68970edcac61ad0de79433ffd84fef580a94b480
Gerrit-Change-Number: 27024
Gerrit-PatchSet: 5
Gerrit-Owner: Giacomo Travaglini 
Gerrit-Reviewer: Ciro Santilli 
Gerrit-Reviewer: Gabe Black 
Gerrit-Reviewer: Gem5 Cloud Project GCB service account  
<345032938...@cloudbuild.gserviceaccount.com>

Gerrit-Reviewer: Giacomo Travaglini 
Gerrit-Reviewer: kokoro 
Gerrit-MessageType: merged
___
gem5-dev mailing list
gem5-dev@gem5.org
http://m5sim.org/mailman/listinfo/gem5-dev

[gem5-dev] Change in gem5/gem5[develop]: arch-arm: Fix aapcs32/aapcs64 compilation issues

2020-03-24 Thread Giacomo Travaglini (Gerrit)
Giacomo Travaglini has submitted this change. (  
https://gem5-review.googlesource.com/c/public/gem5/+/26990 )


Change subject: arch-arm: Fix aapcs32/aapcs64 compilation issues
..

arch-arm: Fix aapcs32/aapcs64 compilation issues

Some compilers won't build ARM due to how guest ABI
has been implemented.

The error is: "left shift count >= width of type"
[-Werror=shift-count-overflow]

The error is triggered when there is a left shift > the variable size
(in bits); this leads to undefined behaviour.

This is a compile time vs run time problem; the code is technically
fine, but the compiler is not able to understand this.

For example in aapcs64:

struct Argument::value>::type> : public Aapcs64ArgumentBase
{
[...]
if (sizeof(Integer) == 16 && state.ngrn + 1 <= state.MAX_GRN) {
Integer low = tc->readIntReg(state.ngrn++);
Integer high = tc->readIntReg(state.ngrn++);
high = high << 64;
return high | low;
}
}

Even if the sizeof operator will be evaluated at compile time,
the block will be executed at runtime: the block will still be part of
the code if Integer = uint32_t.
The compiler will then throw an error because we are left shifting an
uint32_t by 64 bits.

Error arising on:
Compiler: gcc/5.4.0
Distro: Ubuntu 16.04 LTS

Change-Id: Iaafe030b7262c5fb162afe7118ae592a1a759a58
Signed-off-by: Giacomo Travaglini 
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/26990
Reviewed-by: Gabe Black 
Tested-by: kokoro 
---
M src/arch/arm/aapcs32.hh
M src/arch/arm/aapcs64.hh
2 files changed, 91 insertions(+), 27 deletions(-)

Approvals:
  Gabe Black: Looks good to me, approved
  Giacomo Travaglini: Looks good to me, approved
  kokoro: Regressions pass



diff --git a/src/arch/arm/aapcs32.hh b/src/arch/arm/aapcs32.hh
index bfeb553..fd63483 100644
--- a/src/arch/arm/aapcs32.hh
+++ b/src/arch/arm/aapcs32.hh
@@ -131,39 +131,78 @@

 template 
 struct Result::value>::type>
+std::is_integral::value && (sizeof(Integer) <  
sizeof(uint32_t))

+>::type>
 {
 static void
 store(ThreadContext *tc, const Integer &i)
 {
-if (sizeof(Integer) < sizeof(uint32_t)) {
-uint32_t val = std::is_signed::value ?
-sext(i) : i;
-tc->setIntReg(ArmISA::INTREG_R0, val);
-} else if (sizeof(Integer) == sizeof(uint32_t) ||
-   std::is_same::value) {
+uint32_t val = std::is_signed::value ?
+sext(i) : i;
+tc->setIntReg(ArmISA::INTREG_R0, val);
+}
+};
+
+template 
+struct Result+std::is_integral::value && (sizeof(Integer) ==  
sizeof(uint32_t))

+>::type>
+{
+static void
+store(ThreadContext *tc, const Integer &i)
+{
+tc->setIntReg(ArmISA::INTREG_R0, (uint32_t)i);
+}
+};
+
+template 
+struct Result+std::is_integral::value && (sizeof(Integer) ==  
sizeof(uint64_t))

+>::type>
+{
+static void
+store(ThreadContext *tc, const Integer &i)
+{
+if (std::is_same::value) {
 tc->setIntReg(ArmISA::INTREG_R0, (uint32_t)i);
-} else if (sizeof(Integer) == sizeof(uint64_t)) {
-if (ArmISA::byteOrder(tc) == LittleEndianByteOrder) {
-tc->setIntReg(ArmISA::INTREG_R0, (uint32_t)(i >> 0));
-tc->setIntReg(ArmISA::INTREG_R1, (uint32_t)(i >> 32));
-} else {
-tc->setIntReg(ArmISA::INTREG_R0, (uint32_t)(i >> 32));
-tc->setIntReg(ArmISA::INTREG_R1, (uint32_t)(i >> 0));
-}
+} else if (ArmISA::byteOrder(tc) == LittleEndianByteOrder) {
+tc->setIntReg(ArmISA::INTREG_R0, (uint32_t)(i >> 0));
+tc->setIntReg(ArmISA::INTREG_R1, (uint32_t)(i >> 32));
+} else {
+tc->setIntReg(ArmISA::INTREG_R0, (uint32_t)(i >> 32));
+tc->setIntReg(ArmISA::INTREG_R1, (uint32_t)(i >> 0));
 }
 }
 };

 template 
 struct Argument::value>::type> : public Aapcs32ArgumentBase
+std::is_integral::value && (sizeof(Integer) <=  
sizeof(uint32_t))

+>::type> : public Aapcs32ArgumentBase
 {
 static Integer
 get(ThreadContext *tc, Aapcs32::State &state)
 {
-if ((sizeof(Integer) <= sizeof(uint32_t) ||
-std::is_same::value) &&
+if (state.ncrn <= state.MAX_CRN) {
+return tc->readIntReg(state.ncrn++);
+}
+
+// Max out the ncrn since we effectively exhausted it.
+state.ncrn = state.MAX_CRN + 1;
+
+return loadFromStack(tc, state);
+}
+};
+
+template 
+struct Argument+std::is_integral::value && (sizeof(Integer) >  
sizeof(uint32_t))

+>::type> : public Aapcs32ArgumentBase
+{
+static Integer
+get(ThreadContext *tc, Aapcs32::State &state)
+{
+if (std::is_same::value &&
 state.ncrn <= state.MAX_CRN) {
 return tc->readIntReg(state.ncrn++);
 }
diff --git a/src/arch/arm/