asm: implement a mie backend for ivy assembly generation
This commit is contained in:
@@ -11,5 +11,5 @@ else ()
|
|||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
target_include_directories(ivy-asm PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include/)
|
target_include_directories(ivy-asm PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include/)
|
||||||
target_link_libraries(ivy-asm ivy-common Bluelib::Core Bluelib::Object)
|
target_link_libraries(ivy-asm ivy-common mie Bluelib::Core Bluelib::Object)
|
||||||
target_compile_definitions(ivy-asm PRIVATE IVY_EXPORT=1 IVY_STATIC=${IVY_STATIC})
|
target_compile_definitions(ivy-asm PRIVATE IVY_EXPORT=1 IVY_STATIC=${IVY_STATIC})
|
||||||
307
asm/include/ivy/asm/mie.h
Normal file
307
asm/include/ivy/asm/mie.h
Normal file
@@ -0,0 +1,307 @@
|
|||||||
|
#ifndef IVY_ASM_MIE_H_
|
||||||
|
#define IVY_ASM_MIE_H_
|
||||||
|
|
||||||
|
#include <ivy/misc.h>
|
||||||
|
#include <ivy/opcode.h>
|
||||||
|
|
||||||
|
struct mie_target;
|
||||||
|
|
||||||
|
enum ivy_select_opcode {
|
||||||
|
IVY_SELECT_OP_NONE = IVY_INSTR_NONE,
|
||||||
|
IVY_SELECT_OP_LDR = IVY_INSTR_LDR,
|
||||||
|
IVY_SELECT_OP_STR = IVY_INSTR_STR,
|
||||||
|
IVY_SELECT_OP_PUSH = IVY_INSTR_PUSH,
|
||||||
|
IVY_SELECT_OP_POP = IVY_INSTR_POP,
|
||||||
|
IVY_SELECT_OP_MSG = IVY_INSTR_MSG,
|
||||||
|
IVY_SELECT_OP_ADD = IVY_INSTR_ADD,
|
||||||
|
IVY_SELECT_OP_SUB = IVY_INSTR_SUB,
|
||||||
|
IVY_SELECT_OP_MUL = IVY_INSTR_MUL,
|
||||||
|
IVY_SELECT_OP_DIV = IVY_INSTR_DIV,
|
||||||
|
IVY_SELECT_OP_C_EQ = IVY_INSTR_C_EQ,
|
||||||
|
IVY_SELECT_OP_C_NE = IVY_INSTR_C_NE,
|
||||||
|
IVY_SELECT_OP_C_LT = IVY_INSTR_C_LT,
|
||||||
|
IVY_SELECT_OP_C_LE = IVY_INSTR_C_LE,
|
||||||
|
IVY_SELECT_OP_C_GT = IVY_INSTR_C_GT,
|
||||||
|
IVY_SELECT_OP_C_GE = IVY_INSTR_C_GE,
|
||||||
|
IVY_SELECT_OP_BR = IVY_INSTR_BR,
|
||||||
|
IVY_SELECT_OP_BR_T = IVY_INSTR_BR_T,
|
||||||
|
IVY_SELECT_OP_BR_F = IVY_INSTR_BR_F,
|
||||||
|
IVY_SELECT_OP_OB_C = IVY_INSTR_OB_C,
|
||||||
|
IVY_SELECT_OP_OB_E = IVY_INSTR_OB_E,
|
||||||
|
IVY_SELECT_OP_LAM_C = IVY_INSTR_LAM_C,
|
||||||
|
IVY_SELECT_OP_IT_G = IVY_INSTR_IT_G,
|
||||||
|
IVY_SELECT_OP_IT_N = IVY_INSTR_IT_N,
|
||||||
|
IVY_SELECT_OP_IT_V = IVY_INSTR_IT_V,
|
||||||
|
IVY_SELECT_OP_STK_A = IVY_INSTR_STK_A,
|
||||||
|
IVY_SELECT_OP_STK_F = IVY_INSTR_STK_F,
|
||||||
|
IVY_SELECT_OP_RET = IVY_INSTR_RET,
|
||||||
|
IVY_SELECT_OP_RET_N = IVY_INSTR_RET_N,
|
||||||
|
IVY_SELECT_OP_REGISTER,
|
||||||
|
IVY_SELECT_OP_SELECTOR,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ivy_select_register {
|
||||||
|
IVY_SELECT_REG_X0,
|
||||||
|
IVY_SELECT_REG_X1,
|
||||||
|
IVY_SELECT_REG_X2,
|
||||||
|
IVY_SELECT_REG_X3,
|
||||||
|
IVY_SELECT_REG_X4,
|
||||||
|
IVY_SELECT_REG_X5,
|
||||||
|
IVY_SELECT_REG_X6,
|
||||||
|
IVY_SELECT_REG_X7,
|
||||||
|
IVY_SELECT_REG_X8,
|
||||||
|
IVY_SELECT_REG_X9,
|
||||||
|
IVY_SELECT_REG_X10,
|
||||||
|
IVY_SELECT_REG_X11,
|
||||||
|
IVY_SELECT_REG_X12,
|
||||||
|
IVY_SELECT_REG_X13,
|
||||||
|
IVY_SELECT_REG_X14,
|
||||||
|
IVY_SELECT_REG_X15,
|
||||||
|
IVY_SELECT_REG_X16,
|
||||||
|
IVY_SELECT_REG_X17,
|
||||||
|
IVY_SELECT_REG_X18,
|
||||||
|
IVY_SELECT_REG_X19,
|
||||||
|
IVY_SELECT_REG_X20,
|
||||||
|
IVY_SELECT_REG_X21,
|
||||||
|
IVY_SELECT_REG_X22,
|
||||||
|
IVY_SELECT_REG_X23,
|
||||||
|
IVY_SELECT_REG_X24,
|
||||||
|
IVY_SELECT_REG_X25,
|
||||||
|
IVY_SELECT_REG_X26,
|
||||||
|
IVY_SELECT_REG_X27,
|
||||||
|
IVY_SELECT_REG_X28,
|
||||||
|
IVY_SELECT_REG_X29,
|
||||||
|
IVY_SELECT_REG_X30,
|
||||||
|
IVY_SELECT_REG_X31,
|
||||||
|
IVY_SELECT_REG_X32,
|
||||||
|
IVY_SELECT_REG_X33,
|
||||||
|
IVY_SELECT_REG_X34,
|
||||||
|
IVY_SELECT_REG_X35,
|
||||||
|
IVY_SELECT_REG_X36,
|
||||||
|
IVY_SELECT_REG_X37,
|
||||||
|
IVY_SELECT_REG_X38,
|
||||||
|
IVY_SELECT_REG_X39,
|
||||||
|
IVY_SELECT_REG_X40,
|
||||||
|
IVY_SELECT_REG_X41,
|
||||||
|
IVY_SELECT_REG_X42,
|
||||||
|
IVY_SELECT_REG_X43,
|
||||||
|
IVY_SELECT_REG_X44,
|
||||||
|
IVY_SELECT_REG_X45,
|
||||||
|
IVY_SELECT_REG_X46,
|
||||||
|
IVY_SELECT_REG_X47,
|
||||||
|
IVY_SELECT_REG_X48,
|
||||||
|
IVY_SELECT_REG_X49,
|
||||||
|
IVY_SELECT_REG_X50,
|
||||||
|
IVY_SELECT_REG_X51,
|
||||||
|
IVY_SELECT_REG_X52,
|
||||||
|
IVY_SELECT_REG_X53,
|
||||||
|
IVY_SELECT_REG_X54,
|
||||||
|
IVY_SELECT_REG_X55,
|
||||||
|
IVY_SELECT_REG_X56,
|
||||||
|
IVY_SELECT_REG_X57,
|
||||||
|
IVY_SELECT_REG_X58,
|
||||||
|
IVY_SELECT_REG_X59,
|
||||||
|
IVY_SELECT_REG_X60,
|
||||||
|
IVY_SELECT_REG_X61,
|
||||||
|
IVY_SELECT_REG_X62,
|
||||||
|
IVY_SELECT_REG_X63,
|
||||||
|
IVY_SELECT_REG_X64,
|
||||||
|
IVY_SELECT_REG_X65,
|
||||||
|
IVY_SELECT_REG_X66,
|
||||||
|
IVY_SELECT_REG_X67,
|
||||||
|
IVY_SELECT_REG_X68,
|
||||||
|
IVY_SELECT_REG_X69,
|
||||||
|
IVY_SELECT_REG_X70,
|
||||||
|
IVY_SELECT_REG_X71,
|
||||||
|
IVY_SELECT_REG_X72,
|
||||||
|
IVY_SELECT_REG_X73,
|
||||||
|
IVY_SELECT_REG_X74,
|
||||||
|
IVY_SELECT_REG_X75,
|
||||||
|
IVY_SELECT_REG_X76,
|
||||||
|
IVY_SELECT_REG_X77,
|
||||||
|
IVY_SELECT_REG_X78,
|
||||||
|
IVY_SELECT_REG_X79,
|
||||||
|
IVY_SELECT_REG_X80,
|
||||||
|
IVY_SELECT_REG_X81,
|
||||||
|
IVY_SELECT_REG_X82,
|
||||||
|
IVY_SELECT_REG_X83,
|
||||||
|
IVY_SELECT_REG_X84,
|
||||||
|
IVY_SELECT_REG_X85,
|
||||||
|
IVY_SELECT_REG_X86,
|
||||||
|
IVY_SELECT_REG_X87,
|
||||||
|
IVY_SELECT_REG_X88,
|
||||||
|
IVY_SELECT_REG_X89,
|
||||||
|
IVY_SELECT_REG_X90,
|
||||||
|
IVY_SELECT_REG_X91,
|
||||||
|
IVY_SELECT_REG_X92,
|
||||||
|
IVY_SELECT_REG_X93,
|
||||||
|
IVY_SELECT_REG_X94,
|
||||||
|
IVY_SELECT_REG_X95,
|
||||||
|
IVY_SELECT_REG_X96,
|
||||||
|
IVY_SELECT_REG_X97,
|
||||||
|
IVY_SELECT_REG_X98,
|
||||||
|
IVY_SELECT_REG_X99,
|
||||||
|
IVY_SELECT_REG_X100,
|
||||||
|
IVY_SELECT_REG_X101,
|
||||||
|
IVY_SELECT_REG_X102,
|
||||||
|
IVY_SELECT_REG_X103,
|
||||||
|
IVY_SELECT_REG_X104,
|
||||||
|
IVY_SELECT_REG_X105,
|
||||||
|
IVY_SELECT_REG_X106,
|
||||||
|
IVY_SELECT_REG_X107,
|
||||||
|
IVY_SELECT_REG_X108,
|
||||||
|
IVY_SELECT_REG_X109,
|
||||||
|
IVY_SELECT_REG_X110,
|
||||||
|
IVY_SELECT_REG_X111,
|
||||||
|
IVY_SELECT_REG_X112,
|
||||||
|
IVY_SELECT_REG_X113,
|
||||||
|
IVY_SELECT_REG_X114,
|
||||||
|
IVY_SELECT_REG_X115,
|
||||||
|
IVY_SELECT_REG_X116,
|
||||||
|
IVY_SELECT_REG_X117,
|
||||||
|
IVY_SELECT_REG_X118,
|
||||||
|
IVY_SELECT_REG_X119,
|
||||||
|
IVY_SELECT_REG_X120,
|
||||||
|
IVY_SELECT_REG_X121,
|
||||||
|
IVY_SELECT_REG_X122,
|
||||||
|
IVY_SELECT_REG_X123,
|
||||||
|
IVY_SELECT_REG_X124,
|
||||||
|
IVY_SELECT_REG_X125,
|
||||||
|
IVY_SELECT_REG_X126,
|
||||||
|
IVY_SELECT_REG_X127,
|
||||||
|
IVY_SELECT_REG_X128,
|
||||||
|
IVY_SELECT_REG_X129,
|
||||||
|
IVY_SELECT_REG_X130,
|
||||||
|
IVY_SELECT_REG_X131,
|
||||||
|
IVY_SELECT_REG_X132,
|
||||||
|
IVY_SELECT_REG_X133,
|
||||||
|
IVY_SELECT_REG_X134,
|
||||||
|
IVY_SELECT_REG_X135,
|
||||||
|
IVY_SELECT_REG_X136,
|
||||||
|
IVY_SELECT_REG_X137,
|
||||||
|
IVY_SELECT_REG_X138,
|
||||||
|
IVY_SELECT_REG_X139,
|
||||||
|
IVY_SELECT_REG_X140,
|
||||||
|
IVY_SELECT_REG_X141,
|
||||||
|
IVY_SELECT_REG_X142,
|
||||||
|
IVY_SELECT_REG_X143,
|
||||||
|
IVY_SELECT_REG_X144,
|
||||||
|
IVY_SELECT_REG_X145,
|
||||||
|
IVY_SELECT_REG_X146,
|
||||||
|
IVY_SELECT_REG_X147,
|
||||||
|
IVY_SELECT_REG_X148,
|
||||||
|
IVY_SELECT_REG_X149,
|
||||||
|
IVY_SELECT_REG_X150,
|
||||||
|
IVY_SELECT_REG_X151,
|
||||||
|
IVY_SELECT_REG_X152,
|
||||||
|
IVY_SELECT_REG_X153,
|
||||||
|
IVY_SELECT_REG_X154,
|
||||||
|
IVY_SELECT_REG_X155,
|
||||||
|
IVY_SELECT_REG_X156,
|
||||||
|
IVY_SELECT_REG_X157,
|
||||||
|
IVY_SELECT_REG_X158,
|
||||||
|
IVY_SELECT_REG_X159,
|
||||||
|
IVY_SELECT_REG_X160,
|
||||||
|
IVY_SELECT_REG_X161,
|
||||||
|
IVY_SELECT_REG_X162,
|
||||||
|
IVY_SELECT_REG_X163,
|
||||||
|
IVY_SELECT_REG_X164,
|
||||||
|
IVY_SELECT_REG_X165,
|
||||||
|
IVY_SELECT_REG_X166,
|
||||||
|
IVY_SELECT_REG_X167,
|
||||||
|
IVY_SELECT_REG_X168,
|
||||||
|
IVY_SELECT_REG_X169,
|
||||||
|
IVY_SELECT_REG_X170,
|
||||||
|
IVY_SELECT_REG_X171,
|
||||||
|
IVY_SELECT_REG_X172,
|
||||||
|
IVY_SELECT_REG_X173,
|
||||||
|
IVY_SELECT_REG_X174,
|
||||||
|
IVY_SELECT_REG_X175,
|
||||||
|
IVY_SELECT_REG_X176,
|
||||||
|
IVY_SELECT_REG_X177,
|
||||||
|
IVY_SELECT_REG_X178,
|
||||||
|
IVY_SELECT_REG_X179,
|
||||||
|
IVY_SELECT_REG_X180,
|
||||||
|
IVY_SELECT_REG_X181,
|
||||||
|
IVY_SELECT_REG_X182,
|
||||||
|
IVY_SELECT_REG_X183,
|
||||||
|
IVY_SELECT_REG_X184,
|
||||||
|
IVY_SELECT_REG_X185,
|
||||||
|
IVY_SELECT_REG_X186,
|
||||||
|
IVY_SELECT_REG_X187,
|
||||||
|
IVY_SELECT_REG_X188,
|
||||||
|
IVY_SELECT_REG_X189,
|
||||||
|
IVY_SELECT_REG_X190,
|
||||||
|
IVY_SELECT_REG_X191,
|
||||||
|
IVY_SELECT_REG_X192,
|
||||||
|
IVY_SELECT_REG_X193,
|
||||||
|
IVY_SELECT_REG_X194,
|
||||||
|
IVY_SELECT_REG_X195,
|
||||||
|
IVY_SELECT_REG_X196,
|
||||||
|
IVY_SELECT_REG_X197,
|
||||||
|
IVY_SELECT_REG_X198,
|
||||||
|
IVY_SELECT_REG_X199,
|
||||||
|
IVY_SELECT_REG_X200,
|
||||||
|
IVY_SELECT_REG_X201,
|
||||||
|
IVY_SELECT_REG_X202,
|
||||||
|
IVY_SELECT_REG_X203,
|
||||||
|
IVY_SELECT_REG_X204,
|
||||||
|
IVY_SELECT_REG_X205,
|
||||||
|
IVY_SELECT_REG_X206,
|
||||||
|
IVY_SELECT_REG_X207,
|
||||||
|
IVY_SELECT_REG_X208,
|
||||||
|
IVY_SELECT_REG_X209,
|
||||||
|
IVY_SELECT_REG_X210,
|
||||||
|
IVY_SELECT_REG_X211,
|
||||||
|
IVY_SELECT_REG_X212,
|
||||||
|
IVY_SELECT_REG_X213,
|
||||||
|
IVY_SELECT_REG_X214,
|
||||||
|
IVY_SELECT_REG_X215,
|
||||||
|
IVY_SELECT_REG_X216,
|
||||||
|
IVY_SELECT_REG_X217,
|
||||||
|
IVY_SELECT_REG_X218,
|
||||||
|
IVY_SELECT_REG_X219,
|
||||||
|
IVY_SELECT_REG_X220,
|
||||||
|
IVY_SELECT_REG_X221,
|
||||||
|
IVY_SELECT_REG_X222,
|
||||||
|
IVY_SELECT_REG_X223,
|
||||||
|
IVY_SELECT_REG_X224,
|
||||||
|
IVY_SELECT_REG_X225,
|
||||||
|
IVY_SELECT_REG_X226,
|
||||||
|
IVY_SELECT_REG_X227,
|
||||||
|
IVY_SELECT_REG_X228,
|
||||||
|
IVY_SELECT_REG_X229,
|
||||||
|
IVY_SELECT_REG_X230,
|
||||||
|
IVY_SELECT_REG_X231,
|
||||||
|
IVY_SELECT_REG_X232,
|
||||||
|
IVY_SELECT_REG_X233,
|
||||||
|
IVY_SELECT_REG_X234,
|
||||||
|
IVY_SELECT_REG_X235,
|
||||||
|
IVY_SELECT_REG_X236,
|
||||||
|
IVY_SELECT_REG_X237,
|
||||||
|
IVY_SELECT_REG_X238,
|
||||||
|
IVY_SELECT_REG_X239,
|
||||||
|
IVY_SELECT_REG_X240,
|
||||||
|
IVY_SELECT_REG_X241,
|
||||||
|
IVY_SELECT_REG_X242,
|
||||||
|
IVY_SELECT_REG_X243,
|
||||||
|
IVY_SELECT_REG_X244,
|
||||||
|
IVY_SELECT_REG_X245,
|
||||||
|
IVY_SELECT_REG_X246,
|
||||||
|
IVY_SELECT_REG_X247,
|
||||||
|
IVY_SELECT_REG_X248,
|
||||||
|
IVY_SELECT_REG_X249,
|
||||||
|
IVY_SELECT_REG_X250,
|
||||||
|
IVY_SELECT_REG_X251,
|
||||||
|
IVY_SELECT_REG_X252,
|
||||||
|
IVY_SELECT_REG_X253,
|
||||||
|
IVY_SELECT_REG_X254,
|
||||||
|
IVY_SELECT_REG_X255,
|
||||||
|
IVY_SELECT_REG_X256,
|
||||||
|
IVY_SELECT_REG_SP,
|
||||||
|
IVY_SELECT_REG_BP,
|
||||||
|
};
|
||||||
|
|
||||||
|
IVY_API const struct mie_target *ivy_asm_mie_target(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
415
asm/mie/select.c
Normal file
415
asm/mie/select.c
Normal file
@@ -0,0 +1,415 @@
|
|||||||
|
#include "mie/select/opcode.h"
|
||||||
|
|
||||||
|
#include <ivy/asm/mie.h>
|
||||||
|
#include <ivy/opcode.h>
|
||||||
|
#include <mie/ctx.h>
|
||||||
|
#include <mie/ir/const.h>
|
||||||
|
#include <mie/ir/msg.h>
|
||||||
|
#include <mie/select/builder.h>
|
||||||
|
#include <mie/select/graph.h>
|
||||||
|
#include <mie/select/node.h>
|
||||||
|
#include <mie/target/select.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define NODE_NAME(op) \
|
||||||
|
case IVY_SELECT_OP_##op: \
|
||||||
|
return snprintf(out, max, #op)
|
||||||
|
|
||||||
|
#define NODE_NAME_(op, name) \
|
||||||
|
case IVY_SELECT_OP_##op: \
|
||||||
|
return snprintf(out, max, name)
|
||||||
|
|
||||||
|
static size_t node_name(
|
||||||
|
const struct mie_target *target, unsigned int opcode, char *out, size_t max)
|
||||||
|
{
|
||||||
|
switch (opcode) {
|
||||||
|
NODE_NAME(LDR);
|
||||||
|
NODE_NAME(STR);
|
||||||
|
NODE_NAME(PUSH);
|
||||||
|
NODE_NAME(POP);
|
||||||
|
NODE_NAME(MSG);
|
||||||
|
NODE_NAME(ADD);
|
||||||
|
NODE_NAME(SUB);
|
||||||
|
NODE_NAME(MUL);
|
||||||
|
NODE_NAME(DIV);
|
||||||
|
NODE_NAME_(C_EQ, "C.EQ");
|
||||||
|
NODE_NAME_(C_NE, "C.NE");
|
||||||
|
NODE_NAME_(C_LT, "C.LT");
|
||||||
|
NODE_NAME_(C_LE, "C.LE");
|
||||||
|
NODE_NAME_(C_GT, "C.GT");
|
||||||
|
NODE_NAME_(C_GE, "C.GE");
|
||||||
|
NODE_NAME(BR);
|
||||||
|
NODE_NAME_(BR_T, "BR.T");
|
||||||
|
NODE_NAME_(BR_F, "BR.F");
|
||||||
|
NODE_NAME_(OB_C, "OB.C");
|
||||||
|
NODE_NAME_(OB_E, "OB.E");
|
||||||
|
NODE_NAME_(LAM_C, "LAM.C");
|
||||||
|
NODE_NAME_(IT_G, "IT.G");
|
||||||
|
NODE_NAME_(IT_N, "IT.N");
|
||||||
|
NODE_NAME_(IT_V, "IT.V");
|
||||||
|
NODE_NAME_(STK_A, "STK.A");
|
||||||
|
NODE_NAME_(STK_F, "STK.F");
|
||||||
|
NODE_NAME(RET);
|
||||||
|
NODE_NAME_(RET_N, "RET.N");
|
||||||
|
NODE_NAME_(REGISTER, "Register");
|
||||||
|
NODE_NAME_(SELECTOR, "Selector");
|
||||||
|
default:
|
||||||
|
return snprintf(out, max, "UNKNOWN");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum mie_status get_sp_register(
|
||||||
|
const struct mie_target *target, struct mie_select_builder *builder,
|
||||||
|
struct mie_select_value *out)
|
||||||
|
{
|
||||||
|
struct mie_ctx *ctx = mie_select_builder_get_ctx(builder);
|
||||||
|
struct mie_type *ptr_type = mie_ctx_get_type(ctx, MIE_TYPE_PTR);
|
||||||
|
|
||||||
|
struct mie_select_node *sp_node = mie_select_builder_find_node_with_ivalue(
|
||||||
|
builder, target, IVY_SELECT_OP_REGISTER, IVY_SELECT_REG_SP);
|
||||||
|
|
||||||
|
if (sp_node) {
|
||||||
|
mie_select_node_get_value(sp_node, ptr_type, 0, out);
|
||||||
|
return MIE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_select_graph *graph = mie_select_builder_get_graph(builder);
|
||||||
|
enum mie_status status = mie_select_graph_get_node(
|
||||||
|
graph, target, IVY_SELECT_OP_REGISTER, NULL, 0, &ptr_type, 1,
|
||||||
|
&sp_node);
|
||||||
|
if (status != MIE_SUCCESS) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
sp_node->n_value.i = IVY_SELECT_REG_SP;
|
||||||
|
mie_select_node_set_description(sp_node, "$sp");
|
||||||
|
mie_select_node_get_value(sp_node, ptr_type, 0, out);
|
||||||
|
return MIE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum mie_status get_selector(
|
||||||
|
const struct mie_target *target, struct mie_select_builder *builder,
|
||||||
|
struct mie_selector *sel, struct mie_select_value *out)
|
||||||
|
{
|
||||||
|
struct mie_ctx *ctx = mie_select_builder_get_ctx(builder);
|
||||||
|
struct mie_type *ptr_type = mie_ctx_get_type(ctx, MIE_TYPE_PTR);
|
||||||
|
struct mie_select_graph *graph = mie_select_builder_get_graph(builder);
|
||||||
|
|
||||||
|
b_queue *nodes = &graph->g_nodes;
|
||||||
|
b_queue_iterator it;
|
||||||
|
b_queue_foreach (&it, nodes) {
|
||||||
|
struct mie_select_node *node
|
||||||
|
= b_unbox(struct mie_select_node, it.entry, n_entry);
|
||||||
|
|
||||||
|
if (node->n_target != target) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node->n_opcode != IVY_SELECT_OP_SELECTOR) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!node->n_value.v || !mie_value_is_selector(node->n_value.v)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_selector *sel_node = (struct mie_selector *)node;
|
||||||
|
if (strcmp(sel->sel_value, sel_node->sel_value) != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
mie_select_node_get_value(node, ptr_type, 0, out);
|
||||||
|
return MIE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_select_node *sel_node;
|
||||||
|
enum mie_status status = mie_select_graph_get_node(
|
||||||
|
graph, target, IVY_SELECT_OP_SELECTOR, NULL, 0, &ptr_type, 1,
|
||||||
|
&sel_node);
|
||||||
|
if (status != MIE_SUCCESS) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
sel_node->n_value.v = MIE_VALUE(sel);
|
||||||
|
mie_select_node_set_description(sel_node, "%s", sel->sel_value);
|
||||||
|
mie_select_node_get_value(sel_node, ptr_type, 0, out);
|
||||||
|
|
||||||
|
return MIE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum mie_status load_selector(
|
||||||
|
const struct mie_target *target, struct mie_select_builder *builder,
|
||||||
|
struct mie_select_value *sel, struct mie_select_value *out)
|
||||||
|
{
|
||||||
|
struct mie_ctx *ctx = mie_select_builder_get_ctx(builder);
|
||||||
|
struct mie_type *id_type = mie_ctx_get_type(ctx, MIE_TYPE_ID);
|
||||||
|
struct mie_select_graph *graph = mie_select_builder_get_graph(builder);
|
||||||
|
struct mie_select_node *load_sel;
|
||||||
|
|
||||||
|
struct mie_select_value *operands[] = {
|
||||||
|
&graph->g_entry,
|
||||||
|
sel,
|
||||||
|
};
|
||||||
|
const size_t nr_operands = sizeof operands / sizeof operands[0];
|
||||||
|
|
||||||
|
struct mie_type *results[] = {
|
||||||
|
id_type,
|
||||||
|
};
|
||||||
|
const size_t nr_results = sizeof results / sizeof results[0];
|
||||||
|
|
||||||
|
enum mie_status status = mie_select_graph_get_node(
|
||||||
|
graph, mie_target_builtin(), MIE_SELECT_OP_LOAD, operands,
|
||||||
|
nr_operands, results, nr_results, &load_sel);
|
||||||
|
if (status != MIE_SUCCESS) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
mie_select_node_get_value(load_sel, id_type, 0, out);
|
||||||
|
return MIE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum mie_status create_stack_alloc(
|
||||||
|
const struct mie_target *target, struct mie_select_builder *builder,
|
||||||
|
size_t count, struct mie_select_value *incoming_chain,
|
||||||
|
struct mie_select_value *out)
|
||||||
|
{
|
||||||
|
struct mie_select_node *alloc;
|
||||||
|
enum mie_status status;
|
||||||
|
|
||||||
|
struct mie_ctx *ctx = mie_select_builder_get_ctx(builder);
|
||||||
|
struct mie_type *chain = mie_ctx_get_type(ctx, MIE_TYPE_OTHER);
|
||||||
|
struct mie_type *i32 = mie_ctx_get_int_type(ctx, 32);
|
||||||
|
|
||||||
|
struct mie_select_value count_value;
|
||||||
|
mie_select_builder_get_const(builder, count, &count_value);
|
||||||
|
|
||||||
|
struct mie_select_value *operands[] = {
|
||||||
|
&count_value,
|
||||||
|
incoming_chain,
|
||||||
|
};
|
||||||
|
const size_t nr_operands = sizeof operands / sizeof operands[0];
|
||||||
|
|
||||||
|
struct mie_select_graph *graph = mie_select_builder_get_graph(builder);
|
||||||
|
status = mie_select_graph_get_node(
|
||||||
|
graph, target, IVY_SELECT_OP_STK_A, operands, nr_operands,
|
||||||
|
&chain, 1, &alloc);
|
||||||
|
if (status != MIE_SUCCESS) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
mie_select_node_get_value(alloc, chain, 0, out);
|
||||||
|
mie_select_node_set_description(
|
||||||
|
alloc, "(allocate %zu slots on stack)", count);
|
||||||
|
|
||||||
|
return MIE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum mie_status create_stack_free(
|
||||||
|
const struct mie_target *target, struct mie_select_builder *builder,
|
||||||
|
size_t count, struct mie_select_value *incoming_chain,
|
||||||
|
struct mie_select_value *out)
|
||||||
|
{
|
||||||
|
struct mie_select_node *free_node;
|
||||||
|
enum mie_status status;
|
||||||
|
|
||||||
|
struct mie_ctx *ctx = mie_select_builder_get_ctx(builder);
|
||||||
|
struct mie_type *chain = mie_ctx_get_type(ctx, MIE_TYPE_OTHER);
|
||||||
|
struct mie_type *i32 = mie_ctx_get_int_type(ctx, 32);
|
||||||
|
|
||||||
|
struct mie_select_value count_value;
|
||||||
|
mie_select_builder_get_const(builder, count, &count_value);
|
||||||
|
|
||||||
|
struct mie_select_value *operands[] = {
|
||||||
|
&count_value,
|
||||||
|
incoming_chain,
|
||||||
|
};
|
||||||
|
const size_t nr_operands = sizeof operands / sizeof operands[0];
|
||||||
|
|
||||||
|
struct mie_select_graph *graph = mie_select_builder_get_graph(builder);
|
||||||
|
status = mie_select_graph_get_node(
|
||||||
|
graph, target, IVY_SELECT_OP_STK_F, operands, nr_operands,
|
||||||
|
&chain, 1, &free_node);
|
||||||
|
if (status != MIE_SUCCESS) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
mie_select_node_set_description(
|
||||||
|
free_node, "(free %zu slots on stack)", count);
|
||||||
|
mie_select_node_get_value(free_node, chain, 0, out);
|
||||||
|
|
||||||
|
return MIE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum mie_status create_chain_group(
|
||||||
|
const struct mie_target *target, struct mie_select_builder *builder,
|
||||||
|
struct mie_select_value **incoming_chains, size_t count,
|
||||||
|
struct mie_select_value *out)
|
||||||
|
{
|
||||||
|
struct mie_select_graph *graph = mie_select_builder_get_graph(builder);
|
||||||
|
struct mie_ctx *ctx = mie_select_builder_get_ctx(builder);
|
||||||
|
struct mie_select_node *group = NULL;
|
||||||
|
|
||||||
|
struct mie_type *chain_type = mie_ctx_get_type(ctx, MIE_TYPE_OTHER);
|
||||||
|
|
||||||
|
enum mie_status status = mie_select_graph_get_node(
|
||||||
|
graph, mie_target_builtin(), MIE_SELECT_OP_CHAIN_GROUP,
|
||||||
|
incoming_chains, count, &chain_type, 1, &group);
|
||||||
|
if (status != MIE_SUCCESS) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
mie_select_node_get_value(group, chain_type, 0, out);
|
||||||
|
return MIE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum mie_status put_param_on_stack(
|
||||||
|
const struct mie_target *target, struct mie_select_builder *builder,
|
||||||
|
struct mie_select_value *in_chain, struct mie_select_value *param,
|
||||||
|
size_t offset, struct mie_select_value *out_chain)
|
||||||
|
{
|
||||||
|
struct mie_select_value sp;
|
||||||
|
struct mie_select_value offset_value;
|
||||||
|
struct mie_type *chain_type;
|
||||||
|
|
||||||
|
struct mie_select_graph *graph = mie_select_builder_get_graph(builder);
|
||||||
|
struct mie_ctx *ctx = mie_select_builder_get_ctx(builder);
|
||||||
|
|
||||||
|
get_sp_register(target, builder, &sp);
|
||||||
|
mie_select_builder_get_const(builder, offset, &offset_value);
|
||||||
|
chain_type = mie_ctx_get_type(ctx, MIE_TYPE_OTHER);
|
||||||
|
|
||||||
|
struct mie_select_value *operands[] = {
|
||||||
|
in_chain,
|
||||||
|
param,
|
||||||
|
&sp,
|
||||||
|
&offset_value,
|
||||||
|
};
|
||||||
|
const size_t nr_operands = sizeof operands / sizeof operands[0];
|
||||||
|
|
||||||
|
struct mie_select_node *store;
|
||||||
|
enum mie_status status = mie_select_graph_get_node(
|
||||||
|
graph, target, IVY_SELECT_OP_STR, operands, nr_operands,
|
||||||
|
&chain_type, 1, &store);
|
||||||
|
|
||||||
|
mie_select_node_set_description(
|
||||||
|
store, "(store N%zu on stack + %zu)", param->v_node->n_id, offset);
|
||||||
|
mie_select_node_get_value(store, chain_type, 0, out_chain);
|
||||||
|
return MIE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum mie_status lower_msg(
|
||||||
|
const struct mie_target *target, struct mie_select_builder *builder,
|
||||||
|
struct mie_msg *msg, struct mie_select_value *result)
|
||||||
|
{
|
||||||
|
enum mie_status status = MIE_SUCCESS;
|
||||||
|
struct mie_select_graph *graph = mie_select_builder_get_graph(builder);
|
||||||
|
struct mie_ctx *ctx = mie_select_builder_get_ctx(builder);
|
||||||
|
|
||||||
|
struct mie_select_value **param_chains = calloc(
|
||||||
|
b_max(size_t, 2, msg->msg_nr_args + 1),
|
||||||
|
sizeof(struct mie_select_value *));
|
||||||
|
size_t nr_param_chains = 0;
|
||||||
|
struct mie_select_value *chain, *recipient, nr_args;
|
||||||
|
|
||||||
|
chain = mie_select_builder_get_mem_access(builder, msg->msg_recipient);
|
||||||
|
recipient = mie_select_builder_get_value(builder, msg->msg_recipient);
|
||||||
|
mie_select_builder_get_const(builder, msg->msg_nr_args, &nr_args);
|
||||||
|
|
||||||
|
if (chain) {
|
||||||
|
param_chains[nr_param_chains++] = chain;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < msg->msg_nr_args; i++) {
|
||||||
|
struct mie_select_value *chain = mie_select_builder_get_mem_access(
|
||||||
|
builder, msg->msg_args[i]);
|
||||||
|
if (chain) {
|
||||||
|
param_chains[nr_param_chains++] = chain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nr_param_chains == 0) {
|
||||||
|
param_chains[nr_param_chains++] = &graph->g_entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_select_value pre_arg_init_chain, post_arg_init_chain;
|
||||||
|
if (nr_param_chains > 1) {
|
||||||
|
status = create_chain_group(
|
||||||
|
target, builder, param_chains, nr_param_chains,
|
||||||
|
&pre_arg_init_chain);
|
||||||
|
} else {
|
||||||
|
pre_arg_init_chain = *param_chains[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_select_value stack_alloc, stack_free;
|
||||||
|
status = create_stack_alloc(
|
||||||
|
target, builder, msg->msg_nr_args, &pre_arg_init_chain,
|
||||||
|
&stack_alloc);
|
||||||
|
if (status != MIE_SUCCESS) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_select_value *stack_chains = calloc(
|
||||||
|
b_max(size_t, 1, msg->msg_nr_args),
|
||||||
|
sizeof(struct mie_select_value));
|
||||||
|
size_t nr_stack_chains = 0;
|
||||||
|
nr_param_chains = 0;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < msg->msg_nr_args; i++) {
|
||||||
|
struct mie_select_value *param_value
|
||||||
|
= mie_select_builder_get_value(builder, msg->msg_args[i]);
|
||||||
|
status = put_param_on_stack(
|
||||||
|
target, builder, &stack_alloc, param_value, i,
|
||||||
|
&stack_chains[nr_stack_chains]);
|
||||||
|
param_chains[nr_param_chains] = &stack_chains[nr_stack_chains];
|
||||||
|
|
||||||
|
nr_param_chains++;
|
||||||
|
nr_stack_chains++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nr_param_chains > 1) {
|
||||||
|
status = create_chain_group(
|
||||||
|
target, builder, param_chains, nr_param_chains,
|
||||||
|
&post_arg_init_chain);
|
||||||
|
} else {
|
||||||
|
post_arg_init_chain = *param_chains[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
free(param_chains);
|
||||||
|
free(stack_chains);
|
||||||
|
|
||||||
|
struct mie_select_value sel, load_sel;
|
||||||
|
get_selector(target, builder, MIE_SELECTOR(msg->msg_selector), &sel);
|
||||||
|
load_selector(target, builder, &sel, &load_sel);
|
||||||
|
|
||||||
|
struct mie_select_value *msg_params[] = {
|
||||||
|
&post_arg_init_chain,
|
||||||
|
recipient,
|
||||||
|
&load_sel,
|
||||||
|
&nr_args,
|
||||||
|
};
|
||||||
|
const size_t nr_msg_params = sizeof msg_params / sizeof msg_params[0];
|
||||||
|
|
||||||
|
struct mie_type *msg_results[] = {
|
||||||
|
mie_ctx_get_type(ctx, MIE_TYPE_OTHER),
|
||||||
|
mie_ctx_get_type(ctx, MIE_TYPE_GLUE),
|
||||||
|
};
|
||||||
|
const size_t nr_msg_results = sizeof msg_results / sizeof msg_results[0];
|
||||||
|
|
||||||
|
struct mie_select_node *msg_node;
|
||||||
|
status = mie_select_graph_get_node(
|
||||||
|
graph, target, IVY_SELECT_OP_MSG, msg_params, nr_msg_params,
|
||||||
|
msg_results, nr_msg_results, &msg_node);
|
||||||
|
|
||||||
|
result->v_node = msg_node;
|
||||||
|
result->v_index = 0;
|
||||||
|
|
||||||
|
return MIE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct mie_target_select_ops __ivy_select_ops = {
|
||||||
|
.s_node_name = node_name,
|
||||||
|
.s_lower_msg = lower_msg,
|
||||||
|
};
|
||||||
13
asm/mie/target.c
Normal file
13
asm/mie/target.c
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#include <mie/target/target.h>
|
||||||
|
|
||||||
|
extern const struct mie_target_select_ops __ivy_select_ops;
|
||||||
|
|
||||||
|
static const struct mie_target ivy_target = {
|
||||||
|
.t_name = "Ivy",
|
||||||
|
.t_select = &__ivy_select_ops,
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct mie_target *ivy_asm_mie_target(void)
|
||||||
|
{
|
||||||
|
return &ivy_target;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user