summaryrefslogtreecommitdiff
path: root/src/arch/arm/isa/insts
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/arm/isa/insts')
-rw-r--r--src/arch/arm/isa/insts/data64.isa36
-rw-r--r--src/arch/arm/isa/insts/misc.isa40
2 files changed, 76 insertions, 0 deletions
diff --git a/src/arch/arm/isa/insts/data64.isa b/src/arch/arm/isa/insts/data64.isa
index 3284d5b2a..d0ee439cb 100644
--- a/src/arch/arm/isa/insts/data64.isa
+++ b/src/arch/arm/isa/insts/data64.isa
@@ -226,6 +226,42 @@ let {{
"Dest64 = shiftReg64(Op164, Op264, LSR, intWidth)")
buildDataXRegInst("rorv", 2,
"Dest64 = shiftReg64(Op164, Op264, ROR, intWidth)")
+
+ crcCode = '''
+ constexpr uint8_t size_bytes = %(sz)d;
+ constexpr uint32_t poly = %(polynom)s;
+
+ // Initial value is often a previously evaluated
+ // crc value hence is always 32bit in CRC32
+ uint32_t initial_crc = Op164 & 0xFFFFFFFF;
+
+ uint64_t data = htole(Op264);
+ auto data_buffer = reinterpret_cast<uint8_t*>(&data);
+
+ Dest = crc32<poly>(
+ data_buffer, /* Message register */
+ initial_crc, /* Initial value of the CRC */
+ size_bytes /* Size of the original Message */
+ );
+ '''
+ buildDataXRegInst("crc32b", 2,
+ crcCode % {"sz": 1, "polynom": "0x04C11DB7"})
+ buildDataXRegInst("crc32h", 2,
+ crcCode % {"sz": 2, "polynom": "0x04C11DB7"})
+ buildDataXRegInst("crc32w", 2,
+ crcCode % {"sz": 4, "polynom": "0x04C11DB7"})
+ buildDataXRegInst("crc32x", 2,
+ crcCode % {"sz": 8, "polynom": "0x04C11DB7"})
+
+ buildDataXRegInst("crc32cb", 2,
+ crcCode % {"sz": 1, "polynom": "0x1EDC6F41"})
+ buildDataXRegInst("crc32ch", 2,
+ crcCode % {"sz": 2, "polynom": "0x1EDC6F41"})
+ buildDataXRegInst("crc32cw", 2,
+ crcCode % {"sz": 4, "polynom": "0x1EDC6F41"})
+ buildDataXRegInst("crc32cx", 2,
+ crcCode % {"sz": 8, "polynom": "0x1EDC6F41"})
+
buildDataXRegInst("sdiv", 2, '''
int64_t op1 = Op164;
int64_t op2 = Op264;
diff --git a/src/arch/arm/isa/insts/misc.isa b/src/arch/arm/isa/insts/misc.isa
index edeb0f6d3..4681d50a9 100644
--- a/src/arch/arm/isa/insts/misc.isa
+++ b/src/arch/arm/isa/insts/misc.isa
@@ -136,7 +136,47 @@ let {{
decoder_output += BasicConstructor.subst(eretIop)
exec_output += PredOpExecute.subst(eretIop)
+ crcCode = '''
+ constexpr uint8_t size_bytes = %(sz)d;
+ constexpr uint32_t poly = %(polynom)s;
+
+ uint32_t data = htole(Op2);
+ auto data_buffer = reinterpret_cast<uint8_t*>(&data);
+
+ Dest = crc32<poly>(
+ data_buffer, /* Message Register */
+ Op1, /* Initial Value of the CRC */
+ size_bytes /* Size of the original Message */
+ );
+ '''
+
+ def crc32Emit(mnem, implCode, castagnoli, size):
+ global header_output, decoder_output, exec_output
+
+ if castagnoli:
+ # crc32c instructions
+ poly = "0x1EDC6F41"
+ else:
+ # crc32 instructions
+ poly = "0x04C11DB7"
+ data = {'sz' : size, 'polynom': poly}
+
+ instCode = implCode % data
+
+ crcIop = InstObjParams(mnem, mnem.capitalize(), "RegRegRegOp",
+ { "code": instCode,
+ "predicate_test": predicateTest }, [])
+ header_output += RegRegRegOpDeclare.subst(crcIop)
+ decoder_output += RegRegRegOpConstructor.subst(crcIop)
+ exec_output += PredOpExecute.subst(crcIop)
+
+ crc32Emit("crc32b", crcCode, False, 1);
+ crc32Emit("crc32h", crcCode, False, 2);
+ crc32Emit("crc32w", crcCode, False, 4);
+ crc32Emit("crc32cb", crcCode, True, 1);
+ crc32Emit("crc32ch", crcCode, True, 2);
+ crc32Emit("crc32cw", crcCode, True, 4);
}};