mirror of
https://github.com/danog/ir.git
synced 2024-12-04 10:39:38 +01:00
Improve LLVM loader support (incomplete)
This commit is contained in:
parent
1eaf5531e5
commit
a2c6f98e75
37
ir.g
37
ir.g
@ -120,6 +120,7 @@ static void ir_check_indefined_vars(ir_parser_ctx *p)
|
|||||||
/* forward declarations */
|
/* forward declarations */
|
||||||
static void yy_error(const char *msg);
|
static void yy_error(const char *msg);
|
||||||
static void yy_error_sym(const char *msg, int sym);
|
static void yy_error_sym(const char *msg, int sym);
|
||||||
|
static void yy_error_str(const char *msg, const char *str);
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -239,7 +240,35 @@ ir_sym_data(ir_loader *loader):
|
|||||||
{uint8_t t = 0;}
|
{uint8_t t = 0;}
|
||||||
{ir_val val;}
|
{ir_val val;}
|
||||||
{void *p;}
|
{void *p;}
|
||||||
type(&t) const(t, &val)
|
{const char *name;}
|
||||||
|
{size_t name_len;}
|
||||||
|
{char buf[256];}
|
||||||
|
type(&t)
|
||||||
|
(
|
||||||
|
"sym" "(" ID(&name, &name_len) ")"
|
||||||
|
{
|
||||||
|
if (loader->sym_data_ref) {
|
||||||
|
if (name_len > 255) yy_error("name too long");
|
||||||
|
memcpy(buf, name, name_len);
|
||||||
|
buf[name_len] = 0;
|
||||||
|
if (!loader->sym_data_ref(loader, IR_SYM, buf)) {
|
||||||
|
yy_error("sym_data_ref error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
| "func" "(" ID(&name, &name_len) ")"
|
||||||
|
{
|
||||||
|
if (loader->sym_data_ref) {
|
||||||
|
if (name_len > 255) yy_error("name too long");
|
||||||
|
memcpy(buf, name, name_len);
|
||||||
|
buf[name_len] = 0;
|
||||||
|
if (!loader->sym_data_ref(loader, IR_FUNC, buf)) {
|
||||||
|
yy_error("sym_data_ref error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
const(t, &val)
|
||||||
{
|
{
|
||||||
if (loader->sym_data) {
|
if (loader->sym_data) {
|
||||||
switch (ir_type_size[t]) {
|
switch (ir_type_size[t]) {
|
||||||
@ -256,6 +285,7 @@ ir_sym_data(ir_loader *loader):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
)
|
||||||
;
|
;
|
||||||
|
|
||||||
ir_func(ir_parser_ctx *p):
|
ir_func(ir_parser_ctx *p):
|
||||||
@ -542,6 +572,11 @@ static void yy_error_sym(const char *msg, int sym) {
|
|||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void yy_error_str(const char *msg, const char *str) {
|
||||||
|
fprintf(stderr, "ERROR: %s '%s' at line %d\n", msg, str, yy_line);
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
int ir_load(ir_loader *loader, FILE *f) {
|
int ir_load(ir_loader *loader, FILE *f) {
|
||||||
long pos, end;
|
long pos, end;
|
||||||
|
|
||||||
|
1
ir.h
1
ir.h
@ -766,6 +766,7 @@ struct _ir_loader {
|
|||||||
uint32_t flags, ir_type ret_type, uint32_t params_count, ir_type *param_types);
|
uint32_t flags, ir_type ret_type, uint32_t params_count, ir_type *param_types);
|
||||||
bool (*sym_dcl) (ir_loader *loader, const char *name, uint32_t flags, size_t size, bool has_data);
|
bool (*sym_dcl) (ir_loader *loader, const char *name, uint32_t flags, size_t size, bool has_data);
|
||||||
bool (*sym_data) (ir_loader *loader, ir_type type, uint32_t count, const void *data);
|
bool (*sym_data) (ir_loader *loader, ir_type type, uint32_t count, const void *data);
|
||||||
|
bool (*sym_data_ref) (ir_loader *loader, ir_op op, const char *ref);
|
||||||
bool (*sym_data_end) (ir_loader *loader);
|
bool (*sym_data_end) (ir_loader *loader);
|
||||||
bool (*func_init) (ir_loader *loader, ir_ctx *ctx, const char *name);
|
bool (*func_init) (ir_loader *loader, ir_ctx *ctx, const char *name);
|
||||||
bool (*func_process) (ir_loader *loader, ir_ctx *ctx, const char *name);
|
bool (*func_process) (ir_loader *loader, ir_ctx *ctx, const char *name);
|
||||||
|
183
ir_load.c
183
ir_load.c
@ -102,6 +102,7 @@ static void ir_check_indefined_vars(ir_parser_ctx *p)
|
|||||||
/* forward declarations */
|
/* forward declarations */
|
||||||
static void yy_error(const char *msg);
|
static void yy_error(const char *msg);
|
||||||
static void yy_error_sym(const char *msg, int sym);
|
static void yy_error_sym(const char *msg, int sym);
|
||||||
|
static void yy_error_str(const char *msg, const char *str);
|
||||||
|
|
||||||
#define YYPOS cpos
|
#define YYPOS cpos
|
||||||
#define YYEND cend
|
#define YYEND cend
|
||||||
@ -118,13 +119,13 @@ static void yy_error_sym(const char *msg, int sym);
|
|||||||
#define YY_CONST 9
|
#define YY_CONST 9
|
||||||
#define YY__LBRACK 10
|
#define YY__LBRACK 10
|
||||||
#define YY__RBRACK 11
|
#define YY__RBRACK 11
|
||||||
#define YY_FUNC 12
|
#define YY_SYM 12
|
||||||
#define YY__LPAREN 13
|
#define YY__LPAREN 13
|
||||||
#define YY_VOID 14
|
#define YY__RPAREN 14
|
||||||
#define YY__POINT_POINT_POINT 15
|
#define YY_FUNC 15
|
||||||
#define YY__RPAREN 16
|
#define YY_VOID 16
|
||||||
#define YY__COLON 17
|
#define YY__POINT_POINT_POINT 17
|
||||||
#define YY_SYM 18
|
#define YY__COLON 18
|
||||||
#define YY_FUNC_ADDR 19
|
#define YY_FUNC_ADDR 19
|
||||||
#define YY__SLASH 20
|
#define YY__SLASH 20
|
||||||
#define YY_NULL 21
|
#define YY_NULL 21
|
||||||
@ -155,13 +156,13 @@ static const char * sym_name[] = {
|
|||||||
"const",
|
"const",
|
||||||
"[",
|
"[",
|
||||||
"]",
|
"]",
|
||||||
"func",
|
"sym",
|
||||||
"(",
|
"(",
|
||||||
|
")",
|
||||||
|
"func",
|
||||||
"void",
|
"void",
|
||||||
"...",
|
"...",
|
||||||
")",
|
|
||||||
":",
|
":",
|
||||||
"sym",
|
|
||||||
"func_addr",
|
"func_addr",
|
||||||
"/",
|
"/",
|
||||||
"null",
|
"null",
|
||||||
@ -184,6 +185,63 @@ static const char * sym_name[] = {
|
|||||||
#define YY_IN_SET(sym, set, bitset) \
|
#define YY_IN_SET(sym, set, bitset) \
|
||||||
(bitset[sym>>3] & (1 << (sym & 0x7)))
|
(bitset[sym>>3] & (1 << (sym & 0x7)))
|
||||||
|
|
||||||
|
size_t yy_escape(char *buf, unsigned char ch)
|
||||||
|
{
|
||||||
|
switch (ch) {
|
||||||
|
case '\\': buf[0] = '\\'; buf[1] = '\\'; return 2;
|
||||||
|
case '\'': buf[0] = '\\'; buf[1] = '\''; return 2;
|
||||||
|
case '\"': buf[0] = '\\'; buf[1] = '\"'; return 2;
|
||||||
|
case '\a': buf[0] = '\\'; buf[1] = '\a'; return 2;
|
||||||
|
case '\b': buf[0] = '\\'; buf[1] = '\b'; return 2;
|
||||||
|
case '\e': buf[0] = '\\'; buf[1] = '\e'; return 2;
|
||||||
|
case '\f': buf[0] = '\\'; buf[1] = '\f'; return 2;
|
||||||
|
case '\n': buf[0] = '\\'; buf[1] = '\n'; return 2;
|
||||||
|
case '\r': buf[0] = '\\'; buf[1] = '\r'; return 2;
|
||||||
|
case '\t': buf[0] = '\\'; buf[1] = '\t'; return 2;
|
||||||
|
case '\v': buf[0] = '\\'; buf[1] = '\v'; return 2;
|
||||||
|
case '\?': buf[0] = '\\'; buf[1] = 0x3f; return 2;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
if (ch < 32 || ch >= 127) {
|
||||||
|
buf[0] = '\\';
|
||||||
|
buf[1] = '0' + ((ch >> 3) % 8);
|
||||||
|
buf[2] = '0' + ((ch >> 6) % 8);
|
||||||
|
buf[3] = '0' + (ch % 8);
|
||||||
|
return 4;
|
||||||
|
} else {
|
||||||
|
buf[0] = ch;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *yy_escape_char(char *buf, unsigned char ch)
|
||||||
|
{
|
||||||
|
size_t len = yy_escape(buf, ch);
|
||||||
|
buf[len] = 0;
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *yy_escape_string(char *buf, size_t size, const unsigned char *str, size_t n)
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
size_t pos = 0;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
while (i < n) {
|
||||||
|
if (pos + 8 > size) {
|
||||||
|
buf[pos++] = '.';
|
||||||
|
buf[pos++] = '.';
|
||||||
|
buf[pos++] = '.';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
len = yy_escape(buf + pos, str[i]);
|
||||||
|
i++;
|
||||||
|
pos += len;
|
||||||
|
}
|
||||||
|
buf[pos] = 0;
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
static int skip_EOL(int sym);
|
static int skip_EOL(int sym);
|
||||||
static int skip_WS(int sym);
|
static int skip_WS(int sym);
|
||||||
static int skip_ONE_LINE_COMMENT(int sym);
|
static int skip_ONE_LINE_COMMENT(int sym);
|
||||||
@ -208,6 +266,7 @@ static int parse_CHARACTER(int sym, ir_val *val);
|
|||||||
static int parse_STRING(int sym, const char **str, size_t *len);
|
static int parse_STRING(int sym, const char **str, size_t *len);
|
||||||
|
|
||||||
static int get_skip_sym(void) {
|
static int get_skip_sym(void) {
|
||||||
|
char buf[64];
|
||||||
int ch;
|
int ch;
|
||||||
int ret;
|
int ret;
|
||||||
int accept = -1;
|
int accept = -1;
|
||||||
@ -688,9 +747,9 @@ _yy_state_error:
|
|||||||
if (YYPOS >= YYEND) {
|
if (YYPOS >= YYEND) {
|
||||||
yy_error("unexpected <EOF>");
|
yy_error("unexpected <EOF>");
|
||||||
} else if (YYPOS == yy_text) {
|
} else if (YYPOS == yy_text) {
|
||||||
yy_error("unexpected character 'escape_char(ch)'");
|
yy_error_str("unexpected character", yy_escape_char(buf, ch));
|
||||||
} else {
|
} else {
|
||||||
yy_error("unexpected sequence 'escape_string(yy_text, 1 + YYPOS - yy_text))'");
|
yy_error_str("unexpected sequence", yy_escape_string(buf, sizeof(buf), yy_text, 1 + YYPOS - yy_text));
|
||||||
}
|
}
|
||||||
YYPOS++;
|
YYPOS++;
|
||||||
goto _yy_state_start;
|
goto _yy_state_start;
|
||||||
@ -763,7 +822,7 @@ static int parse_ir(int sym, ir_loader *loader) {
|
|||||||
uint32_t params_count;
|
uint32_t params_count;
|
||||||
ir_type param_types[256];
|
ir_type param_types[256];
|
||||||
p.ctx = &ctx;
|
p.ctx = &ctx;
|
||||||
if (YY_IN_SET(sym, (YY_EXTERN,YY_STATIC,YY_VAR,YY_CONST,YY_FUNC), "\012\023\000\000\000")) {
|
if (YY_IN_SET(sym, (YY_EXTERN,YY_STATIC,YY_VAR,YY_CONST,YY_FUNC), "\012\203\000\000\000")) {
|
||||||
do {
|
do {
|
||||||
if (sym == YY_EXTERN) {
|
if (sym == YY_EXTERN) {
|
||||||
sym = get_sym();
|
sym = get_sym();
|
||||||
@ -892,7 +951,7 @@ _yy_state_12:
|
|||||||
} else {
|
} else {
|
||||||
yy_error_sym("unexpected", sym);
|
yy_error_sym("unexpected", sym);
|
||||||
}
|
}
|
||||||
} while (YY_IN_SET(sym, (YY_EXTERN,YY_STATIC,YY_VAR,YY_CONST,YY_FUNC), "\012\023\000\000\000"));
|
} while (YY_IN_SET(sym, (YY_EXTERN,YY_STATIC,YY_VAR,YY_CONST,YY_FUNC), "\012\203\000\000\000"));
|
||||||
} else if (sym == YY__LBRACE) {
|
} else if (sym == YY__LBRACE) {
|
||||||
if (!loader->func_init(loader, &ctx, NULL)) yy_error("ini_func error");
|
if (!loader->func_init(loader, &ctx, NULL)) yy_error("ini_func error");
|
||||||
ctx.ret_type = -1;
|
ctx.ret_type = -1;
|
||||||
@ -942,7 +1001,49 @@ static int parse_ir_sym_data(int sym, ir_loader *loader) {
|
|||||||
uint8_t t = 0;
|
uint8_t t = 0;
|
||||||
ir_val val;
|
ir_val val;
|
||||||
void *p;
|
void *p;
|
||||||
|
const char *name;
|
||||||
|
size_t name_len;
|
||||||
|
char buf[256];
|
||||||
sym = parse_type(sym, &t);
|
sym = parse_type(sym, &t);
|
||||||
|
if (sym == YY_SYM) {
|
||||||
|
sym = get_sym();
|
||||||
|
if (sym != YY__LPAREN) {
|
||||||
|
yy_error_sym("'(' expected, got", sym);
|
||||||
|
}
|
||||||
|
sym = get_sym();
|
||||||
|
sym = parse_ID(sym, &name, &name_len);
|
||||||
|
if (sym != YY__RPAREN) {
|
||||||
|
yy_error_sym("')' expected, got", sym);
|
||||||
|
}
|
||||||
|
sym = get_sym();
|
||||||
|
if (loader->sym_data_ref) {
|
||||||
|
if (name_len > 255) yy_error("name too long");
|
||||||
|
memcpy(buf, name, name_len);
|
||||||
|
buf[name_len] = 0;
|
||||||
|
if (!loader->sym_data_ref(loader, IR_SYM, buf)) {
|
||||||
|
yy_error("sym_data_ref error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (sym == YY_FUNC) {
|
||||||
|
sym = get_sym();
|
||||||
|
if (sym != YY__LPAREN) {
|
||||||
|
yy_error_sym("'(' expected, got", sym);
|
||||||
|
}
|
||||||
|
sym = get_sym();
|
||||||
|
sym = parse_ID(sym, &name, &name_len);
|
||||||
|
if (sym != YY__RPAREN) {
|
||||||
|
yy_error_sym("')' expected, got", sym);
|
||||||
|
}
|
||||||
|
sym = get_sym();
|
||||||
|
if (loader->sym_data_ref) {
|
||||||
|
if (name_len > 255) yy_error("name too long");
|
||||||
|
memcpy(buf, name, name_len);
|
||||||
|
buf[name_len] = 0;
|
||||||
|
if (!loader->sym_data_ref(loader, IR_FUNC, buf)) {
|
||||||
|
yy_error("sym_data_ref error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (YY_IN_SET(sym, (YY_DECNUMBER,YY_HEXNUMBER,YY_FLOATNUMBER,YY_CHARACTER,YY_INF,YY_NAN,YY__MINUS), "\000\000\300\075\000")) {
|
||||||
sym = parse_const(sym, t, &val);
|
sym = parse_const(sym, t, &val);
|
||||||
if (loader->sym_data) {
|
if (loader->sym_data) {
|
||||||
switch (ir_type_size[t]) {
|
switch (ir_type_size[t]) {
|
||||||
@ -958,6 +1059,9 @@ static int parse_ir_sym_data(int sym, ir_loader *loader) {
|
|||||||
yy_error("sym_data error");
|
yy_error("sym_data error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
yy_error_sym("unexpected", sym);
|
||||||
|
}
|
||||||
return sym;
|
return sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -989,7 +1093,7 @@ static int parse_ir_func_prototype(int sym, ir_parser_ctx *p, char *buf, uint32_
|
|||||||
const unsigned char *save_pos;
|
const unsigned char *save_pos;
|
||||||
const unsigned char *save_text;
|
const unsigned char *save_text;
|
||||||
int save_line;
|
int save_line;
|
||||||
int alt55;
|
int alt63;
|
||||||
const char *name;
|
const char *name;
|
||||||
size_t len;
|
size_t len;
|
||||||
uint8_t t = 0;
|
uint8_t t = 0;
|
||||||
@ -1019,32 +1123,32 @@ static int parse_ir_func_prototype(int sym, ir_parser_ctx *p, char *buf, uint32_
|
|||||||
save_pos = yy_pos;
|
save_pos = yy_pos;
|
||||||
save_text = yy_text;
|
save_text = yy_text;
|
||||||
save_line = yy_line;
|
save_line = yy_line;
|
||||||
alt55 = -2;
|
alt63 = -2;
|
||||||
sym2 = sym;
|
sym2 = sym;
|
||||||
if (sym2 == YY__COMMA) {
|
if (sym2 == YY__COMMA) {
|
||||||
sym2 = get_sym();
|
sym2 = get_sym();
|
||||||
goto _yy_state_55_1;
|
goto _yy_state_63_1;
|
||||||
} else if (sym2 == YY__RPAREN) {
|
} else if (sym2 == YY__RPAREN) {
|
||||||
alt55 = 60;
|
alt63 = 68;
|
||||||
goto _yy_state_55;
|
goto _yy_state_63;
|
||||||
} else {
|
} else {
|
||||||
yy_error_sym("unexpected", sym2);
|
yy_error_sym("unexpected", sym2);
|
||||||
}
|
}
|
||||||
_yy_state_55_1:
|
_yy_state_63_1:
|
||||||
if (sym2 == YY_ID) {
|
if (sym2 == YY_ID) {
|
||||||
alt55 = 56;
|
alt63 = 64;
|
||||||
goto _yy_state_55;
|
goto _yy_state_63;
|
||||||
} else if (sym2 == YY__POINT_POINT_POINT) {
|
} else if (sym2 == YY__POINT_POINT_POINT) {
|
||||||
alt55 = 58;
|
alt63 = 66;
|
||||||
goto _yy_state_55;
|
goto _yy_state_63;
|
||||||
} else {
|
} else {
|
||||||
yy_error_sym("unexpected", sym2);
|
yy_error_sym("unexpected", sym2);
|
||||||
}
|
}
|
||||||
_yy_state_55:
|
_yy_state_63:
|
||||||
yy_pos = save_pos;
|
yy_pos = save_pos;
|
||||||
yy_text = save_text;
|
yy_text = save_text;
|
||||||
yy_line = save_line;
|
yy_line = save_line;
|
||||||
if (alt55 != 56) {
|
if (alt63 != 64) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sym = get_sym();
|
sym = get_sym();
|
||||||
@ -1052,7 +1156,7 @@ _yy_state_55:
|
|||||||
param_types[n++] = t;
|
param_types[n++] = t;
|
||||||
if (n > 256) yy_error("name too params");
|
if (n > 256) yy_error("name too params");
|
||||||
}
|
}
|
||||||
if (alt55 == 58) {
|
if (alt63 == 66) {
|
||||||
sym = get_sym();
|
sym = get_sym();
|
||||||
if (sym != YY__POINT_POINT_POINT) {
|
if (sym != YY__POINT_POINT_POINT) {
|
||||||
yy_error_sym("'...' expected, got", sym);
|
yy_error_sym("'...' expected, got", sym);
|
||||||
@ -1087,7 +1191,7 @@ static int parse_ir_insn(int sym, ir_parser_ctx *p) {
|
|||||||
const unsigned char *save_pos;
|
const unsigned char *save_pos;
|
||||||
const unsigned char *save_text;
|
const unsigned char *save_text;
|
||||||
int save_line;
|
int save_line;
|
||||||
int alt64;
|
int alt72;
|
||||||
const char *str, *str2 = NULL, *func;
|
const char *str, *str2 = NULL, *func;
|
||||||
size_t len, len2 = 0, func_len;
|
size_t len, len2 = 0, func_len;
|
||||||
uint8_t op;
|
uint8_t op;
|
||||||
@ -1103,36 +1207,36 @@ static int parse_ir_insn(int sym, ir_parser_ctx *p) {
|
|||||||
save_pos = yy_pos;
|
save_pos = yy_pos;
|
||||||
save_text = yy_text;
|
save_text = yy_text;
|
||||||
save_line = yy_line;
|
save_line = yy_line;
|
||||||
alt64 = -2;
|
alt72 = -2;
|
||||||
sym2 = sym;
|
sym2 = sym;
|
||||||
if (sym2 == YY_ID) {
|
if (sym2 == YY_ID) {
|
||||||
sym2 = get_sym();
|
sym2 = get_sym();
|
||||||
goto _yy_state_64_1;
|
goto _yy_state_72_1;
|
||||||
} else {
|
} else {
|
||||||
yy_error_sym("unexpected", sym2);
|
yy_error_sym("unexpected", sym2);
|
||||||
}
|
}
|
||||||
_yy_state_64_1:
|
_yy_state_72_1:
|
||||||
if (sym2 == YY_ID) {
|
if (sym2 == YY_ID) {
|
||||||
alt64 = 65;
|
alt72 = 73;
|
||||||
goto _yy_state_64;
|
goto _yy_state_72;
|
||||||
} else if (sym2 == YY__EQUAL) {
|
} else if (sym2 == YY__EQUAL) {
|
||||||
alt64 = 69;
|
alt72 = 77;
|
||||||
goto _yy_state_64;
|
goto _yy_state_72;
|
||||||
} else {
|
} else {
|
||||||
yy_error_sym("unexpected", sym2);
|
yy_error_sym("unexpected", sym2);
|
||||||
}
|
}
|
||||||
_yy_state_64:
|
_yy_state_72:
|
||||||
yy_pos = save_pos;
|
yy_pos = save_pos;
|
||||||
yy_text = save_text;
|
yy_text = save_text;
|
||||||
yy_line = save_line;
|
yy_line = save_line;
|
||||||
if (alt64 == 65) {
|
if (alt72 == 73) {
|
||||||
sym = parse_type(sym, &t);
|
sym = parse_type(sym, &t);
|
||||||
sym = parse_ID(sym, &str, &len);
|
sym = parse_ID(sym, &str, &len);
|
||||||
if (sym == YY__COMMA) {
|
if (sym == YY__COMMA) {
|
||||||
sym = get_sym();
|
sym = get_sym();
|
||||||
sym = parse_ID(sym, &str2, &len2);
|
sym = parse_ID(sym, &str2, &len2);
|
||||||
}
|
}
|
||||||
} else if (alt64 == 69) {
|
} else if (alt72 == 77) {
|
||||||
sym = parse_ID(sym, &str, &len);
|
sym = parse_ID(sym, &str, &len);
|
||||||
} else {
|
} else {
|
||||||
yy_error_sym("unexpected", sym);
|
yy_error_sym("unexpected", sym);
|
||||||
@ -1470,6 +1574,11 @@ static void yy_error_sym(const char *msg, int sym) {
|
|||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void yy_error_str(const char *msg, const char *str) {
|
||||||
|
fprintf(stderr, "ERROR: %s '%s' at line %d\n", msg, str, yy_line);
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
int ir_load(ir_loader *loader, FILE *f) {
|
int ir_load(ir_loader *loader, FILE *f) {
|
||||||
long pos, end;
|
long pos, end;
|
||||||
|
|
||||||
|
@ -1596,7 +1596,7 @@ static int llvm2ir_forward_func(ir_loader *loader, const char *name, LLVMValueRe
|
|||||||
return loader->forward_func_dcl(loader, name, flags, ret_type, count, param_types);
|
return loader->forward_func_dcl(loader, name, flags, ret_type, count, param_types);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int llvm2ir_data(ir_loader *loader, LLVMTypeRef type, LLVMValueRef op)
|
static int llvm2ir_data(ir_loader *loader, LLVMTargetDataRef target_data, LLVMTypeRef type, LLVMValueRef op)
|
||||||
{
|
{
|
||||||
LLVMTypeRef el_type;
|
LLVMTypeRef el_type;
|
||||||
LLVMValueRef el;
|
LLVMValueRef el;
|
||||||
@ -1604,9 +1604,13 @@ static int llvm2ir_data(ir_loader *loader, LLVMTypeRef type, LLVMValueRef op)
|
|||||||
ir_type t;
|
ir_type t;
|
||||||
ir_val val;
|
ir_val val;
|
||||||
uint32_t i, len;
|
uint32_t i, len;
|
||||||
|
const char *name;
|
||||||
|
size_t name_len;
|
||||||
|
char buf[256];
|
||||||
void *p = NULL;
|
void *p = NULL;
|
||||||
|
LLVMValueKind kind = LLVMGetValueKind(op);
|
||||||
|
|
||||||
switch (LLVMGetValueKind(op)) {
|
switch (kind) {
|
||||||
case LLVMConstantIntValueKind:
|
case LLVMConstantIntValueKind:
|
||||||
t = llvm2ir_type(type);
|
t = llvm2ir_type(type);
|
||||||
IR_ASSERT(IR_IS_TYPE_INT(t));
|
IR_ASSERT(IR_IS_TYPE_INT(t));
|
||||||
@ -1638,31 +1642,71 @@ static int llvm2ir_data(ir_loader *loader, LLVMTypeRef type, LLVMValueRef op)
|
|||||||
case LLVMConstantPointerNullValueKind:
|
case LLVMConstantPointerNullValueKind:
|
||||||
val.addr = 0;
|
val.addr = 0;
|
||||||
return loader->sym_data(loader, IR_ADDR, 1, &val.addr);
|
return loader->sym_data(loader, IR_ADDR, 1, &val.addr);
|
||||||
// case LLVMConstantArrayValueKind:
|
case LLVMConstantArrayValueKind:
|
||||||
case LLVMConstantDataArrayValueKind:
|
case LLVMConstantDataArrayValueKind:
|
||||||
el_type = LLVMGetElementType(type);
|
el_type = LLVMGetElementType(type);
|
||||||
len = LLVMGetArrayLength(type);
|
len = LLVMGetArrayLength(type);
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
el = LLVMGetAggregateElement(op, i);
|
el = LLVMGetAggregateElement(op, i);
|
||||||
if (!llvm2ir_data(loader, el_type, el)) {
|
if (!llvm2ir_data(loader, target_data, el_type, el)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
break;
|
case LLVMConstantStructValueKind:
|
||||||
case LLVMConstantExprValueKind:
|
len = LLVMCountStructElementTypes(type);
|
||||||
IR_ASSERT(0);
|
for (i = 0; i < len; i++) {
|
||||||
return 0;
|
// TODO: support for offset and alignment
|
||||||
case LLVMGlobalVariableValueKind:
|
// offset = LLVMOffsetOfElement(target_data, type, i);
|
||||||
IR_ASSERT(0);
|
el_type = LLVMStructGetTypeAtIndex(type, i);
|
||||||
return 0;
|
el = LLVMGetAggregateElement(op, i);
|
||||||
case LLVMFunctionValueKind:
|
if (!llvm2ir_data(loader, target_data, el_type, el)) {
|
||||||
IR_ASSERT(0);
|
|
||||||
return 0;
|
|
||||||
case LLVMUndefValueValueKind:
|
|
||||||
IR_ASSERT(0);
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
case LLVMConstantAggregateZeroValueKind:
|
||||||
|
switch (LLVMGetTypeKind(type)) {
|
||||||
|
case LLVMIntegerTypeKind:
|
||||||
|
case LLVMFloatTypeKind:
|
||||||
|
case LLVMDoubleTypeKind:
|
||||||
|
case LLVMPointerTypeKind:
|
||||||
|
case LLVMFunctionTypeKind:
|
||||||
|
case LLVMLabelTypeKind:
|
||||||
|
t = llvm2ir_type(type);
|
||||||
|
val.u64 = 0;
|
||||||
|
return loader->sym_data(loader, t, 1, &val.u64);
|
||||||
default:
|
default:
|
||||||
|
// TODO: use bigger type if possible
|
||||||
|
len = LLVMABISizeOfType(target_data, type);
|
||||||
|
val.u64 = 0;
|
||||||
|
return loader->sym_data(loader, IR_U8, len, &val.u64);
|
||||||
|
}
|
||||||
|
case LLVMGlobalVariableValueKind:
|
||||||
|
// TODO: resolve variable address
|
||||||
|
name = LLVMGetValueName2(op, &name_len);
|
||||||
|
name = llvm2ir_sym_name(buf, name, name_len);
|
||||||
|
if (!name) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return loader->sym_data_ref(loader, IR_SYM, name);
|
||||||
|
case LLVMFunctionValueKind:
|
||||||
|
// TODO: function prototype
|
||||||
|
// TODO: resolve function address
|
||||||
|
name = LLVMGetValueName2(op, &name_len);
|
||||||
|
name = llvm2ir_sym_name(buf, name, name_len);
|
||||||
|
if (!name) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return loader->sym_data_ref(loader, IR_FUNC, name);
|
||||||
|
// case LLVMConstantExprValueKind:
|
||||||
|
// IR_ASSERT(0);
|
||||||
|
// return 0;
|
||||||
|
// case LLVMUndefValueValueKind:
|
||||||
|
// IR_ASSERT(0);
|
||||||
|
// return 0;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "Unsupported LLVM value kind: %d\n", kind);
|
||||||
IR_ASSERT(0);
|
IR_ASSERT(0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1713,8 +1757,12 @@ static int ir_load_llvm_module(ir_loader *loader, LLVMModuleRef module)
|
|||||||
if (LLVMIsGlobalConstant(sym)) {
|
if (LLVMIsGlobalConstant(sym)) {
|
||||||
flags |= IR_CONST;
|
flags |= IR_CONST;
|
||||||
}
|
}
|
||||||
|
name = llvm2ir_sym_name(buf, name, name_len);
|
||||||
|
if (!name) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if (loader->external_sym_dcl
|
if (loader->external_sym_dcl
|
||||||
&& !loader->external_sym_dcl(loader, buf, flags)) {
|
&& !loader->external_sym_dcl(loader, name, flags)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1741,7 +1789,7 @@ static int ir_load_llvm_module(ir_loader *loader, LLVMModuleRef module)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (has_data) {
|
if (has_data) {
|
||||||
llvm2ir_data(loader, type, init);
|
llvm2ir_data(loader, target_data, type, init);
|
||||||
if (!loader->sym_data_end(loader)) {
|
if (!loader->sym_data_end(loader)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
42
ir_main.c
42
ir_main.c
@ -382,6 +382,12 @@ static bool ir_loader_sym_dcl(ir_loader *loader, const char *name, uint32_t flag
|
|||||||
}
|
}
|
||||||
fprintf(l->dump_file, "%s %s [%ld]%s\n", (flags & IR_CONST) ? "const" : "var", name, size, has_data ? " = {" : ";");
|
fprintf(l->dump_file, "%s %s [%ld]%s\n", (flags & IR_CONST) ? "const" : "var", name, size, has_data ? " = {" : ";");
|
||||||
}
|
}
|
||||||
|
if (l->c_file) {
|
||||||
|
// TODO:
|
||||||
|
}
|
||||||
|
if (l->llvm_file) {
|
||||||
|
// TODO:
|
||||||
|
}
|
||||||
if (l->dump_asm || l->dump_size || l->run) {
|
if (l->dump_asm || l->dump_size || l->run) {
|
||||||
void *data = ir_mem_malloc(size);
|
void *data = ir_mem_malloc(size);
|
||||||
|
|
||||||
@ -435,6 +441,12 @@ static bool ir_loader_sym_data(ir_loader *loader, ir_type type, uint32_t count,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (l->c_file) {
|
||||||
|
// TODO:
|
||||||
|
}
|
||||||
|
if (l->llvm_file) {
|
||||||
|
// TODO:
|
||||||
|
}
|
||||||
if (l->dump_asm || l->dump_size || l->run) {
|
if (l->dump_asm || l->dump_size || l->run) {
|
||||||
size_t size = ir_type_size[type] * count;
|
size_t size = ir_type_size[type] * count;
|
||||||
|
|
||||||
@ -448,6 +460,26 @@ static bool ir_loader_sym_data(ir_loader *loader, ir_type type, uint32_t count,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ir_loader_sym_data_ref(ir_loader *loader, ir_op op, const char *ref)
|
||||||
|
{
|
||||||
|
ir_main_loader *l = (ir_main_loader*) loader;
|
||||||
|
|
||||||
|
IR_ASSERT(op == IR_FUNC || op == IR_SYM);
|
||||||
|
if ((l->dump & IR_DUMP_SAVE) && (l->dump_file)) {
|
||||||
|
fprintf(l->dump_file, "\t%s %s(%s),\n", ir_type_cname[IR_ADDR], op == IR_FUNC ? "func" : "sym", ref);
|
||||||
|
}
|
||||||
|
if (l->c_file) {
|
||||||
|
// TODO:
|
||||||
|
}
|
||||||
|
if (l->llvm_file) {
|
||||||
|
// TODO:
|
||||||
|
}
|
||||||
|
if (l->dump_asm || l->dump_size || l->run) {
|
||||||
|
// TODO:
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static bool ir_loader_sym_data_end(ir_loader *loader)
|
static bool ir_loader_sym_data_end(ir_loader *loader)
|
||||||
{
|
{
|
||||||
ir_main_loader *l = (ir_main_loader*) loader;
|
ir_main_loader *l = (ir_main_loader*) loader;
|
||||||
@ -455,6 +487,15 @@ static bool ir_loader_sym_data_end(ir_loader *loader)
|
|||||||
if ((l->dump & IR_DUMP_SAVE) && (l->dump_file)) {
|
if ((l->dump & IR_DUMP_SAVE) && (l->dump_file)) {
|
||||||
fprintf(l->dump_file, "};\n");
|
fprintf(l->dump_file, "};\n");
|
||||||
}
|
}
|
||||||
|
if (l->c_file) {
|
||||||
|
// TODO:
|
||||||
|
}
|
||||||
|
if (l->llvm_file) {
|
||||||
|
// TODO:
|
||||||
|
}
|
||||||
|
if (l->dump_asm || l->dump_size || l->run) {
|
||||||
|
// TODO:
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -799,6 +840,7 @@ int main(int argc, char **argv)
|
|||||||
loader.loader.forward_func_dcl = ir_loader_forward_func_dcl;
|
loader.loader.forward_func_dcl = ir_loader_forward_func_dcl;
|
||||||
loader.loader.sym_dcl = ir_loader_sym_dcl;
|
loader.loader.sym_dcl = ir_loader_sym_dcl;
|
||||||
loader.loader.sym_data = ir_loader_sym_data;
|
loader.loader.sym_data = ir_loader_sym_data;
|
||||||
|
loader.loader.sym_data_ref = ir_loader_sym_data_ref;
|
||||||
loader.loader.sym_data_end = ir_loader_sym_data_end;
|
loader.loader.sym_data_end = ir_loader_sym_data_end;
|
||||||
loader.loader.func_init = ir_loader_func_init;
|
loader.loader.func_init = ir_loader_func_init;
|
||||||
loader.loader.func_process = ir_loader_func_process;
|
loader.loader.func_process = ir_loader_func_process;
|
||||||
|
Loading…
Reference in New Issue
Block a user