Skip to content

Commit

Permalink
Add string search to add vector layout info.
Browse files Browse the repository at this point in the history
  • Loading branch information
Rot127 committed Nov 1, 2023
1 parent 366af95 commit 2ddf991
Show file tree
Hide file tree
Showing 4 changed files with 206 additions and 115 deletions.
81 changes: 81 additions & 0 deletions arch/AArch64/AArch64Mapping.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,86 @@ static const char *get_custom_reg_alias(unsigned reg)
return NULL;
}

/// Very annoyingly LLVM hard codes the vector layout post-fixes into the asm string.
/// In this function we check for these cases and add the vectorlayout/arrangement
/// specifier.
void AArch64_add_vas(MCInst *MI, const SStream *OS) {
assert(MI);

if (AArch64_get_detail(MI)->op_count == 0) {
return;
}

// Search for r".[0-9]{1,2}[bhsdq]\W"
// with poor mans regex
const char *vl_ptr = strchr(OS->buffer, '.');
while (vl_ptr) {
// Number after dot?
unsigned num = 0;
if (strchr("1248", vl_ptr[1])) {
num = atoi(vl_ptr + 1);
vl_ptr = num > 9 ? vl_ptr + 3 : vl_ptr + 2;
} else {
vl_ptr++;
}

// Layout letter
char letter = '\0';
if (strchr("bhsdq", vl_ptr[0])) {
letter = vl_ptr[0];
}
if (!letter) {
goto next_dot_continue;
}

AArch64Layout_VectorLayout vl = AArch64Layout_Invalid;
switch (letter) {
default:
assert(0 && "Unhandled vector layout letter.");
return;
case 'b':
vl = AArch64Layout_VL_B;
break;
case 'h':
vl = AArch64Layout_VL_H;
break;
case 's':
vl = AArch64Layout_VL_S;
break;
case 'd':
vl = AArch64Layout_VL_D;
break;
case 'q':
vl = AArch64Layout_VL_Q;
break;
}
vl |= (num << 8);

// Determine op index by searching for trainling commata after op string
uint32_t op_idx = 0;
const char *comma_ptr = strchr(OS->buffer, ',');;
while (comma_ptr && comma_ptr < vl_ptr) {
++op_idx;
comma_ptr = strchr(comma_ptr + 1, ',');
}
if (!comma_ptr) {
// Last op doesn't have a trailing commata.
op_idx = AArch64_get_detail(MI)->op_count - 1;
}
assert(op_idx < AArch64_get_detail(MI)->op_count);

// Search for the operand this one belongs to.
cs_aarch64_op *op = &AArch64_get_detail(MI)->operands[op_idx];
if ((op->type != AArch64_OP_REG && op->type != AArch64_OP_SME_MATRIX) || op->vas != AArch64Layout_Invalid) {
goto next_dot_continue;
}
op->vas = vl;

next_dot_continue:
vl_ptr = strchr(vl_ptr + 1, '.');
}
}

const char *AArch64_reg_name(csh handle, unsigned int reg)
{
int syntax_opt = ((cs_struct *)(uintptr_t)handle)->syntax;
Expand Down Expand Up @@ -330,6 +410,7 @@ void AArch64_printer(MCInst *MI, SStream *O, void * /* MCRegisterInfo* */ info)
patch_cs_reg_alias(O->buffer);
AArch64_add_not_defined_ops(MI);
AArch64_add_cs_groups(MI);
AArch64_add_vas(MI, O);
}

// given internal insn id, return public instruction info
Expand Down
1 change: 1 addition & 0 deletions arch/AArch64/AArch64Mapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,6 @@ void AArch64_set_detail_op_float(MCInst *MI, unsigned OpNum, float Val);
void AArch64_set_detail_op_sys(MCInst *MI, unsigned OpNum, aarch64_sysop sys_op, aarch64_op_type type);
void AArch64_set_detail_op_sme(MCInst *MI, unsigned OpNum, aarch64_sme_op_part part, AArch64Layout_VectorLayout vas, ...);
void AArch64_insert_detail_op_reg_at(MCInst *MI, unsigned index, aarch64_reg Reg, cs_ac_type access);
void AArch64_add_vas(MCInst *MI, const SStream *OS);

#endif
29 changes: 19 additions & 10 deletions include/capstone/aarch64.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ typedef enum aarch64_extender {
AArch64_EXT_SXTX = 8,
} aarch64_extender;

// Moved from AArch64BaseInfo.h
// Moved from AArch64BaseInfo.h and modified
// With extension of Q
typedef enum VectorLayout {
AArch64Layout_Invalid = 0,
Expand All @@ -105,16 +105,25 @@ typedef enum VectorLayout {
AArch64Layout_VL_D = 64,
AArch64Layout_VL_Q = 128,

AArch64Layout_VL_8B,
AArch64Layout_VL_4H,
AArch64Layout_VL_2S,
AArch64Layout_VL_1D,
AArch64Layout_VL_4B = (4 << 8) | AArch64Layout_VL_B,
AArch64Layout_VL_2H = (2 << 8) | AArch64Layout_VL_H,
AArch64Layout_VL_1S = (1 << 8) | AArch64Layout_VL_S,

AArch64Layout_VL_8B = (8 << 8) | AArch64Layout_VL_B,
AArch64Layout_VL_4H = (4 << 8) | AArch64Layout_VL_H,
AArch64Layout_VL_2S = (2 << 8) | AArch64Layout_VL_S,
AArch64Layout_VL_1D = (1 << 8) | AArch64Layout_VL_D,

AArch64Layout_VL_16B = (16 << 8) | AArch64Layout_VL_B,
AArch64Layout_VL_8H = (8 << 8) | AArch64Layout_VL_H,
AArch64Layout_VL_4S = (4 << 8) | AArch64Layout_VL_S,
AArch64Layout_VL_2D = (2 << 8) | AArch64Layout_VL_D,
AArch64Layout_VL_1Q = (1 << 8) | AArch64Layout_VL_Q,

AArch64Layout_VL_16B,
AArch64Layout_VL_8H,
AArch64Layout_VL_4S,
AArch64Layout_VL_2D,
AArch64Layout_VL_1Q,
AArch64Layout_VL_64B = (64 << 8) | AArch64Layout_VL_B,
AArch64Layout_VL_32H = (32 << 8) | AArch64Layout_VL_H,
AArch64Layout_VL_16S = (16 << 8) | AArch64Layout_VL_S,
AArch64Layout_VL_8D = (8 << 8) | AArch64Layout_VL_D,

AArch64Layout_VL_Complete, ///< Indicates that the complete matrix is used.
} AArch64Layout_VectorLayout;
Expand Down
Loading

0 comments on commit 2ddf991

Please sign in to comment.