Skip to content

Commit

Permalink
arm64: Adding some FPU SIMD instructions.
Browse files Browse the repository at this point in the history
  • Loading branch information
mikeakohn committed Jan 31, 2024
1 parent b1a1811 commit 984372e
Show file tree
Hide file tree
Showing 2 changed files with 236 additions and 0 deletions.
176 changes: 176 additions & 0 deletions asm/arm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1362,6 +1362,154 @@ static int op_vector_shift_imm(
return 4;
}

static int op_vector_v_v_v_fpu(
AsmContext *asm_context,
struct _operand *operands,
int operand_count,
uint32_t opcode,
char *instr)
{
if (operand_count != 3) { return -2; }

if (operands[0].type != OPERAND_REG_VECTOR ||
operands[1].type != OPERAND_REG_VECTOR ||
operands[2].type != OPERAND_REG_VECTOR ||
operands[0].attribute != operands[1].attribute ||
operands[0].attribute != operands[2].attribute)
{
return -2;
}

int q = 0;
int sz = 0;

switch (operands[0].attribute)
{
case SIZE_2S: q = 0; sz = 0; break;
case SIZE_4S: q = 1; sz = 0; break;
case SIZE_2D: q = 1; sz = 1; break;
default: return -2;
}

opcode |= (q << 30) |
(sz << 22) |
(operands[2].value << 16) |
(operands[1].value << 5) |
operands[0].value;

add_bin32(asm_context, opcode, IS_OPCODE);

return 4;
}

static int op_vector_v_v_fpu(
AsmContext *asm_context,
struct _operand *operands,
int operand_count,
uint32_t opcode,
char *instr)
{
if (operand_count != 2) { return -2; }

if (operands[0].type != OPERAND_REG_VECTOR ||
operands[1].type != OPERAND_REG_VECTOR ||
operands[0].attribute != operands[1].attribute)
{
return -2;
}

int q = 0;
int sz = 0;

switch (operands[0].attribute)
{
case SIZE_2S: q = 0; sz = 0; break;
case SIZE_4S: q = 1; sz = 0; break;
case SIZE_2D: q = 1; sz = 1; break;
default: return -2;
}

opcode |= (q << 30) |
(sz << 22) |
(operands[1].value << 5) |
operands[0].value;

add_bin32(asm_context, opcode, IS_OPCODE);

return 4;
}

static int op_vector_d_d_d_fpu(
AsmContext *asm_context,
struct _operand *operands,
int operand_count,
uint32_t opcode,
char *instr)
{
if (operand_count != 3) { return -2; }

if (operands[0].type != OPERAND_REG_SCALAR ||
operands[1].type != OPERAND_REG_SCALAR ||
operands[2].type != OPERAND_REG_SCALAR ||
operands[0].attribute != operands[1].attribute ||
operands[0].attribute != operands[2].attribute)
{
return -2;
}

int type = 0;

switch (operands[0].attribute)
{
case 2: type = 0; break;
case 3: type = 1; break;
default: return -2;
}

opcode |= (type << 22) |
(operands[2].value << 16) |
(operands[1].value << 5) |
operands[0].value;

add_bin32(asm_context, opcode, IS_OPCODE);

return 4;
}

static int op_vector_d_d_fpu(
AsmContext *asm_context,
struct _operand *operands,
int operand_count,
uint32_t opcode,
char *instr)
{
if (operand_count != 2) { return -2; }

if (operands[0].type != OPERAND_REG_SCALAR ||
operands[1].type != OPERAND_REG_SCALAR ||
operands[0].attribute != operands[1].attribute)
{
return -2;
}

int type = 0;

switch (operands[0].attribute)
{
case 2: type = 0; break;
case 3: type = 1; break;
default: return -2;
}

opcode |= (type << 22) |
(operands[1].value << 5) |
operands[0].value;

add_bin32(asm_context, opcode, IS_OPCODE);

return 4;
}

static bool reg_matches(int operand, int wanted)
{
switch (wanted)
Expand Down Expand Up @@ -2027,6 +2175,34 @@ int parse_instruction_arm64(AsmContext *asm_context, char *instr)
if (ret == -2) { continue; }
return ret;
}
case OP_VECTOR_V_V_V_FPU:
{
ret = op_vector_v_v_v_fpu(asm_context, operands, operand_count, table_arm64[n].opcode, instr);

if (ret == -2) { continue; }
return ret;
}
case OP_VECTOR_V_V_FPU:
{
ret = op_vector_v_v_fpu(asm_context, operands, operand_count, table_arm64[n].opcode, instr);

if (ret == -2) { continue; }
return ret;
}
case OP_VECTOR_D_D_D_FPU:
{
ret = op_vector_d_d_d_fpu(asm_context, operands, operand_count, table_arm64[n].opcode, instr);

if (ret == -2) { continue; }
return ret;
}
case OP_VECTOR_D_D_FPU:
{
ret = op_vector_d_d_fpu(asm_context, operands, operand_count, table_arm64[n].opcode, instr);

if (ret == -2) { continue; }
return ret;
}
default:
{
break;
Expand Down
60 changes: 60 additions & 0 deletions disasm/arm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,66 @@ int disasm_arm64(

return 4;
}
case OP_VECTOR_V_V_V_FPU:
{
int q = (opcode >> 30) & 1;
int sz = (opcode >> 22) & 1;
const char *size = "?";

if (sz == 0 && q == 0) { size = "2s"; }
else if (sz == 0 && q == 1) { size = "4s"; }
else if (sz == 1 && q == 1) { size = "2d"; }

snprintf(instruction, length, "%s v%d.%s, v%d.%s, v%d.%s",
table_arm64[n].instr,
rd, size,
rn, size,
rm, size);

return 4;
}
case OP_VECTOR_V_V_FPU:
{
int q = (opcode >> 30) & 1;
int sz = (opcode >> 22) & 1;
const char *size = "?";

if (sz == 0 && q == 0) { size = "2s"; }
else if (sz == 0 && q == 1) { size = "4s"; }
else if (sz == 1 && q == 1) { size = "2d"; }

snprintf(instruction, length, "%s v%d.%s, v%d.%s",
table_arm64[n].instr,
rd, size,
rn, size);

return 4;
}
case OP_VECTOR_D_D_D_FPU:
{
int type = (opcode >> 22) & 3;
char size[] = { 's', 'd', '?', '?' };

snprintf(instruction, length, "%s %c%d, %c%d, %c%d",
table_arm64[n].instr,
size[type], rd,
size[type], rn,
size[type], rm);

return 4;
}
case OP_VECTOR_D_D_FPU:
{
int type = (opcode >> 22) & 3;
char size[] = { 's', 'd', '?', '?' };

snprintf(instruction, length, "%s %c%d, %c%d",
table_arm64[n].instr,
size[type], rd,
size[type], rn);

return 4;
}
default:
{
//print_error_internal(asm_context, __FILE__, __LINE__);
Expand Down

0 comments on commit 984372e

Please sign in to comment.