summaryrefslogtreecommitdiff
path: root/src/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/arm')
-rw-r--r--src/arch/arm/isa.hh21
-rw-r--r--src/arch/arm/utility.cc23
2 files changed, 37 insertions, 7 deletions
diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh
index 60c572833..a3e89b544 100644
--- a/src/arch/arm/isa.hh
+++ b/src/arch/arm/isa.hh
@@ -699,15 +699,28 @@ namespace ArmISA
}
template<>
-struct initRenameMode<ArmISA::ISA>
+struct RenameMode<ArmISA::ISA>
{
- static Enums::VecRegRenameMode mode(const ArmISA::ISA* isa)
+ static Enums::VecRegRenameMode
+ init(const ArmISA::ISA* isa)
{
return isa->vecRegRenameMode();
}
- static bool equals(const ArmISA::ISA* isa1, const ArmISA::ISA* isa2)
+
+ static Enums::VecRegRenameMode
+ mode(const ArmISA::PCState& pc)
+ {
+ if (pc.aarch64()) {
+ return Enums::Full;
+ } else {
+ return Enums::Elem;
+ }
+ }
+
+ static bool
+ equalsInit(const ArmISA::ISA* isa1, const ArmISA::ISA* isa2)
{
- return mode(isa1) == mode(isa2);
+ return init(isa1) == init(isa2);
}
};
diff --git a/src/arch/arm/utility.cc b/src/arch/arm/utility.cc
index 175fd7c00..11c3479c6 100644
--- a/src/arch/arm/utility.cc
+++ b/src/arch/arm/utility.cc
@@ -145,6 +145,24 @@ skipFunction(ThreadContext *tc)
}
}
+static void
+copyVecRegs(ThreadContext *src, ThreadContext *dest)
+{
+ auto src_mode = RenameMode<ArmISA::ISA>::mode(src->pcState());
+
+ // The way vector registers are copied (VecReg vs VecElem) is relevant
+ // in the O3 model only.
+ if (src_mode == Enums::Full) {
+ for (auto idx = 0; idx < NumVecRegs; idx++)
+ dest->setVecRegFlat(idx, src->readVecRegFlat(idx));
+ } else {
+ for (auto idx = 0; idx < NumVecRegs; idx++)
+ for (auto elem_idx = 0; elem_idx < NumVecElemPerVecReg; elem_idx++)
+ dest->setVecElemFlat(
+ idx, elem_idx, src->readVecElemFlat(idx, elem_idx));
+ }
+}
+
void
copyRegs(ThreadContext *src, ThreadContext *dest)
{
@@ -154,15 +172,14 @@ copyRegs(ThreadContext *src, ThreadContext *dest)
for (int i = 0; i < NumFloatRegs; i++)
dest->setFloatRegBitsFlat(i, src->readFloatRegBitsFlat(i));
- for (int i = 0; i < NumVecRegs; i++)
- dest->setVecRegFlat(i, src->readVecRegFlat(i));
-
for (int i = 0; i < NumCCRegs; i++)
dest->setCCReg(i, src->readCCReg(i));
for (int i = 0; i < NumMiscRegs; i++)
dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i));
+ copyVecRegs(src, dest);
+
// setMiscReg "with effect" will set the misc register mapping correctly.
// e.g. updateRegMap(val)
dest->setMiscReg(MISCREG_CPSR, src->readMiscRegNoEffect(MISCREG_CPSR));