Skip to content

Commit

Permalink
RISC-V: Adding the start of v-extension (vector) instructions.
Browse files Browse the repository at this point in the history
  • Loading branch information
mikeakohn committed Dec 29, 2024
1 parent 48f22b2 commit 80fe129
Show file tree
Hide file tree
Showing 6 changed files with 274 additions and 11 deletions.
217 changes: 210 additions & 7 deletions asm/riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* Web: https://www.mikekohn.net/
* License: GPLv3
*
* Copyright 2010-2023 by Michael Kohn
* Copyright 2010-2024 by Michael Kohn
*
*/

Expand All @@ -21,7 +21,7 @@
#include "common/eval_expression.h"
#include "table/riscv.h"

#define MAX_OPERANDS 5
#define MAX_OPERANDS 6

enum
{
Expand All @@ -33,6 +33,11 @@ enum
OPERAND_REGISTER_OFFSET,
// FIXME: What is this?
OPERAND_IORW,
// RISC-V V-extension (vectors).
OPERAND_VSEW,
OPERAND_LMUL,
OPERAND_TUA,
OPERAND_MUA,
};

#define RM_RNE 0
Expand Down Expand Up @@ -504,6 +509,130 @@ static int compute_alias(
}
#endif

static int build_vset(_operand *operands, int operand_count, uint32_t &opcode)
{
if (operand_count < 3)
{
return -1;
}

int value = 0;

for (int i = 2; i < operand_count; i++)
{
switch (operands[i].type)
{
case OPERAND_VSEW:
value |= operands[i].value << 3;
break;
case OPERAND_LMUL:
value |= operands[i].value;
break;
case OPERAND_TUA:
value |= operands[i].value << 6;
break;
case OPERAND_MUA:
value |= operands[i].value << 7;
break;
default:
return -1;
}
}

opcode |= value << 20;

return 0;
}

static bool check_for_vector_config(const char *token, _operand &operand)
{
if (strcasecmp(token, "tu") == 0)
{
operand.type = OPERAND_TUA;
operand.value = 0;
return true;
}

if (strcasecmp(token, "ta") == 0)
{
operand.type = OPERAND_TUA;
operand.value = 1;
return true;
}

if (strcasecmp(token, "mu") == 0)
{
operand.type = OPERAND_MUA;
operand.value = 0;
return true;
}

if (strcasecmp(token, "ma") == 0)
{
operand.type = OPERAND_MUA;
operand.value = 1;
return true;
}

int value = 0;

if (token[0] == 'e')
{
int n = atoi(token + 1);

switch (n)
{
case 8: value = 0; break;
case 16: value = 1; break;
case 32: value = 2; break;
case 64: value = 3; break;
default: return false;
}

operand.type = OPERAND_VSEW;
operand.value = value;
return true;
}

if (token[0] == 'm')
{
if (token[1] == 'f')
{
int n = atoi(token + 2);

switch (n)
{
case 8: value = 5; break;
case 4: value = 6; break;
case 2: value = 7; break;
default: return false;
}

operand.type = OPERAND_LMUL;
operand.value = value;
return true;
}

int n = atoi(token + 1);

switch (n)
{
case 1: value = 0; break;
case 2: value = 1; break;
case 4: value = 2; break;
case 8: value = 3; break;
default: return false;
}

operand.type = OPERAND_LMUL;
operand.value = value;

return true;
}

return false;
}

static int get_operands(
AsmContext *asm_context,
struct _operand *operands,
Expand Down Expand Up @@ -620,6 +749,16 @@ static int get_operands(
break;
}

// Check for vset (vector instruction) operands.
// These should only be operand 3 and above.
if (operand_count >= 2)
{
if (check_for_vector_config(token, operands[operand_count]))
{
break;
}
}

// Check if this is (reg)
if (IS_TOKEN(token, '('))
{
Expand Down Expand Up @@ -715,10 +854,6 @@ static int get_operands(
{
tokens_push(asm_context, token, token_type);
}

//}

//break;
} while (false);

operand_count++;
Expand All @@ -727,7 +862,7 @@ static int get_operands(

if (token_type == TOKEN_EOL) { break; }

if (IS_NOT_TOKEN(token, ',') || operand_count == 5)
if (IS_NOT_TOKEN(token, ',') || operand_count == MAX_OPERANDS)
{
print_error_unexp(asm_context, token);
return -1;
Expand Down Expand Up @@ -1948,6 +2083,74 @@ int parse_instruction_riscv(AsmContext *asm_context, char *instr)

return 4;
}
case OP_V_VSET_RRI:
{
if (operands[0].type != OPERAND_X_REGISTER ||
operands[1].type != OPERAND_X_REGISTER)
{
print_error_illegal_operands(asm_context, instr);
return -1;
}

opcode = table_riscv[n].opcode |
(operands[1].value << 15) |
(operands[0].value << 7);

if (operand_count == 3 && operands[2].type == OPERAND_NUMBER)
{
if (check_range(asm_context, "Immediate", operands[2].value, 0, 0x7ff) == -1) { return -1; }

opcode |= table_riscv[n].opcode | (operands[2].value << 20);
add_bin32(asm_context, opcode, IS_OPCODE);

return 4;
}

if (build_vset(operands, operand_count, opcode) == -1)
{
print_error_illegal_operands(asm_context, instr);
return -1;
}

add_bin32(asm_context, opcode, IS_OPCODE);

return 4;
}
case OP_V_VSET_RII:
{
if (operands[0].type != OPERAND_X_REGISTER ||
operands[1].type != OPERAND_NUMBER )
{
print_error_illegal_operands(asm_context, instr);
return -1;
}

if (check_range(asm_context, "Immediate", operands[1].value, 0, 31) == -1) { return -1; }

opcode = table_riscv[n].opcode |
(operands[1].value << 15) |
(operands[0].value << 7);

if (operand_count == 3 && operands[2].type == OPERAND_NUMBER)
{
if (check_range(asm_context, "Immediate", operands[2].value, 0, 0x3ff) == -1) { return -1; }

opcode |= table_riscv[n].opcode | (operands[2].value << 20);
add_bin32(asm_context, opcode, IS_OPCODE);

return 4;
}

if (build_vset(operands, operand_count, opcode) == -1)
{
print_error_illegal_operands(asm_context, instr);
return -1;
}

add_bin32(asm_context, opcode, IS_OPCODE);

return 4;
}
default:
break;
}
Expand Down
2 changes: 1 addition & 1 deletion asm/riscv.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* Web: https://www.mikekohn.net/
* License: GPLv3
*
* Copyright 2010-2023 by Michael Kohn
* Copyright 2010-2024 by Michael Kohn
*
*/

Expand Down
32 changes: 32 additions & 0 deletions disasm/riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@ const char *riscv_reg_names[32] =
"s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6"
};

static const char *riscv_vector_sew[8] =
{
"e8", "e16", "e32", "e64", "e?", "e?", "e?", "e?"
};

static const char *riscv_vector_lmul[8] =
{
"m1", "m2", "m4", "m8", "m?", "mf8", "mf4", "mf2"
};

// REVIEW: Probably don't need this since compressed register
// can be mapped to reg + 8. Still not sure what to do with s0/fp.
#if 0
Expand Down Expand Up @@ -431,6 +441,28 @@ int disasm_riscv(
opcode >> 20,
rs1);
break;
case OP_V_VSET_RRI:
snprintf(instruction, length, "%s %s, %s, %s, %s, t%c, m%c",
instr,
riscv_reg_names[rd],
riscv_reg_names[rs1],
riscv_vector_sew[(opcode >> 23) & 0x7],
riscv_vector_lmul[(opcode >> 20) & 0x7],
((opcode >> 26) & 1) == 0 ? 'u' : 'a',
((opcode >> 27) & 1) == 0 ? 'u' : 'a');
break;
case OP_V_VSET_RII:
snprintf(instruction, length, "%s %s, %d, %s, %s, t%c, m%c",
instr,
riscv_reg_names[rd],
rs1,
riscv_vector_sew[(opcode >> 23) & 0x7],
riscv_vector_lmul[(opcode >> 20) & 0x7],
((opcode >> 26) & 1) == 0 ? 'u' : 'a',
((opcode >> 27) & 1) == 0 ? 'u' : 'a');
break;
//case OP_V_VSET_RRR:
// break;
default:
strcpy(instruction, "???");
break;
Expand Down
19 changes: 19 additions & 0 deletions include/riscv/csr.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; RISC-V CSR include.
;; Part of the naken_asm assembler
;;
;; Create by: Michael Kohn ([email protected])
;; Date: 2024-Dec-28
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Vector unit config.
vstart equ 0x008
vxsat equ 0x009
vxrm equ 0x00a
vcsr equ 0x00f
vl equ 0xc20
vtype equ 0xc21
vlenb equ 0xc22

9 changes: 7 additions & 2 deletions table/riscv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* Web: https://www.mikekohn.net/
* License: GPLv3
*
* Copyright 2010-2023 by Michael Kohn
* Copyright 2010-2024 by Michael Kohn
*
*/

Expand Down Expand Up @@ -298,13 +298,17 @@ struct _table_riscv table_riscv[] =
{ "fcvt.d.l", 0xd2200053, 0xfff0007f, OP_FP_R_RM, 0 },
{ "fcvt.d.lu", 0xd2300053, 0xfff0007f, OP_FP_R_RM, 0 },
{ "fmv.d.x", 0xf2000053, 0xfff0707f, OP_FP_R, 0 },
// Privileged Instructions?
// Privileged instructions?
{ "uret", 0x00200073, 0xffffffff, OP_NONE, 0 },
{ "sret", 0x10200073, 0xffffffff, OP_NONE, 0 },
{ "hret", 0x20200073, 0xffffffff, OP_NONE, 0 },
{ "mret", 0x30200073, 0xffffffff, OP_NONE, 0 },
{ "wfi", 0x10500073, 0xffffffff, OP_NONE, 0 },
{ "sfence.vm", 0x10400073, 0xfff07fff, OP_RS1, 0 },
// RISC-V V Extension (vectors).
{ "vsetvli", 0x00007057, 0x8000707f, OP_V_VSET_RRI, 0 },
{ "vsetivli", 0xc0007057, 0xc000707f, OP_V_VSET_RII, 0 },
{ "vsetvl", 0x80007057, 0xfe00707f, OP_R_TYPE, 0 },
{ NULL, 0, 0, 0, 0 }
};

Expand Down Expand Up @@ -354,6 +358,7 @@ struct _table_riscv_comp table_riscv_comp[] =
{ "c.lwsp", 0x4002, 0xe003, OP_COMP_RD_5_4276, 0 },
{ "c.flwsp", 0x6002, 0xe003, OP_COMP_RD_5_4276, RISCV_FP },
{ "c.ldsp", 0x6002, 0xe003, OP_COMP_RD_5_4386, RISCV64 | RISCV128 },
{ "c.ret", 0x8082, 0xffff, OP_NONE, 0 },
{ "c.jr", 0x8002, 0xf07f, OP_COMP_RD32, 0 },
{ "c.mv", 0x8002, 0xf003, OP_COMP_RS1_RS2, 0 },
{ "c.ebreak", 0x9002, 0xffff, OP_NONE, 0 },
Expand Down
Loading

0 comments on commit 80fe129

Please sign in to comment.