/*
- * Copyright (c) 2011-2013,2018 ARM Limited
+ * Copyright (c) 2011-2013,2018, 2021 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
ccprintf(ss, ", #%d", pc + imm);
return ss.str();
}
+
+std::string
+MemoryAtomicPair64::generateDisassembly(
+ Addr pc, const Loader::SymbolTable *symtab) const
+{
+ std::stringstream ss;
+ printMnemonic(ss, "", false);
+ printIntReg(ss, result);
+ ccprintf(ss, ", ");
+ printIntReg(ss, result2);
+ ccprintf(ss, ", ");
+ printIntReg(ss, dest);
+ ccprintf(ss, ", ");
+ printIntReg(ss, dest2);
+ ccprintf(ss, ", [");
+ printIntReg(ss, base);
+ ccprintf(ss, "]");
+ return ss.str();
+}
+
}
/*
- * Copyright (c) 2011-2013,2017-2019 ARM Limited
+ * Copyright (c) 2011-2013,2017-2019, 2021 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
Addr pc, const Loader::SymbolTable *symtab) const override;
};
+class MemoryAtomicPair64 : public Memory64
+{
+ protected:
+ IntRegIndex dest2;
+ IntRegIndex result;
+ IntRegIndex result2;
+
+ MemoryAtomicPair64(const char *mnem, ExtMachInst _machInst,
+ OpClass __opClass, IntRegIndex _dest, IntRegIndex _base,
+ IntRegIndex _result)
+ : Memory64(mnem, _machInst, __opClass, _dest, _base),
+ dest2((IntRegIndex)(_dest + (IntRegIndex)(1))),
+ result(_result),
+ result2((IntRegIndex)(_result + (IntRegIndex)(1)))
+ {}
+
+ std::string generateDisassembly(
+ Addr pc, const Loader::SymbolTable *symtab) const override;
+};
+
}
#endif //__ARCH_ARM_INSTS_MEM_HH__
// -*- mode:c++ -*-
+// Copyright (c) 2021 ARM Limited
// Copyright (c) 2018 Metempsy Technology Consulting
// All rights reserved
//
flavor="release").emit(OP_DICT['CAS'])
class CasPair64(AtomicInst64):
- decConstBase = 'AmoPairOp'
- base = 'ArmISA::MemoryEx64'
+ decConstBase = 'AmoOp'
+ base = 'ArmISA::MemoryAtomicPair64'
writeback = True
post = False
execBase = 'AmoOp'
isBigEndian64(xc->tcBase()));
uint64_t result2 = cSwap(Mem%(suffix)s[1],
isBigEndian64(xc->tcBase()));
- xc->setIntRegOperand(this, r2_dst, (result2)
- & mask(aarch64 ? 64 : 32));
+
+ XResult2 = result2;
'''
elif self.size == 4:
self.res = 'Result_uw'
uint32_t result2 = isBigEndian64(xc->tcBase())
? (uint32_t)data
: (data >> 32);
- xc->setIntRegOperand(this, r2_dst, (result2) &
- mask(aarch64 ? 64 : 32));
+
+ XResult2 = result2;
'''
store_res = store_res % {"result":self.res, "suffix":self.suffix}
# Code that actually handles the access
if self.size == 4:
- accCode = \
- "uint32_t result2 = ((xc->readIntRegOperand(this, r2_src))"\
- " & mask(aarch64 ? 64 : 32)) ;\n"\
- " uint32_t dest2 = ((xc->readIntRegOperand(this, d2_src)) "\
- " & mask(aarch64 ? 64 : 32)) ;"
- accCode += '''
- uint64_t data = dest2;
+ accCode = '''
+ uint64_t data = XDest2;
data = isBigEndian64(xc->tcBase())
? ((uint64_t(WDest_uw) << 32) | data)
: ((data << 32) | WDest_uw);
valRs = cSwap(data, isBigEndian64(xc->tcBase()));
- uint64_t data2 = result2 ;
+ uint64_t data2 = XResult2 ;
data2 = isBigEndian64(xc->tcBase())
? ((uint64_t(Result_uw) << 32) | data2)
: ((data2 << 32) | Result_uw);
" %(type)s c){ %(op)s });\n"
elif self.size == 8:
- accCode = ""\
- "uint64_t result2 = ((xc->readIntRegOperand(this, r2_src))"\
- " & mask(aarch64 ? 64 : 32)) ;\n"\
- " uint64_t dest2 = ((xc->readIntRegOperand(this, d2_src)) "\
- " & mask(aarch64 ? 64 : 32)) ;"
- accCode += '''
+ accCode = '''
// This temporary needs to be here so that the parser
// will correctly identify this instruction as a store.
std::array<uint64_t, 2> temp;
temp[0] = cSwap(XDest_ud,isBigEndian64(xc->tcBase()));
- temp[1] = cSwap(dest2,isBigEndian64(xc->tcBase()));
+ temp[1] = cSwap(XDest2,isBigEndian64(xc->tcBase()));
valRs = temp;
std::array<uint64_t, 2> temp2;
temp2[0] = cSwap(XResult_ud,isBigEndian64(xc->tcBase()));
- temp2[1] = cSwap(result2,isBigEndian64(xc->tcBase()));
+ temp2[1] = cSwap(XResult2,isBigEndian64(xc->tcBase()));
Mem_tud = temp2;
'''
// -*- mode:c++ -*-
-// Copyright (c) 2010-2014, 2016-2018 ARM Limited
+// Copyright (c) 2010-2014, 2016-2018, 2021 ARM Limited
// All rights reserved
//
// The license below extends only to copyright in the software and shall
'IWDest2': intRegIWPC('dest2'),
'Result': intReg('result'),
'XResult': intRegX64('result'),
+ 'XResult2': intRegX64('result2'),
'XBase': intRegX64('base', id = srtBase),
'Base': intRegAPC('base', id = srtBase),
'XOffset': intRegX64('offset'),
}
}};
-def template AmoPairOpDeclare {{
- class %(class_name)s : public %(base_class)s
- {
- private:
- %(reg_idx_arr_decl)s;
-
- public:
- uint32_t d2_src ;
- uint32_t r2_src ;
- uint32_t r2_dst ;
- /// Constructor.
- %(class_name)s(ExtMachInst machInst, IntRegIndex _dest,
- IntRegIndex _base, IntRegIndex _result);
-
- Fault execute(ExecContext *, Trace::InstRecord *) const override;
- Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override;
- Fault completeAcc(PacketPtr, ExecContext *,
- Trace::InstRecord *) const override;
-
- void
- annotateFault(ArmISA::ArmFault *fault) override
- {
- %(fa_code)s
- }
- };
-}};
-
-
-def template AmoPairOpConstructor {{
- %(class_name)s::%(class_name)s(ExtMachInst machInst,
- IntRegIndex _dest, IntRegIndex _base, IntRegIndex _result) :
- %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
- _dest, _base, _result)
- {
- %(set_reg_idx_arr)s;
- %(constructor)s;
-
- uint32_t d2 = RegId(IntRegClass, dest).index() + 1 ;
- uint32_t r2 = RegId(IntRegClass, result).index() + 1 ;
-
- d2_src = _numSrcRegs ;
- setSrcRegIdx(_numSrcRegs++, RegId(IntRegClass, d2));
- r2_src = _numSrcRegs ;
- setSrcRegIdx(_numSrcRegs++, RegId(IntRegClass, r2));
- r2_dst = _numDestRegs ;
- setDestRegIdx(_numDestRegs++, RegId(IntRegClass, r2));
- flags[IsStore] = false;
- flags[IsLoad] = false;
- }
-}};
-
def template AmoArithmeticOpDeclare {{
class %(class_name)s : public %(base_class)s
{