Files
ivy/asm/instr.c

129 lines
4.8 KiB
C

#include <ivy/asm/instr.h>
#include <stddef.h>
#define INSTR0(id, l, op) \
[IVY_OP_##op] = { \
.i_id = IVY_INSTR_##id, \
.i_layout = IVY_INSTR_##l, \
.i_opcode = IVY_OP_##op, \
.i_operand = {}, \
}
#define INSTR1(id, l, op, a0) \
[IVY_OP_##op] = { \
.i_id = IVY_INSTR_##id, \
.i_layout = IVY_INSTR_##l, \
.i_opcode = IVY_OP_##op, \
.i_operand = {IVY_INSTR_OPERAND_##a0,}, \
}
#define INSTR2(id, l, op, a0, a1) \
[IVY_OP_##op] = { \
.i_id = IVY_INSTR_##id, \
.i_layout = IVY_INSTR_##l, \
.i_opcode = IVY_OP_ ##op, \
.i_operand = {IVY_INSTR_OPERAND_##a0, IVY_INSTR_OPERAND_##a1,}, \
}
#define INSTR3(id, l, op, a0, a1, a2) \
[IVY_OP_##op] = {.i_id = IVY_INSTR_##id, \
.i_layout = IVY_INSTR_##l, \
.i_opcode = IVY_OP_##op, \
.i_operand = { \
IVY_INSTR_OPERAND_##a0, \
IVY_INSTR_OPERAND_##a1, \
IVY_INSTR_OPERAND_##a2, \
}, \
}
/* clang-format off */
static const struct ivy_instr_definition instructions[] = {
INSTR2(LDR, R1D, LDR_SP_REG, REGISTER, SP_INDEX_REG),
INSTR2(LDR, R1D, LDR_SP_CONST, REGISTER, SP_INDEX_CONST),
INSTR2(LDR, R1D, LDR_BP_REG, REGISTER, BP_INDEX_REG),
INSTR2(LDR, R1D, LDR_BP_CONST, REGISTER, BP_INDEX_CONST),
INSTR2(LDR, R1D, LDR_SELF_REG, REGISTER, SELF_INDEX_REG),
INSTR2(LDR, R1D, LDR_SELF_CONST, REGISTER, SELF_INDEX_CONST),
INSTR2(LDR, R1D, LDR_POOL_REG, REGISTER, POOL_INDEX_REG),
INSTR2(LDR, R1D, LDR_POOL_CONST, REGISTER, POOL_INDEX_CONST),
INSTR2(LDR, R1D, LDR_CONST, REGISTER, CONST),
INSTR2(STR, R1D, STR_SP_REG, REGISTER, SP_INDEX_REG),
INSTR2(STR, R1D, STR_SP_CONST, REGISTER, SP_INDEX_CONST),
INSTR2(STR, R1D, STR_BP_REG, REGISTER, BP_INDEX_REG),
INSTR2(STR, R1D, STR_BP_CONST, REGISTER, BP_INDEX_CONST),
INSTR2(STR, R1D, STR_SELF_REG, REGISTER, SELF_INDEX_REG),
INSTR2(STR, R1D, STR_SELF_CONST, REGISTER, SELF_INDEX_CONST),
INSTR1(PUSH, R1, PUSH_REG, REGISTER),
INSTR1(PUSH, R1, PUSH_CONST, CONST),
INSTR1(POP, R1, POP, REGISTER),
INSTR3(MSG, R3, MSG_REG, REGISTER, REGISTER, REGISTER),
INSTR3(MSG, R2D, MSG_CONST, REGISTER, REGISTER, CONST),
INSTR3(ADD, R3, ADD, REGISTER, REGISTER, REGISTER),
INSTR3(SUB, R3, SUB, REGISTER, REGISTER, REGISTER),
INSTR3(MUL, R3, MUL, REGISTER, REGISTER, REGISTER),
INSTR3(DIV, R3, DIV, REGISTER, REGISTER, REGISTER),
INSTR2(C_EQ, R2, C_EQ, REGISTER, REGISTER),
INSTR2(C_NE, R2, C_NE, REGISTER, REGISTER),
INSTR2(C_LT, R2, C_LT, REGISTER, REGISTER),
INSTR2(C_LE, R2, C_LE, REGISTER, REGISTER),
INSTR2(C_GT, R2, C_GT, REGISTER, REGISTER),
INSTR2(C_GE, R2, C_GE, REGISTER, REGISTER),
INSTR1(BR, D, BR, CONST),
INSTR1(BR_T, D, BR_T, CONST),
INSTR1(BR_F, D, BR_F, CONST),
INSTR2(OB_C, R2, OB_C_REG, REGISTER, POOL_INDEX_REG),
INSTR2(OB_C, R1D, OB_C_CONST, REGISTER, POOL_INDEX_CONST),
INSTR1(OB_E, R1, OB_E, REGISTER),
INSTR2(LAM_C, R2, LAM_C_REG, REGISTER, POOL_INDEX_REG),
INSTR2(LAM_C, R1D, LAM_C_CONST, REGISTER, POOL_INDEX_CONST),
INSTR2(IT_G, R2, IT_G, REGISTER, REGISTER),
INSTR1(IT_N, R1, IT_N, REGISTER),
INSTR1(IT_V, R1, IT_V, REGISTER),
INSTR0(RET, X, RET),
INSTR0(RET_N, X, RET_N),
};
static const size_t nr_instructions = sizeof instructions / sizeof instructions[0];
/* clang-format on */
const struct ivy_instr_definition *ivy_instr_find(
enum ivy_instr_id id, const enum ivy_instr_operand_type operands[4])
{
if (operands[3] != IVY_INSTR_OPERAND_NONE) {
return NULL;
}
for (size_t i = 0; i < nr_instructions; i++) {
const struct ivy_instr_definition *def = &instructions[i];
if (def->i_id != id) {
continue;
}
if (def->i_operand[0] != operands[0]) {
continue;
}
if (def->i_operand[1] != operands[1]) {
continue;
}
if (def->i_operand[2] != operands[2]) {
continue;
}
return def;
}
return NULL;
}