#include "assembler.h" #include #include #include #include #include #include #include #include #define R_MASK_OP 0x01800C03u #define R_MASK_R1 0x000003FCu #define R_MASK_R2 0x000FF000u #define R_MASK_R3 0x01800C03u #define R_MASK_D1 0xFE700000u #define R_MASK_D2 0xFE7FF000u #define R_MASK_D3 0xFE7FF3FCu #define R_SET_OPCODE(i, op) \ (((i) & ~R_MASK_OP) | (op & 0x03u) | ((op & 0x0Cu) << 8) \ | ((op & 0x30u) << 19)) #define R_SET_R1(i, r) (((i) & ~R_MASK_R1) | ((r & 0xFFu) << 2)) #define R_SET_R2(i, r) (((i) & ~R_MASK_R2) | ((r & 0xFFu) << 12)) #define R_SET_R3(i, r) \ (((i) & ~R_MASK_R3) | ((r & 0x01u) << 22) | ((r & 0xFEu) << 24)) #define R_SET_D1(i, r) \ (((i) & ~R_MASK_D1) | ((r & 0x07u) << 20) | ((r & 0x3F8u) << 22)) #define R_SET_D2(i, r) \ (((i) & ~R_MASK_D2) | ((r & 0x7FFu) << 12) | ((r & 0x3F800u) << 14)) #define R_SET_D3(i, r) \ (((i) & ~R_MASK_D3) | ((r & 0xFFu) << 2) | ((r & 0x7FF00u) << 4) \ | ((r & 0x3F80000u) << 6)) 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, };