Files
ivy/asm/assembler/block.c

78 lines
1.8 KiB
C

#include "assembler.h"
#include <blue/core/hash.h>
#include <blue/object/dict.h>
#include <blue/object/number.h>
#include <blue/object/string.h>
#include <ivy/asm/bin.h>
#include <ivy/asm/instr.h>
#include <ivy/ident.h>
#include <ivy/selector.h>
struct block_assembler_scope {
struct assembler_scope s_base;
};
static enum ivy_status init_scope(
struct ivy_assembler *as, struct assembler_scope *scope,
const ivy_assembler_attrib_table attrib)
{
struct ivy_bin_block header = {0};
header.b_index = b_i32_htob((uint32_t)attrib[IVY_ASM_ATTRIB_INDEX]);
assembler_write_data(as, &header, sizeof header);
struct block_assembler_scope *c = (struct block_assembler_scope *)scope;
return IVY_OK;
}
static enum ivy_status put_instr(
struct ivy_assembler *as, struct assembler_scope *scope,
const struct ivy_instr *instr)
{
uint32_t v = 0;
v = R_SET_OPCODE(v, instr->i_op->i_opcode);
switch (instr->i_op->i_layout) {
case IVY_INSTR_X:
break;
case IVY_INSTR_D:
v |= R_SET_D3(v, instr->i_arg[0]);
break;
case IVY_INSTR_R1:
v |= R_SET_R1(v, instr->i_arg[0]);
break;
case IVY_INSTR_R1D:
v |= R_SET_R1(v, instr->i_arg[0]);
v |= R_SET_D2(v, instr->i_arg[1]);
break;
case IVY_INSTR_R2:
v |= R_SET_R1(v, instr->i_arg[0]);
v |= R_SET_R2(v, instr->i_arg[1]);
break;
case IVY_INSTR_R2D:
v |= R_SET_R1(v, instr->i_arg[0]);
v |= R_SET_R2(v, instr->i_arg[1]);
v |= R_SET_D1(v, instr->i_arg[2]);
break;
case IVY_INSTR_R3:
v |= R_SET_R1(v, instr->i_arg[0]);
v |= R_SET_R2(v, instr->i_arg[1]);
v |= R_SET_R3(v, instr->i_arg[2]);
break;
default:
return IVY_ERR_INTERNAL_FAILURE;
}
b_i32 x = b_i32_htob(v);
assembler_write_data(as, &x, sizeof x);
return IVY_OK;
}
const struct assembler_scope_type block_scope_type = {
.s_scope_size = sizeof(struct block_assembler_scope),
.s_init_scope = init_scope,
.s_put_instr = put_instr,
};