Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 16 additions & 8 deletions src/include/simeng/arch/aarch64/helpers/auxiliaryFunctions.hh
Original file line number Diff line number Diff line change
Expand Up @@ -139,16 +139,18 @@ class AuxFunc {

// Rounding function that rounds a double to nearest integer (64-bit). In
Comment thread
FinnWilkinson marked this conversation as resolved.
// event of a tie (i.e. 7.5) it will be rounded to the nearest even number.
static int64_t doubleRoundToNearestTiesToEven(double input) {
if (std::fabs(input - std::trunc(input)) == 0.5) {
if (static_cast<int64_t>(input - 0.5) % 2 == 0) {
return static_cast<int64_t>(input - 0.5);
} else {
return static_cast<int64_t>(input + 0.5);
}
template <typename IN, typename OUT>
static OUT roundToNearestTiesToEven(IN input) {
IN half = static_cast<IN>(0.5);
if (std::fabs(input - std::trunc(input)) == half) {
OUT truncd = static_cast<OUT>(std::trunc(input));
// if value is negative, then may need to -1 from truncd, else may need to
// +1.
OUT addand = (truncd > 0) ? 1 : -1;
return ((truncd % 2 == 0) ? truncd : (truncd + addand));
}
// Otherwise round to nearest
return static_cast<int64_t>(std::round(input));
return static_cast<OUT>(std::round(input));
}

/** Extend `value` according to `extendType`, and left-shift the result by
Expand Down Expand Up @@ -268,6 +270,10 @@ class AuxFunc {

// Get pattern string
std::string pattern(operandStr.substr(operandStr.find(",") + 2));
if (pattern.find(',') != std::string::npos) {
pattern.erase(pattern.find(","));
}

if (pattern == "pow2") {
int n = 1;
while (elements >= std::pow(2, n)) {
Expand Down Expand Up @@ -304,6 +310,8 @@ class AuxFunc {
return elements - (elements % 4);
else if (pattern == "mul3")
return elements - (elements % 3);
else if (pattern == "all")
return elements;

return 0;
}
Expand Down
54 changes: 32 additions & 22 deletions src/include/simeng/arch/aarch64/helpers/sve.hh
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,10 @@ class sveHelp {
const simeng::arch::aarch64::InstructionMetadata& metadata,
const uint16_t VL_bits) {
const uint8_t imm = static_cast<uint8_t>(metadata.operands[1].imm);
return (uint64_t)((VL_bits / (sizeof(T) * 8)) * imm);

const uint16_t elems =
AuxFunc::sveGetPattern(metadata.operandStr, (sizeof(T) * 8), VL_bits);
return (uint64_t)(elems * imm);
}

/** Helper function for SVE instructions with the format `cntp xd, pg, pn`.
Expand Down Expand Up @@ -244,15 +247,16 @@ class sveHelp {
* pattern{, MUL #imm}}`.
* T represents the type of operation (e.g. for DECD, T = uint64_t).
* Returns single value of type uint64_t. */
// TODO : Add support for patterns
template <typename T>
static uint64_t sveDec_scalar(
static int64_t sveDec_scalar(
std::array<RegisterValue, Instruction::MAX_SOURCE_REGISTERS>& operands,
const simeng::arch::aarch64::InstructionMetadata& metadata,
const uint16_t VL_bits) {
const uint64_t n = operands[0].get<uint64_t>();
const int64_t n = operands[0].get<int64_t>();
const uint8_t imm = static_cast<uint8_t>(metadata.operands[1].imm);
return (n - ((VL_bits / (sizeof(T) * 8)) * imm));
const uint16_t elems =
AuxFunc::sveGetPattern(metadata.operandStr, sizeof(T) * 8, VL_bits);
return (n - static_cast<int64_t>(elems * imm));
}

/** Helper function for SVE instructions with the format `dup zd, <#imm{,
Expand Down Expand Up @@ -331,7 +335,7 @@ class sveHelp {
}

/** Helper function for SVE instructions with the format `fadda rd,
* pg/m, rn, zm`.
* pg, rn, zm`.
* T represents the type of operands (e.g. for zm.d, T = uint64_t).
* Returns correctly formatted RegisterValue. */
template <typename T>
Expand Down Expand Up @@ -663,8 +667,9 @@ class sveHelp {
static RegisterValue sveFnegPredicated(
std::array<RegisterValue, Instruction::MAX_SOURCE_REGISTERS>& operands,
const uint16_t VL_bits) {
const uint64_t* p = operands[0].getAsVector<uint64_t>();
const T* n = operands[1].getAsVector<T>();
const T* d = operands[0].getAsVector<T>();
const uint64_t* p = operands[1].getAsVector<uint64_t>();
const T* n = operands[2].getAsVector<T>();

const uint16_t partition_num = VL_bits / (sizeof(T) * 8);
T out[256 / sizeof(T)] = {0};
Expand All @@ -674,7 +679,7 @@ class sveHelp {
if (p[i / (64 / sizeof(T))] & shifted_active)
out[i] = -n[i];
else
out[i] = n[i];
out[i] = d[i];
}
return {out, 256};
}
Expand Down Expand Up @@ -735,7 +740,7 @@ class sveHelp {
* zn`.
* D represents the destination vector register type (e.g. zd.s would be
* int32_t).
* N represents the source vector register type (e.g. zd.d would be
* N represents the source vector register type (e.g. zn.d would be
* double).
* Returns correctly formatted RegisterValue. */
template <typename D, typename N>
Expand All @@ -751,10 +756,11 @@ class sveHelp {

for (int i = 0; i < partition_num; i++) {
uint64_t shifted_active = 1ull << ((i % (64 / sizeof(N))) * sizeof(N));
if (p[i / (64 / sizeof(N))] & shifted_active)
out[i] = AuxFunc::doubleRoundToNearestTiesToEven(n[i]);
else
if (p[i / (64 / sizeof(N))] & shifted_active) {
out[i] = AuxFunc::roundToNearestTiesToEven<N, D>(n[i]);
} else {
out[i] = d[i];
}
}
return {out, 256};
}
Expand Down Expand Up @@ -784,17 +790,19 @@ class sveHelp {
}

/** Helper function for SVE instructions with the format `inc<b, d, h, w>
* xdn{, pattern{, #imm}}`.
* xdn{, pattern{, MUL #imm}}`.
* T represents the type of operation (e.g. for INCB, T = int8_t).
* Returns single value of type uint64_t. */
* Returns single value of type int64_t. */
template <typename T>
static uint64_t sveInc_gprImm(
static int64_t sveInc_gprImm(
std::array<RegisterValue, Instruction::MAX_SOURCE_REGISTERS>& operands,
const simeng::arch::aarch64::InstructionMetadata& metadata,
const uint16_t VL_bits) {
const uint64_t n = operands[0].get<uint64_t>();
const int64_t n = operands[0].get<int64_t>();
const uint8_t imm = static_cast<uint8_t>(metadata.operands[1].imm);
uint64_t out = n + ((VL_bits / (sizeof(T) * 8)) * imm);
const uint16_t elems =
AuxFunc::sveGetPattern(metadata.operandStr, sizeof(T) * 8, VL_bits);
int64_t out = n + (elems * imm);
return out;
}

Expand All @@ -812,9 +820,11 @@ class sveHelp {

const uint16_t partition_num = VL_bits / (sizeof(T) * 8);
typename std::make_signed<T>::type out[256 / sizeof(T)] = {0};
const uint16_t elems =
AuxFunc::sveGetPattern(metadata.operandStr, sizeof(T) * 8, VL_bits);

for (int i = 0; i < partition_num; i++) {
out[i] = n[i] + ((VL_bits / (sizeof(T) * 8)) * imm);
out[i] = n[i] + (elems * imm);
}
return {out, 256};
}
Expand Down Expand Up @@ -894,7 +904,7 @@ class sveHelp {
}

/** Helper function for SVE instructions with the format `<AND, EOR, ...>
* zd, pg/z, zn, zm`.
* zd, pg/m, zn, zm`.
* T represents the type of operands (e.g. for zn.d, T = uint64_t).
* Returns correctly formatted RegisterValue. */
template <typename T>
Expand Down Expand Up @@ -1062,7 +1072,7 @@ class sveHelp {
return {out, 256};
}

/** Helper function for SVE instructions with the format `mul zd, pg/m, zn,
/** Helper function for SVE instructions with the format `mul zdn, pg/m, zdn,
* <zm, #imm>`.
* T represents the type of operands (e.g. for zn.d, T = uint64_t).
* Returns correctly formatted RegisterValue. */
Expand Down Expand Up @@ -1248,7 +1258,7 @@ class sveHelp {
return {out, 256};
}

/** Helper function for SVE instructions with the format `sel zd, pg/z, zn,
/** Helper function for SVE instructions with the format `sel zd, pg, zn,
* zm`.
* T represents the type of operands (e.g. for zn.d, T = uint64_t).
* Returns correctly formatted RegisterValue. */
Expand Down
8 changes: 4 additions & 4 deletions src/lib/arch/aarch64/InstructionMetadata.cc
Original file line number Diff line number Diff line change
Expand Up @@ -380,10 +380,6 @@ InstructionMetadata::InstructionMetadata(const cs_insn& insn)
[[fallthrough]];
case Opcode::AArch64_FMUL_ZZZ_S:
[[fallthrough]];
case Opcode::AArch64_FNEG_ZPmZ_D:
[[fallthrough]];
case Opcode::AArch64_FNEG_ZPmZ_S:
[[fallthrough]];
case Opcode::AArch64_SMAX_ZI_S:
[[fallthrough]];
case Opcode::AArch64_SMINV_VPZ_S:
Expand Down Expand Up @@ -416,6 +412,10 @@ InstructionMetadata::InstructionMetadata(const cs_insn& insn)
[[fallthrough]];
case Opcode::AArch64_FCPY_ZPmI_S:
[[fallthrough]];
case Opcode::AArch64_FNEG_ZPmZ_D:
[[fallthrough]];
case Opcode::AArch64_FNEG_ZPmZ_S:
[[fallthrough]];
case Opcode::AArch64_FRINTN_ZPmZ_D:
[[fallthrough]];
case Opcode::AArch64_FRINTN_ZPmZ_S:
Expand Down
18 changes: 9 additions & 9 deletions src/lib/arch/aarch64/Instruction_execute.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2559,12 +2559,12 @@ void Instruction::execute() {
}
case Opcode::AArch64_DECB_XPiI: { // decb xdn{, pattern{, MUL #imm}}
results[0] =
sveHelp::sveDec_scalar<uint8_t>(operands, metadata, VL_bits);
sveHelp::sveDec_scalar<int8_t>(operands, metadata, VL_bits);
break;
}
case Opcode::AArch64_DECD_XPiI: { // decd xdn{, pattern{, MUL #imm}}
results[0] =
sveHelp::sveDec_scalar<uint64_t>(operands, metadata, VL_bits);
sveHelp::sveDec_scalar<int64_t>(operands, metadata, VL_bits);
break;
}
case Opcode::AArch64_DECD_ZPiI: {
Expand Down Expand Up @@ -7153,25 +7153,25 @@ void Instruction::execute() {
}
case Opcode::AArch64_INCB_XPiI: { // incb xdn{, pattern{, #imm}}
results[0] =
sveHelp::sveInc_gprImm<uint8_t>(operands, metadata, VL_bits);
sveHelp::sveInc_gprImm<int8_t>(operands, metadata, VL_bits);
break;
}
case Opcode::AArch64_INCD_XPiI: { // incd xdn{, pattern{, #imm}}
results[0] =
sveHelp::sveInc_gprImm<uint64_t>(operands, metadata, VL_bits);
sveHelp::sveInc_gprImm<int64_t>(operands, metadata, VL_bits);
break;
}
case Opcode::AArch64_INCD_ZPiI: { // incd zdn.d{, pattern{, #imm}}
results[0] = sveHelp::sveInc_imm<uint64_t>(operands, metadata, VL_bits);
results[0] = sveHelp::sveInc_imm<int64_t>(operands, metadata, VL_bits);
break;
}
case Opcode::AArch64_INCH_XPiI: { // inch xdn{, pattern{, #imm}}
results[0] =
sveHelp::sveInc_gprImm<uint16_t>(operands, metadata, VL_bits);
sveHelp::sveInc_gprImm<int16_t>(operands, metadata, VL_bits);
break;
}
case Opcode::AArch64_INCH_ZPiI: { // inch zdn.h{, pattern{, #imm}}
results[0] = sveHelp::sveInc_imm<uint16_t>(operands, metadata, VL_bits);
results[0] = sveHelp::sveInc_imm<int16_t>(operands, metadata, VL_bits);
break;
}
case Opcode::AArch64_INCP_XP_B: { // incp xdn, pm.b
Expand Down Expand Up @@ -7204,11 +7204,11 @@ void Instruction::execute() {
}
case Opcode::AArch64_INCW_XPiI: { // incw xdn{, pattern{, #imm}}
results[0] =
sveHelp::sveInc_gprImm<uint32_t>(operands, metadata, VL_bits);
sveHelp::sveInc_gprImm<int32_t>(operands, metadata, VL_bits);
break;
}
case Opcode::AArch64_INCW_ZPiI: { // incw zdn.s{, pattern{, #imm}}
results[0] = sveHelp::sveInc_imm<uint32_t>(operands, metadata, VL_bits);
results[0] = sveHelp::sveInc_imm<int32_t>(operands, metadata, VL_bits);
break;
}
case Opcode::AArch64_INDEX_II_B: { // index zd.b, #imm, #imm
Expand Down
Loading