arch-power: Fix load-store instructions
Now that 64-bit registers and operands are being used, the instructions for words must read or write just one word at a time. This fixes the following instructions. * Load Word and Zero (lwz) * Load Word and Zero Indexed (lwzx) * Load Word and Zero with Update (lwzu) * Load Word and Zero with Update Indexed (lwzux) * Load Word And Reserve Indexed (lwarx) * Store Word (stw) * Store Word Indexed (stwx) * Store Word with Update (stwu) * Store Word with Update Indexed (stwux) * Store Word Conditional Indexed (stwcx.) This also fixes decoding of load-store update instructions for some special scenarios when RA is zero or RA and RT are the same. In such cases, the instruction is considered invalid. Change-Id: I6787d3614ba8f1b1cbf30a49f85ef422324d7c21 Signed-off-by: Sandipan Das <sandipan@linux.ibm.com> Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/40893 Reviewed-by: Boris Shingarov <shingarov@labware.com> Maintainer: Jason Lowe-Power <power.jg@gmail.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
committed by
Boris Shingarov
parent
77ed301bd7
commit
2600ac281e
@@ -196,8 +196,12 @@ decode PO default Unknown::unknown() {
|
||||
}});
|
||||
|
||||
format LoadIndexOp {
|
||||
20: lwarx({{ Rt = Mem_sw; Rsv = 1; RsvLen = 4; RsvAddr = EA; }});
|
||||
23: lwzx({{ Rt = Mem; }});
|
||||
20: lwarx({{
|
||||
Rt = Mem_uw;
|
||||
Rsv = 1; RsvLen = 4; RsvAddr = EA;
|
||||
}});
|
||||
|
||||
23: lwzx({{ Rt = Mem_uw; }});
|
||||
}
|
||||
|
||||
format IntLogicOp {
|
||||
@@ -219,7 +223,7 @@ decode PO default Unknown::unknown() {
|
||||
CR = insertCRField(CR, BF, cr);
|
||||
}});
|
||||
|
||||
55: LoadIndexUpdateOp::lwzux({{ Rt = Mem; }});
|
||||
55: LoadIndexUpdateOp::lwzux({{ Rt = Mem_uw; }});
|
||||
60: IntLogicOp::andc({{ Ra = Rs & ~Rb; }});
|
||||
87: LoadIndexOp::lbzx({{ Rt = Mem_ub; }});
|
||||
119: LoadIndexUpdateOp::lbzux({{ Rt = Mem_ub; }});
|
||||
@@ -228,7 +232,7 @@ decode PO default Unknown::unknown() {
|
||||
format StoreIndexOp {
|
||||
150: stwcx({{
|
||||
bool store_performed = false;
|
||||
Mem = Rs;
|
||||
Mem_uw = Rs_uw;
|
||||
if (Rsv) {
|
||||
if (RsvLen == 4) {
|
||||
if (RsvAddr == EA) {
|
||||
@@ -243,7 +247,7 @@ decode PO default Unknown::unknown() {
|
||||
Rsv = 0;
|
||||
}});
|
||||
|
||||
151: stwx({{ Mem = Rs; }});
|
||||
151: stwx({{ Mem_uw = Rs_uw; }});
|
||||
}
|
||||
|
||||
183: StoreIndexUpdateOp::stwux({{ Mem = Rs; }});
|
||||
@@ -515,12 +519,12 @@ decode PO default Unknown::unknown() {
|
||||
}
|
||||
}
|
||||
|
||||
32: LoadDispOp::lwz({{ Rt = Mem; }});
|
||||
33: LoadDispUpdateOp::lwzu({{ Rt = Mem; }});
|
||||
32: LoadDispOp::lwz({{ Rt = Mem_uw; }});
|
||||
33: LoadDispUpdateOp::lwzu({{ Rt = Mem_uw; }});
|
||||
34: LoadDispOp::lbz({{ Rt = Mem_ub; }});
|
||||
35: LoadDispUpdateOp::lbzu({{ Rt = Mem_ub; }});
|
||||
36: StoreDispOp::stw({{ Mem = Rs; }});
|
||||
37: StoreDispUpdateOp::stwu({{ Mem = Rs; }});
|
||||
36: StoreDispOp::stw({{ Mem_uw = Rs_uw; }});
|
||||
37: StoreDispUpdateOp::stwu({{ Mem_uw = Rs_uw; }});
|
||||
38: StoreDispOp::stb({{ Mem_ub = Rs_ub; }});
|
||||
39: StoreDispUpdateOp::stbu({{ Mem_ub = Rs_ub; }});
|
||||
40: LoadDispOp::lhz({{ Rt = Mem_uh; }});
|
||||
|
||||
@@ -263,6 +263,7 @@ def format LoadIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
|
||||
(header_output, decoder_output, decode_block, exec_output) = \
|
||||
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
||||
base_class = 'MemIndexOp',
|
||||
decode_template = CheckRaRtDecode,
|
||||
exec_template_base = 'Load')
|
||||
}};
|
||||
|
||||
@@ -277,6 +278,7 @@ def format StoreIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }},
|
||||
(header_output, decoder_output, decode_block, exec_output) = \
|
||||
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
||||
base_class = 'MemIndexOp',
|
||||
decode_template = CheckRaZeroDecode,
|
||||
exec_template_base = 'Store')
|
||||
}};
|
||||
|
||||
@@ -319,6 +321,7 @@ def format LoadDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + d; }},
|
||||
(header_output, decoder_output, decode_block, exec_output) = \
|
||||
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
||||
base_class = 'MemDispOp',
|
||||
decode_template = CheckRaRtDecode,
|
||||
exec_template_base = 'Load')
|
||||
}};
|
||||
|
||||
@@ -333,5 +336,6 @@ def format StoreDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + d; }},
|
||||
(header_output, decoder_output, decode_block, exec_output) = \
|
||||
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
||||
base_class = 'MemDispOp',
|
||||
decode_template = CheckRaZeroDecode,
|
||||
exec_template_base = 'Store')
|
||||
}};
|
||||
|
||||
@@ -123,6 +123,26 @@ def template CheckBoLkDecode {{
|
||||
}
|
||||
}};
|
||||
|
||||
def template CheckRaRtDecode {{
|
||||
{
|
||||
if ((RA == 0) || (RA == RT)) {
|
||||
return new Unknown(machInst);
|
||||
} else {
|
||||
return new %(class_name)s(machInst);
|
||||
}
|
||||
}
|
||||
}};
|
||||
|
||||
def template CheckRaZeroDecode {{
|
||||
{
|
||||
if (RA == 0) {
|
||||
return new Unknown(machInst);
|
||||
} else {
|
||||
return new %(class_name)s(machInst);
|
||||
}
|
||||
}
|
||||
}};
|
||||
|
||||
let {{
|
||||
|
||||
def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
||||
|
||||
Reference in New Issue
Block a user