return csprintf("%-10s", mnemonic);
}
+
std::string
MemDispOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
// Print the data register for a store
else {
- printReg(ss, _srcRegIdx[1]);
+ if (_numSrcRegs > 0) {
+ printReg(ss, _srcRegIdx[0]);
+ }
}
// Print the displacement
- ss << ", " << (int32_t)disp;
+ ss << ", " << disp;
+ ss << "(";
+
+ // Print the address register for a load
+ if (!flags[IsStore]) {
+ if (_numSrcRegs > 0) {
+ printReg(ss, _srcRegIdx[0]);
+ }
+
+ // The address register is skipped if it is R0
+ else {
+ ss << "0";
+ }
+ }
+
+ // Print the address register for a store
+ else {
+ if (_numSrcRegs > 1) {
+ printReg(ss, _srcRegIdx[1]);
+ }
+
+ // The address register is skipped if it is R0
+ else {
+ ss << "0";
+ }
+ }
+
+ ss << ")";
+
+ return ss.str();
+}
+
+
+std::string
+MemDispShiftOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+{
+ std::stringstream ss;
+
+ ccprintf(ss, "%-10s ", mnemonic);
+
+ // Print the destination only for a load
+ if (!flags[IsStore]) {
+ if (_numDestRegs > 0) {
+
+ // If the instruction updates the source register with the
+ // EA, then this source register is placed in position 0,
+ // therefore we print the last destination register.
+ printReg(ss, _destRegIdx[_numDestRegs-1]);
+ }
+ }
+
+ // Print the data register for a store
+ else {
+ if (_numSrcRegs > 0) {
+ printReg(ss, _srcRegIdx[0]);
+ }
+ }
- // Print the address register
+ // Print the displacement
+ ss << ", " << (disp << 2);
ss << "(";
- printReg(ss, _srcRegIdx[0]);
+
+ // Print the address register for a load
+ if (!flags[IsStore]) {
+ if (_numSrcRegs > 0) {
+ printReg(ss, _srcRegIdx[0]);
+ }
+
+ // The address register is skipped if it is R0
+ else {
+ ss << "0";
+ }
+ }
+
+ // Print the address register for a store
+ else {
+ if (_numSrcRegs > 1) {
+ printReg(ss, _srcRegIdx[1]);
+ }
+
+ // The address register is skipped if it is R0
+ else {
+ ss << "0";
+ }
+ }
+
ss << ")";
return ss.str();
}
+
+
+std::string
+MemIndexOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+{
+ std::stringstream ss;
+
+ ccprintf(ss, "%-10s ", mnemonic);
+
+ // Print the destination only for a load
+ if (!flags[IsStore]) {
+ if (_numDestRegs > 0) {
+
+ // If the instruction updates the source register with the
+ // EA, then this source register is placed in position 0,
+ // therefore we print the last destination register.
+ printReg(ss, _destRegIdx[_numDestRegs-1]);
+ }
+ }
+
+ // Print the data register for a store
+ else {
+ if (_numSrcRegs > 0) {
+ printReg(ss, _srcRegIdx[0]);
+ }
+ }
+
+ ss << ", ";
+
+ // Print the address registers for a load
+ if (!flags[IsStore]) {
+ if (_numSrcRegs > 1) {
+ printReg(ss, _srcRegIdx[0]);
+ ss << ", ";
+ printReg(ss, _srcRegIdx[1]);
+ }
+
+ // The first address register is skipped if it is R0
+ else if (_numSrcRegs > 0) {
+ ss << "0, ";
+ printReg(ss, _srcRegIdx[0]);
+ }
+ }
+
+ // Print the address registers for a store
+ else {
+ if (_numSrcRegs > 2) {
+ printReg(ss, _srcRegIdx[1]);
+ ss << ", ";
+ printReg(ss, _srcRegIdx[2]);
+ }
+
+ // The first address register is skipped if it is R0
+ else if (_numSrcRegs > 1) {
+ ss << "0, ";
+ printReg(ss, _srcRegIdx[1]);
+ }
+ }
+
+ return ss.str();
+}
Addr pc, const SymbolTable *symtab) const override;
};
+/**
+ * Class for memory operations with shifted displacement.
+ */
+class MemDispShiftOp : public MemOp
+{
+ protected:
+
+ int16_t disp;
+
+ /// Constructor
+ MemDispShiftOp(const char *mnem, MachInst _machInst, OpClass __opClass)
+ : MemOp(mnem, _machInst, __opClass),
+ disp(sext<14>(machInst.ds))
+ {
+ }
+
+ std::string generateDisassembly(
+ Addr pc, const SymbolTable *symtab) const override;
+};
+
+
+/**
+ * Class for memory operations with register indexed addressing.
+ */
+class MemIndexOp : public MemOp
+{
+ protected:
+
+ /// Constructor
+ MemIndexOp(const char *mnem, MachInst _machInst, OpClass __opClass)
+ : MemOp(mnem, _machInst, __opClass)
+ {
+ }
+
+ std::string generateDisassembly(
+ Addr pc, const SymbolTable *symtab) const override;
+};
+
} // namespace PowerISA
#endif //__ARCH_POWER_INSTS_MEM_HH__
34: lbz({{ Rt = Mem_ub; }});
40: lhz({{ Rt = Mem_uh; }});
42: lha({{ Rt = Mem_sh; }});
- 32: lwz({{ Rt = Mem; }});
+ 32: lwz({{ Rt = Mem_uw; }});
}
58: decode DS_XO {
- format LoadDispOp {
- 2: lwa({{ Rt = Mem_sw; }},
- {{ EA = Ra + (disp & 0xfffffffc); }},
- {{ EA = disp & 0xfffffffc; }});
+ format LoadDispShiftOp {
+ 2: lwa({{ Rt = Mem_sw; }});
}
}
35: lbzu({{ Rt = Mem_ub; }});
41: lhzu({{ Rt = Mem_uh; }});
43: lhau({{ Rt = Mem_sh; }});
- 33: lwzu({{ Rt = Mem; }});
+ 33: lwzu({{ Rt = Mem_uw; }});
}
format StoreDispOp {
38: stb({{ Mem_ub = Rs_ub; }});
44: sth({{ Mem_uh = Rs_uh; }});
- 36: stw({{ Mem = Rs; }});
+ 36: stw({{ Mem = Rs_uw; }});
}
format StoreDispUpdateOp {
39: stbu({{ Mem_ub = Rs_ub; }});
45: sthu({{ Mem_uh = Rs_uh; }});
- 37: stwu({{ Mem = Rs; }});
+ 37: stwu({{ Mem = Rs_uw; }});
}
format IntImmArithCheckRaOp {
87: lbzx({{ Rt = Mem_ub; }});
279: lhzx({{ Rt = Mem_uh; }});
343: lhax({{ Rt = Mem_sh; }});
- 23: lwzx({{ Rt = Mem; }});
+ 23: lwzx({{ Rt = Mem_uw; }});
341: lwax({{ Rt = Mem_sw; }});
- 20: lwarx({{ Rt = Mem_sw; Rsv = 1; RsvLen = 4; RsvAddr = EA; }});
+ 20: lwarx({{ Rt = Mem_uw; Rsv = 1; RsvLen = 4; RsvAddr = EA; }});
535: lfsx({{ Ft_sf = Mem_sf; }});
599: lfdx({{ Ft = Mem_df; }});
855: lfiwax({{ Ft_uw = Mem; }});
119: lbzux({{ Rt = Mem_ub; }});
311: lhzux({{ Rt = Mem_uh; }});
375: lhaux({{ Rt = Mem_sh; }});
- 55: lwzux({{ Rt = Mem; }});
+ 55: lwzux({{ Rt = Mem_uw; }});
373: lwaux({{ Rt = Mem_sw; }});
567: lfsux({{ Ft_sf = Mem_sf; }});
631: lfdux({{ Ft = Mem_df; }});
format StoreIndexOp {
215: stbx({{ Mem_ub = Rs_ub; }});
407: sthx({{ Mem_uh = Rs_uh; }});
- 151: stwx({{ Mem = Rs; }});
+ 151: stwx({{ Mem_uw = Rs_uw; }});
150: stwcx({{
bool store_performed = false;
- Mem = Rs;
+ Mem_uw = Rs_uw;
if (Rsv) {
if (RsvLen == 4) {
if (RsvAddr == EA) {
format StoreIndexUpdateOp {
247: stbux({{ Mem_ub = Rs_ub; }});
439: sthux({{ Mem_uh = Rs_uh; }});
- 183: stwux({{ Mem = Rs; }});
+ 183: stwux({{ Mem_uw = Rs_uw; }});
}
format IntOp {
mem_flags = [], inst_flags = []) {{
(header_output, decoder_output, decode_block, exec_output) = \
GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
- 'MemOp', 'Load', mem_flags, inst_flags)
+ 'MemIndexOp', 'Load', mem_flags, inst_flags)
}};
mem_flags = [], inst_flags = []) {{
(header_output, decoder_output, decode_block, exec_output) = \
GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
- 'MemOp', 'Store', mem_flags, inst_flags)
+ 'MemIndexOp', 'Store', mem_flags, inst_flags)
}};
# Generate the class
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
- base_class = 'MemOp',
+ base_class = 'MemIndexOp',
exec_template_base = 'Load')
}};
# Generate the class
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
- base_class = 'MemOp',
+ base_class = 'MemIndexOp',
exec_template_base = 'Store')
}};
}};
+def format LoadDispShiftOp(memacc_code,
+ ea_code = {{ EA = Ra + (disp << 2); }},
+ ea_code_ra0 = {{ EA = (disp << 2); }},
+ mem_flags = [], inst_flags = []) {{
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
+ 'MemDispShiftOp', 'Load', mem_flags, inst_flags)
+}};
+
+
def format LoadDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
mem_flags = [], inst_flags = []) {{
def operands {{
# General Purpose Integer Reg Operands
- 'Ra': ('IntReg', 'ud', 'RA', 'IsInteger', 1),
- 'Rb': ('IntReg', 'ud', 'RB', 'IsInteger', 2),
- 'Rs': ('IntReg', 'ud', 'RS', 'IsInteger', 3),
+ 'Rs': ('IntReg', 'ud', 'RS', 'IsInteger', 1),
+ 'Ra': ('IntReg', 'ud', 'RA', 'IsInteger', 2),
+ 'Rb': ('IntReg', 'ud', 'RB', 'IsInteger', 3),
'Rt': ('IntReg', 'ud', 'RT', 'IsInteger', 4),
# General Purpose Floating Point Reg Operands
// Immediate fields
Bitfield<15, 0> si;
Bitfield<15, 0> d;
+ Bitfield<15, 2> ds;
// Special purpose register identifier
Bitfield<20, 11> spr;