Sandipan Das has submitted this change. (
https://gem5-review.googlesource.com/c/public/gem5/+/40928 )
Change subject: arch-power: Add doubleword shift instructions
......................................................................
arch-power: Add doubleword shift instructions
This introduces a new class and a new format for XS form
instructions where the shift amount is specified by two
fields that must be concatenated and adds the following
instructions.
* Shift Left Doubleword (sld[.])
* Shift Right Doubleword (srd[.])
* Shift Right Algebraic Doubleword (srad[.])
* Shift Right Algebraic Doubleword Immediate (sradi[.])
* Extend-Sign Word and Shift Left Immediate (extswsli[.])
Change-Id: If51c676009ddafb40f855b66c00eeeffa5d8874c
Signed-off-by: Sandipan Das <sandi...@linux.ibm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/40928
Reviewed-by: Boris Shingarov <shinga...@labware.com>
Maintainer: Boris Shingarov <shinga...@labware.com>
Tested-by: kokoro <noreply+kok...@google.com>
---
M src/arch/power/insts/integer.cc
M src/arch/power/insts/integer.hh
M src/arch/power/isa/decoder.isa
M src/arch/power/isa/formats/integer.isa
4 files changed, 243 insertions(+), 61 deletions(-)
Approvals:
Boris Shingarov: Looks good to me, approved; Looks good to me, approved
kokoro: Regressions pass
diff --git a/src/arch/power/insts/integer.cc
b/src/arch/power/insts/integer.cc
index 2a3ab31..484354b 100644
--- a/src/arch/power/insts/integer.cc
+++ b/src/arch/power/insts/integer.cc
@@ -595,6 +595,68 @@
std::string
+IntConcatShiftOp::generateDisassembly(
+ Addr pc, const Loader::SymbolTable *symtab) const
+{
+ std::stringstream ss;
+ bool printSecondSrc = true;
+ bool printShift = false;
+
+ // Generate the correct mnemonic
+ std::string myMnemonic(mnemonic);
+
+ // Special cases
+ if (myMnemonic == "sradi" ||
+ myMnemonic == "extswsli") {
+ printSecondSrc = false;
+ printShift = true;
+ }
+
+ // Additional characters depending on isa bits being set
+ if (rc)
+ myMnemonic = myMnemonic + ".";
+ ccprintf(ss, "%-10s ", myMnemonic);
+
+ // Print the first destination only
+ if (_numDestRegs > 0)
+ printReg(ss, destRegIdx(0));
+
+ // Print the first source register
+ if (_numSrcRegs > 0) {
+ if (_numDestRegs > 0)
+ ss << ", ";
+ printReg(ss, srcRegIdx(0));
+
+ // Print the second source register
+ if (printSecondSrc) {
+
+ // If the instruction updates the CR, the destination register
+ // Ra is read and thus, it becomes the second source register
+ // due to its higher precedence over Rb. In this case, it must
+ // be skipped.
+ if (rc) {
+ if (_numSrcRegs > 2) {
+ ss << ", ";
+ printReg(ss, srcRegIdx(2));
+ }
+ } else {
+ if (_numSrcRegs > 1) {
+ ss << ", ";
+ printReg(ss, srcRegIdx(1));
+ }
+ }
+ }
+ }
+
+ // Print the shift value
+ if (printShift)
+ ss << ", " << (int) sh;
+
+ return ss.str();
+}
+
+
+std::string
IntRotateOp::generateDisassembly(
Addr pc, const loader::SymbolTable *symtab) const
{
diff --git a/src/arch/power/insts/integer.hh
b/src/arch/power/insts/integer.hh
index 7a8c201..d655e08 100644
--- a/src/arch/power/insts/integer.hh
+++ b/src/arch/power/insts/integer.hh
@@ -601,6 +601,28 @@
/**
+ * Class for integer shift operations with a shift value obtained from
+ * a register or by concatenating immediates.
+ */
+class IntConcatShiftOp : public IntOp
+{
+ protected:
+
+ uint8_t sh;
+
+ /// Constructor
+ IntConcatShiftOp(const char *mnem, MachInst _machInst, OpClass
__opClass)
+ : IntOp(mnem, _machInst, __opClass),
+ sh((machInst.shn << 5) | machInst.sh)
+ {
+ }
+
+ std::string generateDisassembly(
+ Addr pc, const Loader::SymbolTable *symtab) const override;
+};
+
+
+/**
* Class for integer rotate operations.
*/
class IntRotateOp : public IntShiftOp
diff --git a/src/arch/power/isa/decoder.isa b/src/arch/power/isa/decoder.isa
index 2db66b6..2a21a48 100644
--- a/src/arch/power/isa/decoder.isa
+++ b/src/arch/power/isa/decoder.isa
@@ -250,10 +250,19 @@
Ra = res;
}});
- format IntLogicOp {
- 26: cntlzw({{ Ra = findLeadingZeros(Rs_uw); }}, true);
- 28: and({{ Ra = Rs & Rb; }}, true);
- }
+ 26: IntLogicOp::cntlzw({{ Ra = findLeadingZeros(Rs_uw); }}, true);
+
+ 27: IntConcatShiftOp::sld({{
+ int64_t shift = Rb_sd;
+ uint64_t res = Rs & ~((shift << 57) >> 63);
+ if (shift != 0) {
+ shift = bits(shift, 5, 0);
+ res = res << shift;
+ }
+ Ra = res;
+ }});
+
+ 28: IntLogicOp::and({{ Ra = Rs & Rb; }}, true);
32: IntCompOp::cmpl({{
if (l)
@@ -512,6 +521,17 @@
}});
538: IntLogicOp::cnttzw({{ Ra = findTrailingZeros(Rs_uw); }},
true);
+
+ 539: IntConcatShiftOp::srd({{
+ int64_t shift = Rb_sd;
+ uint64_t res = Rs & ~((shift << 57) >> 63);
+ if (shift != 0) {
+ shift = bits(shift, 5, 0);
+ res = res >> shift;
+ }
+ Ra = res;
+ }});
+
567: LoadIndexUpdateOp::lfsux({{ Ft_sf = Mem_sf; }});
570: IntLogicOp::cnttzd({{ Ra = findTrailingZeros(Rs); }}, true);
598: MiscOp::sync({{ }}, [ IsReadBarrier, IsWriteBarrier ]);
@@ -590,40 +610,57 @@
790: LoadIndexOp::lhbrx({{ Rt = swap_byte(Mem_uh); }});
- format IntShiftOp {
- 792: sraw({{
- int32_t src = Rs_sw;
- uint32_t shift = Rb_uw;
- int64_t res;
- if (bits(shift, 5)) {
- res = src >> 31;
- if (res != 0) {
- setCA = true;
- }
- } else {
- if (shift != 0) {
- shift = bits(shift, 4, 0);
- res = src >> shift;
- setCA = src < 0 && (src & mask(shift)) != 0;
- } else {
- res = src;
- }
+ 792: IntShiftOp::sraw({{
+ int32_t src = Rs_sw;
+ uint32_t shift = Rb_uw;
+ int64_t res;
+ if (bits(shift, 5)) {
+ res = src >> 31;
+ if (res != 0) {
+ setCA = true;
}
- Ra = res;
- }}, true);
-
- 824: srawi({{
- int32_t src = Rs_sw;
- int64_t res;
- if (sh) {
- res = src >> sh;
- setCA = src < 0 && (src & mask(sh)) != 0;
+ } else {
+ if (shift != 0) {
+ shift = bits(shift, 4, 0);
+ res = src >> shift;
+ setCA = src < 0 && (src & mask(shift)) != 0;
} else {
res = src;
}
- Ra = res;
- }}, true);
- }
+ }
+ Ra = res;
+ }}, true);
+
+ 794: IntConcatShiftOp::srad({{
+ int64_t src = Rs_sd;
+ uint64_t shift = Rb;
+ int64_t res;
+ if (bits(shift, 6)) {
+ res = src >> 63;
+ setCA = res != 0;
+ } else {
+ if (shift != 0) {
+ shift = shift & 0x3f;
+ res = src >> shift;
+ setCA = src < 0 && (src & mask(shift)) != 0;
+ } else {
+ res = src;
+ }
+ }
+ Ra = res;
+ }}, true);
+
+ 824: IntShiftOp::srawi({{
+ int32_t src = Rs_sw;
+ int64_t res;
+ if (sh) {
+ res = src >> sh;
+ setCA = src < 0 && (src & mask(sh)) != 0;
+ } else {
+ res = src;
+ }
+ Ra = res;
+ }}, true);
854: MiscOp::eieio({{ }}, [ IsReadBarrier, IsWriteBarrier ]);
855: LoadIndexOp::lfiwax({{ Ft_uw = Mem; }});
@@ -810,38 +847,64 @@
}}, true);
}
- default: decode XFX_XO {
- format IntOp {
- 19: mfcr({{ Rt = CR; }});
-
- 144: mtcrf({{
- uint32_t mask = 0;
- for (int i = 0; i < 8; ++i) {
- if (((FXM >> i) & 0x1) == 0x1) {
- mask |= 0xf << (4 * i);
+ // These instructions are of XS form and use bits 21 - 29 as
XO.
+ default: decode XS_XO {
+ format IntConcatShiftOp {
+ 413: sradi({{
+ int64_t src = Rs_sd;
+ if (sh != 0) {
+ Ra = src >> sh;
+ if (src < 0 && (src & mask(sh))) {
+ setCA = true;
}
+ } else {
+ Ra = src;
}
- CR = (Rs & mask) | (CR & ~mask);
+ }}, true);
+
+ 445: extswsli({{
+ int64_t src = Rs_sw;
+ if (sh != 0) {
+ Ra = src << sh;
+ } else {
+ Ra = src;
+ }
}});
+ }
- 339: decode SPR {
- 0x20: mfxer({{ Rt = XER; }});
- 0x100: mflr({{ Rt = LR; }});
- 0x120: mfctr({{ Rt = CTR; }});
- 0x1f9: mftar({{ Rt = TAR; }});
+ default: decode XFX_XO {
+ format IntOp {
+ 19: mfcr({{ Rt = CR; }});
+
+ 144: mtcrf({{
+ uint32_t mask = 0;
+ for (int i = 0; i < 8; ++i) {
+ if (((FXM >> i) & 0x1) == 0x1) {
+ mask |= 0xf << (4 * i);
+ }
+ }
+ CR = (Rs & mask) | (CR & ~mask);
+ }});
+
+ 339: decode SPR {
+ 0x20: mfxer({{ Rt = XER; }});
+ 0x100: mflr({{ Rt = LR; }});
+ 0x120: mfctr({{ Rt = CTR; }});
+ 0x1f9: mftar({{ Rt = TAR; }});
+ }
+
+ 467: decode SPR {
+ 0x20: mtxer({{ XER = Rs; }});
+ 0x100: mtlr({{ LR = Rs; }});
+ 0x120: mtctr({{ CTR = Rs; }});
+ 0x1f9: mttar({{ TAR = Rs; }});
+ }
+
+ 512: mcrxr({{
+ CR = insertCRField(CR, BF, XER<31:28>);
+ XER = XER<27:0>;
+ }});
}
-
- 467: decode SPR {
- 0x20: mtxer({{ XER = Rs; }});
- 0x100: mtlr({{ LR = Rs; }});
- 0x120: mtctr({{ CTR = Rs; }});
- 0x1f9: mttar({{ TAR = Rs; }});
- }
-
- 512: mcrxr({{
- CR = insertCRField(CR, BF, XER<31:28>);
- XER = XER<27:0>;
- }});
}
}
}
diff --git a/src/arch/power/isa/formats/integer.isa
b/src/arch/power/isa/formats/integer.isa
index d8abd5a..3cef9cc 100644
--- a/src/arch/power/isa/formats/integer.isa
+++ b/src/arch/power/isa/formats/integer.isa
@@ -453,6 +453,41 @@
}};
+// Integer instructions that also perform shift operations. Everything
+// is same as above except if the shift value is not obtained from a
+// register, two immediates need to be concatenated to get the final
+// shift value.
+def format IntConcatShiftOp(code, computeCA = 0, inst_flags = []) {{
+ dict = {'result':'Ra'}
+
+ # Add code to setup variables and access XER if necessary
+ code = 'GEM5_VAR_USED bool setCA = false;\n' + code
+
+ # Code when Rc is set
+ code_rc1 = readXERCode + code + computeCR0Code % dict
+
+ # Add code for calculating the carry, if needed
+ if computeCA:
+ code = readXERCode + code + setCACode + setXERCode
+ code_rc1 += setCACode + setXERCode
+
+ # Generate the first class
+ (header_output, decoder_output, decode_block, exec_output) = \
+ GenAluOp(name, Name, 'IntConcatShiftOp', code, inst_flags,
+ CheckRcDecode, BasicConstructor)
+
+ # Generate the second class
+ (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
+ GenAluOp(name, Name + 'RcSet', 'IntConcatShiftOp', code_rc1,
+ inst_flags, CheckRcDecode, BasicConstructor)
+
+ # Finally, add to the other outputs
+ header_output += header_output_rc1
+ decoder_output += decoder_output_rc1
+ exec_output += exec_output_rc1
+}};
+
+
// A special format for rotate instructions which use certain fields
// from the instruction's binary encoding. We need two versions for each
// instruction to deal with the Rc bit.
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/40928
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: If51c676009ddafb40f855b66c00eeeffa5d8874c
Gerrit-Change-Number: 40928
Gerrit-PatchSet: 8
Gerrit-Owner: Sandipan Das <sandi...@linux.ibm.com>
Gerrit-Reviewer: Boris Shingarov <shinga...@labware.com>
Gerrit-Reviewer: Sandipan Das <sandi...@linux.ibm.com>
Gerrit-Reviewer: kokoro <noreply+kok...@google.com>
Gerrit-MessageType: merged
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s