Skip to content

Commit

Permalink
arm64: Some fixes for simd move.
Browse files Browse the repository at this point in the history
  • Loading branch information
mikeakohn committed Jan 28, 2024
1 parent 3618f4b commit 4965eb9
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 24 deletions.
76 changes: 63 additions & 13 deletions asm/arm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1128,7 +1128,7 @@ static bool reg_matches(int operand, int wanted)
{
switch (wanted)
{
case ARM64_REG_V: return operand == OPERAND_REG_VECTOR;
case ARM64_REG_V_DOT: return operand == OPERAND_REG_VECTOR;
case ARM64_REG_V_SCALAR: return operand == OPERAND_REG_SCALAR;
case ARM64_REG_V_ELEMENT: return operand == OPERAND_REG_VECTOR_ELEMENT;
case ARM64_REG_B:
Expand All @@ -1138,18 +1138,68 @@ static bool reg_matches(int operand, int wanted)
}
}

static bool match_vector_size(int attribute, int type)
static int get_register_size(_operand *operand)
{
if (attribute == SIZE_D)
switch (operand->type)
{
return type == OPERAND_REG_64;
}
else
{
return type == OPERAND_REG_32;
case OPERAND_REG_32: return 32;
case OPERAND_REG_64: return 64;
case OPERAND_REG_VECTOR:
switch (operand->attribute)
{
case SIZE_8B: return 8;
case SIZE_16B: return 8;
case SIZE_4H: return 16;
case SIZE_8H: return 16;
case SIZE_2S: return 32;
case SIZE_4S: return 32;
case SIZE_1D: return 64;
case SIZE_2D: return 64;
case SIZE_B: return 8;
case SIZE_H: return 16;
case SIZE_S: return 32;
case SIZE_D: return 64;
default: return -4;
}
case OPERAND_REG_VECTOR_ELEMENT:
switch (operand->attribute)
{
case SIZE_8B: return 8;
case SIZE_16B: return 8;
case SIZE_4H: return 16;
case SIZE_8H: return 16;
case SIZE_2S: return 32;
case SIZE_4S: return 32;
case SIZE_1D: return 64;
case SIZE_2D: return 64;
case SIZE_B: return 8;
case SIZE_H: return 16;
case SIZE_S: return 32;
case SIZE_D: return 64;
default: return -4;
}
case OPERAND_REG_SCALAR:
switch (operand->attribute)
{
case 0: return 8;
case 1: return 16;
case 2: return 32;
case 3: return 64;
default: return -3;
}
default:
return -1;
}
}

static bool match_vector_size(_operand *operands)
{
int size_d = get_register_size(&operands[0]);
int size_n = get_register_size(&operands[1]);

return size_d == size_n;
}

static bool encode_vector_element(_operand *operand, int &imm)
{
switch (operand->attribute)
Expand Down Expand Up @@ -1434,9 +1484,9 @@ int parse_instruction_arm64(AsmContext *asm_context, char *instr)
else
if (operands[0].type == OPERAND_REG_VECTOR_ELEMENT)
{
if (!match_vector_size(operands[0].attribute, operands[1].type))
if (!match_vector_size(operands))
{
print_error(asm_context, "Mismatched register sizes.");
print_error(asm_context, "Mismatched register sizes");
return -1;
}

Expand All @@ -1445,9 +1495,9 @@ int parse_instruction_arm64(AsmContext *asm_context, char *instr)
else
if (operands[1].type == OPERAND_REG_VECTOR_ELEMENT)
{
if (!match_vector_size(operands[1].attribute, operands[0].type))
if (!match_vector_size(operands))
{
print_error(asm_context, "Mismatched register sizes.");
print_error(asm_context, "Mismatched register sizes");
return -1;
}

Expand All @@ -1456,7 +1506,7 @@ int parse_instruction_arm64(AsmContext *asm_context, char *instr)

opcode = 0x0e000400 |
(table_arm64_simd_copy[n].q << 31) |
(table_arm64_simd_copy[n].op << 29) |
(table_arm64_simd_copy[n].op << 28) |
(imm5 << 16) |
(imm4 << 11) |
(operands[1].value << 5) |
Expand Down
2 changes: 1 addition & 1 deletion common/version.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef NAKEN_ASM_VERSION_H
#define NAKEN_ASM_VERSION_H

#define VERSION "January 11, 2024"
#define VERSION "January 28, 2024"

#endif

13 changes: 7 additions & 6 deletions disasm/arm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ static const char *get_at(int value)
return "???";
}

static const char *decode_imm5_scalar(int imm, int q)
static const char *decode_imm5_vector(int imm, int q)
{
int size = 0;

Expand Down Expand Up @@ -79,11 +79,12 @@ static void get_reg_name(char *s, int length, int num, int imm, int type, int q)
case ARM64_REG_B:
snprintf(s, length, "%c%d", (imm & 8) == 0 ? 'w' : 'x', num);
break;
case ARM64_REG_V:
snprintf(s, length, "v%d", num);
case ARM64_REG_V_DOT:
snprintf(s, length, "v%d.%s", num, decode_imm5_vector(imm, q));
break;
case ARM64_REG_V_SCALAR:
snprintf(s, length, "v%d.%s", num, decode_imm5_scalar(imm, q));
decode_imm5_element(imm, size, element);
snprintf(s, length, "%c%d", size, num);
break;
case ARM64_REG_V_ELEMENT:
decode_imm5_element(imm, size, element);
Expand Down Expand Up @@ -121,12 +122,12 @@ int disasm_arm64(
sf = (opcode >> 31) & 0x1;
v = (opcode >> 26) & 0x1;

if ((opcode & 0x9fe08400) == 0x0e000400)
if ((opcode & 0x8fe08400) == 0x0e000400)
{
for (n = 0; table_arm64_simd_copy[n].instr != NULL; n++)
{
int q = opcode >> 31;
int op = (opcode >> 29) & 1;
int op = (opcode >> 28) & 3;
int imm5 = (opcode >> 16) & 0x1f;
int imm4 = (opcode >> 11) & 0xf;

Expand Down
7 changes: 4 additions & 3 deletions table/arm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -338,12 +338,13 @@ struct _table_arm64_uncond_branch table_arm64_uncond_branch[] =
// C3.6.5 AdvSIMD copy.
struct _table_arm64_simd_copy table_arm64_simd_copy[] =
{
{ "dup", 0, 0, 0x0, ARM64_REG_V, ARM64_REG_V_ELEMENT },
{ "dup", 0, 0, 0x1, ARM64_REG_V_SCALAR, ARM64_REG_V_ELEMENT },
{ "dup", 0, 0, 0x0, ARM64_REG_V_DOT, ARM64_REG_V_ELEMENT },
{ "dup", 0, 1, 0x0, ARM64_REG_V_SCALAR, ARM64_REG_V_ELEMENT },
{ "dup", 0, 0, 0x1, ARM64_REG_V_DOT, ARM64_REG_B },
{ "smov", 0, 0, 0x5, ARM64_REG_B, ARM64_REG_V_ELEMENT },
{ "umov", 0, 0, 0x7, ARM64_REG_B, ARM64_REG_V_ELEMENT },
{ "ins", 1, 0, 0x3, ARM64_REG_V_ELEMENT, ARM64_REG_V_ELEMENT },
{ "ins", 1, 1, 0x0, ARM64_REG_V_ELEMENT, ARM64_REG_B },
{ "ins", 1, 2, 0x0, ARM64_REG_V_ELEMENT, ARM64_REG_B },
{ NULL, 0, 0, 0x0, 0, 0 },
};

Expand Down
2 changes: 1 addition & 1 deletion table/arm64.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ enum
enum
{
ARM64_REG_B,
ARM64_REG_V,
ARM64_REG_V_SCALAR,
ARM64_REG_V_DOT,
ARM64_REG_V_ELEMENT,
};

Expand Down

0 comments on commit 4965eb9

Please sign in to comment.