mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2025-01-18 14:21:36 +00:00
All ir_instrs now get their lex-context, so that we can create an LNO file with -flno
This commit is contained in:
parent
2f3612d905
commit
6fc00e523d
6 changed files with 201 additions and 127 deletions
88
ast.c
88
ast.c
|
@ -1451,7 +1451,7 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir)
|
|||
if (!self->vtype->expression.next ||
|
||||
self->vtype->expression.next->expression.vtype == TYPE_VOID)
|
||||
{
|
||||
return ir_block_create_return(self->curblock, NULL);
|
||||
return ir_block_create_return(self->curblock, ast_ctx(self), NULL);
|
||||
}
|
||||
else if (vec_size(self->curblock->entries))
|
||||
{
|
||||
|
@ -1462,7 +1462,7 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir)
|
|||
{
|
||||
return false;
|
||||
}
|
||||
return ir_block_create_return(self->curblock, NULL);
|
||||
return ir_block_create_return(self->curblock, ast_ctx(self), NULL);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -1584,7 +1584,7 @@ bool ast_store_codegen(ast_store *self, ast_function *func, bool lvalue, ir_valu
|
|||
if (!(*cgen)((ast_expression*)(self->source), func, false, &right))
|
||||
return false;
|
||||
|
||||
call = ir_block_create_call(func->curblock, ast_function_label(func, "store"), funval);
|
||||
call = ir_block_create_call(func->curblock, ast_ctx(self), ast_function_label(func, "store"), funval);
|
||||
if (!call)
|
||||
return false;
|
||||
ir_call_param(call, iridx);
|
||||
|
@ -1606,7 +1606,7 @@ bool ast_store_codegen(ast_store *self, ast_function *func, bool lvalue, ir_valu
|
|||
if (!(*cgen)((ast_expression*)(self->source), func, false, &right))
|
||||
return false;
|
||||
|
||||
if (!ir_block_create_store_op(func->curblock, self->op, left, right))
|
||||
if (!ir_block_create_store_op(func->curblock, ast_ctx(self), self->op, left, right))
|
||||
return false;
|
||||
self->expression.outr = right;
|
||||
}
|
||||
|
@ -1670,7 +1670,7 @@ bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_va
|
|||
compile_error(ast_ctx(self), "don't know how to cast to bool...");
|
||||
return false;
|
||||
}
|
||||
left = ir_block_create_unary(func->curblock,
|
||||
left = ir_block_create_unary(func->curblock, ast_ctx(self),
|
||||
ast_function_label(func, "sce_not"),
|
||||
notop,
|
||||
left);
|
||||
|
@ -1679,10 +1679,10 @@ bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_va
|
|||
|
||||
other = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "sce_other"));
|
||||
if ( !(self->op == INSTR_OR) != !OPTS_FLAG(PERL_LOGIC) ) {
|
||||
if (!ir_block_create_if(func->curblock, left, other, merge))
|
||||
if (!ir_block_create_if(func->curblock, ast_ctx(self), left, other, merge))
|
||||
return false;
|
||||
} else {
|
||||
if (!ir_block_create_if(func->curblock, left, merge, other))
|
||||
if (!ir_block_create_if(func->curblock, ast_ctx(self), left, merge, other))
|
||||
return false;
|
||||
}
|
||||
/* use the likely flag */
|
||||
|
@ -1698,21 +1698,21 @@ bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_va
|
|||
compile_error(ast_ctx(self), "don't know how to cast to bool...");
|
||||
return false;
|
||||
}
|
||||
right = ir_block_create_unary(func->curblock,
|
||||
right = ir_block_create_unary(func->curblock, ast_ctx(self),
|
||||
ast_function_label(func, "sce_not"),
|
||||
notop,
|
||||
right);
|
||||
}
|
||||
from_right = func->curblock;
|
||||
|
||||
if (!ir_block_create_jump(func->curblock, merge))
|
||||
if (!ir_block_create_jump(func->curblock, ast_ctx(self), merge))
|
||||
return false;
|
||||
|
||||
vec_remove(func->ir_func->blocks, merge_id, 1);
|
||||
vec_push(func->ir_func->blocks, merge);
|
||||
|
||||
func->curblock = merge;
|
||||
phi = ir_block_create_phi(func->curblock, ast_function_label(func, "sce_value"), TYPE_FLOAT);
|
||||
phi = ir_block_create_phi(func->curblock, ast_ctx(self), ast_function_label(func, "sce_value"), TYPE_FLOAT);
|
||||
ir_phi_add(phi, from_left, left);
|
||||
ir_phi_add(phi, from_right, right);
|
||||
*out = ir_phi_value(phi);
|
||||
|
@ -1722,7 +1722,7 @@ bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_va
|
|||
compile_error(ast_ctx(self), "don't know how to cast to bool...");
|
||||
return false;
|
||||
}
|
||||
*out = ir_block_create_unary(func->curblock,
|
||||
*out = ir_block_create_unary(func->curblock, ast_ctx(self),
|
||||
ast_function_label(func, "sce_final_not"),
|
||||
notop,
|
||||
*out);
|
||||
|
@ -1741,7 +1741,7 @@ bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_va
|
|||
if (!(*cgen)((ast_expression*)(self->right), func, false, &right))
|
||||
return false;
|
||||
|
||||
*out = ir_block_create_binop(func->curblock, ast_function_label(func, "bin"),
|
||||
*out = ir_block_create_binop(func->curblock, ast_ctx(self), ast_function_label(func, "bin"),
|
||||
self->op, left, right);
|
||||
if (!*out)
|
||||
return false;
|
||||
|
@ -1797,7 +1797,7 @@ bool ast_binstore_codegen(ast_binstore *self, ast_function *func, bool lvalue, i
|
|||
return false;
|
||||
|
||||
/* now the binary */
|
||||
bin = ir_block_create_binop(func->curblock, ast_function_label(func, "binst"),
|
||||
bin = ir_block_create_binop(func->curblock, ast_ctx(self), ast_function_label(func, "binst"),
|
||||
self->opbin, leftr, right);
|
||||
self->expression.outr = bin;
|
||||
|
||||
|
@ -1822,7 +1822,7 @@ bool ast_binstore_codegen(ast_binstore *self, ast_function *func, bool lvalue, i
|
|||
if (!(*cgen)((ast_expression*)(arr->setter), func, true, &funval))
|
||||
return false;
|
||||
|
||||
call = ir_block_create_call(func->curblock, ast_function_label(func, "store"), funval);
|
||||
call = ir_block_create_call(func->curblock, ast_ctx(self), ast_function_label(func, "store"), funval);
|
||||
if (!call)
|
||||
return false;
|
||||
ir_call_param(call, iridx);
|
||||
|
@ -1836,7 +1836,7 @@ bool ast_binstore_codegen(ast_binstore *self, ast_function *func, bool lvalue, i
|
|||
return false;
|
||||
self->expression.outl = leftl;
|
||||
|
||||
if (!ir_block_create_store_op(func->curblock, self->opstore, leftl, bin))
|
||||
if (!ir_block_create_store_op(func->curblock, ast_ctx(self), self->opstore, leftl, bin))
|
||||
return false;
|
||||
self->expression.outr = bin;
|
||||
}
|
||||
|
@ -1874,7 +1874,7 @@ bool ast_unary_codegen(ast_unary *self, ast_function *func, bool lvalue, ir_valu
|
|||
if (!(*cgen)((ast_expression*)(self->operand), func, false, &operand))
|
||||
return false;
|
||||
|
||||
*out = ir_block_create_unary(func->curblock, ast_function_label(func, "unary"),
|
||||
*out = ir_block_create_unary(func->curblock, ast_ctx(self), ast_function_label(func, "unary"),
|
||||
self->op, operand);
|
||||
if (!*out)
|
||||
return false;
|
||||
|
@ -1910,10 +1910,10 @@ bool ast_return_codegen(ast_return *self, ast_function *func, bool lvalue, ir_va
|
|||
if (!(*cgen)((ast_expression*)(self->operand), func, false, &operand))
|
||||
return false;
|
||||
|
||||
if (!ir_block_create_return(func->curblock, operand))
|
||||
if (!ir_block_create_return(func->curblock, ast_ctx(self), operand))
|
||||
return false;
|
||||
} else {
|
||||
if (!ir_block_create_return(func->curblock, NULL))
|
||||
if (!ir_block_create_return(func->curblock, ast_ctx(self), NULL))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1950,10 +1950,10 @@ bool ast_entfield_codegen(ast_entfield *self, ast_function *func, bool lvalue, i
|
|||
|
||||
if (lvalue) {
|
||||
/* address! */
|
||||
*out = ir_block_create_fieldaddress(func->curblock, ast_function_label(func, "efa"),
|
||||
*out = ir_block_create_fieldaddress(func->curblock, ast_ctx(self), ast_function_label(func, "efa"),
|
||||
ent, field);
|
||||
} else {
|
||||
*out = ir_block_create_load_from_ent(func->curblock, ast_function_label(func, "efv"),
|
||||
*out = ir_block_create_load_from_ent(func->curblock, ast_ctx(self), ast_function_label(func, "efv"),
|
||||
ent, field, self->expression.vtype);
|
||||
}
|
||||
if (!*out) {
|
||||
|
@ -2049,7 +2049,7 @@ bool ast_array_index_codegen(ast_array_index *self, ast_function *func, bool lva
|
|||
if (!(*cgen)((ast_expression*)(arr->getter), func, true, &funval))
|
||||
return false;
|
||||
|
||||
call = ir_block_create_call(func->curblock, ast_function_label(func, "fetch"), funval);
|
||||
call = ir_block_create_call(func->curblock, ast_ctx(self), ast_function_label(func, "fetch"), funval);
|
||||
if (!call)
|
||||
return false;
|
||||
ir_call_param(call, iridx);
|
||||
|
@ -2163,9 +2163,9 @@ bool ast_ifthen_codegen(ast_ifthen *self, ast_function *func, bool lvalue, ir_va
|
|||
if (!merge)
|
||||
return false;
|
||||
/* add jumps ot the merge block */
|
||||
if (ontrue && !ontrue_endblock->final && !ir_block_create_jump(ontrue_endblock, merge))
|
||||
if (ontrue && !ontrue_endblock->final && !ir_block_create_jump(ontrue_endblock, ast_ctx(self), merge))
|
||||
return false;
|
||||
if (onfalse && !onfalse_endblock->final && !ir_block_create_jump(onfalse_endblock, merge))
|
||||
if (onfalse && !onfalse_endblock->final && !ir_block_create_jump(onfalse_endblock, ast_ctx(self), merge))
|
||||
return false;
|
||||
|
||||
/* Now enter the merge block */
|
||||
|
@ -2174,7 +2174,7 @@ bool ast_ifthen_codegen(ast_ifthen *self, ast_function *func, bool lvalue, ir_va
|
|||
|
||||
/* we create the if here, that way all blocks are ordered :)
|
||||
*/
|
||||
if (!ir_block_create_if(cond, condval,
|
||||
if (!ir_block_create_if(cond, ast_ctx(self), condval,
|
||||
(ontrue ? ontrue : merge),
|
||||
(onfalse ? onfalse : merge)))
|
||||
{
|
||||
|
@ -2260,13 +2260,13 @@ bool ast_ternary_codegen(ast_ternary *self, ast_function *func, bool lvalue, ir_
|
|||
if (!merge)
|
||||
return false;
|
||||
/* jump to merge block */
|
||||
if (!ir_block_create_jump(ontrue_out, merge))
|
||||
if (!ir_block_create_jump(ontrue_out, ast_ctx(self), merge))
|
||||
return false;
|
||||
if (!ir_block_create_jump(onfalse_out, merge))
|
||||
if (!ir_block_create_jump(onfalse_out, ast_ctx(self), merge))
|
||||
return false;
|
||||
|
||||
/* create if instruction */
|
||||
if (!ir_block_create_if(cond_out, condval, ontrue, onfalse))
|
||||
if (!ir_block_create_if(cond_out, ast_ctx(self), condval, ontrue, onfalse))
|
||||
return false;
|
||||
|
||||
/* Now enter the merge block */
|
||||
|
@ -2281,7 +2281,7 @@ bool ast_ternary_codegen(ast_ternary *self, ast_function *func, bool lvalue, ir_
|
|||
}
|
||||
|
||||
/* create PHI */
|
||||
phi = ir_block_create_phi(merge, ast_function_label(func, "phi"), trueval->vtype);
|
||||
phi = ir_block_create_phi(merge, ast_ctx(self), ast_function_label(func, "phi"), trueval->vtype);
|
||||
if (!phi)
|
||||
return false;
|
||||
ir_phi_add(phi, ontrue_out, trueval);
|
||||
|
@ -2467,7 +2467,7 @@ bool ast_loop_codegen(ast_loop *self, ast_function *func, bool lvalue, ir_value
|
|||
else if (bbody) tmpblock = bbody;
|
||||
else if (bpostcond) tmpblock = bpostcond;
|
||||
else tmpblock = bout;
|
||||
if (!ir_block_create_jump(bin, tmpblock))
|
||||
if (!ir_block_create_jump(bin, ast_ctx(self), tmpblock))
|
||||
return false;
|
||||
|
||||
/* From precond */
|
||||
|
@ -2479,7 +2479,7 @@ bool ast_loop_codegen(ast_loop *self, ast_function *func, bool lvalue, ir_value
|
|||
else if (bpostcond) ontrue = bpostcond;
|
||||
else ontrue = bprecond;
|
||||
onfalse = bout;
|
||||
if (!ir_block_create_if(end_bprecond, precond, ontrue, onfalse))
|
||||
if (!ir_block_create_if(end_bprecond, ast_ctx(self), precond, ontrue, onfalse))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2490,7 +2490,7 @@ bool ast_loop_codegen(ast_loop *self, ast_function *func, bool lvalue, ir_value
|
|||
else if (bpostcond) tmpblock = bpostcond;
|
||||
else if (bprecond) tmpblock = bprecond;
|
||||
else tmpblock = bbody;
|
||||
if (!end_bbody->final && !ir_block_create_jump(end_bbody, tmpblock))
|
||||
if (!end_bbody->final && !ir_block_create_jump(end_bbody, ast_ctx(self), tmpblock))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2501,7 +2501,7 @@ bool ast_loop_codegen(ast_loop *self, ast_function *func, bool lvalue, ir_value
|
|||
else if (bprecond) tmpblock = bprecond;
|
||||
else if (bbody) tmpblock = bbody;
|
||||
else tmpblock = bout;
|
||||
if (!ir_block_create_jump(end_bincrement, tmpblock))
|
||||
if (!ir_block_create_jump(end_bincrement, ast_ctx(self), tmpblock))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2514,7 +2514,7 @@ bool ast_loop_codegen(ast_loop *self, ast_function *func, bool lvalue, ir_value
|
|||
else if (bincrement) ontrue = bincrement;
|
||||
else ontrue = bpostcond;
|
||||
onfalse = bout;
|
||||
if (!ir_block_create_if(end_bpostcond, postcond, ontrue, onfalse))
|
||||
if (!ir_block_create_if(end_bpostcond, ast_ctx(self), postcond, ontrue, onfalse))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2552,7 +2552,7 @@ bool ast_breakcont_codegen(ast_breakcont *self, ast_function *func, bool lvalue,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!ir_block_create_jump(func->curblock, target))
|
||||
if (!ir_block_create_jump(func->curblock, ast_ctx(self), target))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
@ -2627,7 +2627,7 @@ bool ast_switch_codegen(ast_switch *self, ast_function *func, bool lvalue, ir_va
|
|||
if (!(*cgen)((ast_expression*)(swcase->value), func, false, &val))
|
||||
return false;
|
||||
/* generate the condition */
|
||||
cond = ir_block_create_binop(func->curblock, ast_function_label(func, "switch_eq"), cmpinstr, irop, val);
|
||||
cond = ir_block_create_binop(func->curblock, ast_ctx(self), ast_function_label(func, "switch_eq"), cmpinstr, irop, val);
|
||||
if (!cond)
|
||||
return false;
|
||||
|
||||
|
@ -2636,12 +2636,12 @@ bool ast_switch_codegen(ast_switch *self, ast_function *func, bool lvalue, ir_va
|
|||
bnot = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "not_case"));
|
||||
if (!bcase || !bnot)
|
||||
return false;
|
||||
if (!ir_block_create_if(func->curblock, cond, bcase, bnot))
|
||||
if (!ir_block_create_if(func->curblock, ast_ctx(self), cond, bcase, bnot))
|
||||
return false;
|
||||
|
||||
/* Make the previous case-end fall through */
|
||||
if (bfall && !bfall->final) {
|
||||
if (!ir_block_create_jump(bfall, bcase))
|
||||
if (!ir_block_create_jump(bfall, ast_ctx(self), bcase))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2669,7 +2669,7 @@ bool ast_switch_codegen(ast_switch *self, ast_function *func, bool lvalue, ir_va
|
|||
}
|
||||
|
||||
/* Jump from the last bnot to bout */
|
||||
if (bfall && !bfall->final && !ir_block_create_jump(bfall, bout)) {
|
||||
if (bfall && !bfall->final && !ir_block_create_jump(bfall, ast_ctx(self), bout)) {
|
||||
/*
|
||||
astwarning(ast_ctx(bfall), WARN_???, "missing break after last case");
|
||||
*/
|
||||
|
@ -2685,7 +2685,7 @@ bool ast_switch_codegen(ast_switch *self, ast_function *func, bool lvalue, ir_va
|
|||
|
||||
/* Insert the fallthrough jump */
|
||||
if (def_bfall && !def_bfall->final) {
|
||||
if (!ir_block_create_jump(def_bfall, bcase))
|
||||
if (!ir_block_create_jump(def_bfall, ast_ctx(self), bcase))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2696,7 +2696,7 @@ bool ast_switch_codegen(ast_switch *self, ast_function *func, bool lvalue, ir_va
|
|||
}
|
||||
|
||||
/* Jump from the last bnot to bout */
|
||||
if (!func->curblock->final && !ir_block_create_jump(func->curblock, bout))
|
||||
if (!func->curblock->final && !ir_block_create_jump(func->curblock, ast_ctx(self), bout))
|
||||
return false;
|
||||
/* enter the outgoing block */
|
||||
func->curblock = bout;
|
||||
|
@ -2729,7 +2729,7 @@ bool ast_label_codegen(ast_label *self, ast_function *func, bool lvalue, ir_valu
|
|||
return false;
|
||||
}
|
||||
if (!func->curblock->final) {
|
||||
if (!ir_block_create_jump(func->curblock, self->irblock))
|
||||
if (!ir_block_create_jump(func->curblock, ast_ctx(self), self->irblock))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2757,14 +2757,14 @@ bool ast_goto_codegen(ast_goto *self, ast_function *func, bool lvalue, ir_value
|
|||
if (self->irblock_from) {
|
||||
/* we already tried once, this is the callback */
|
||||
self->irblock_from->final = false;
|
||||
if (!ir_block_create_jump(self->irblock_from, self->target->irblock)) {
|
||||
if (!ir_block_create_jump(self->irblock_from, ast_ctx(self), self->target->irblock)) {
|
||||
compile_error(ast_ctx(self), "failed to generate goto to `%s`", self->name);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ir_block_create_jump(func->curblock, self->target->irblock)) {
|
||||
if (!ir_block_create_jump(func->curblock, ast_ctx(self), self->target->irblock)) {
|
||||
compile_error(ast_ctx(self), "failed to generate goto to `%s`", self->name);
|
||||
return false;
|
||||
}
|
||||
|
@ -2825,7 +2825,7 @@ bool ast_call_codegen(ast_call *self, ast_function *func, bool lvalue, ir_value
|
|||
vec_push(params, param);
|
||||
}
|
||||
|
||||
callinstr = ir_block_create_call(func->curblock, ast_function_label(func, "call"), funval);
|
||||
callinstr = ir_block_create_call(func->curblock, ast_ctx(self), ast_function_label(func, "call"), funval);
|
||||
if (!callinstr)
|
||||
goto error;
|
||||
|
||||
|
|
49
code.c
49
code.c
|
@ -24,14 +24,21 @@
|
|||
#include "gmqcc.h"
|
||||
|
||||
prog_section_statement *code_statements;
|
||||
int *code_linenums;
|
||||
prog_section_def *code_defs;
|
||||
prog_section_field *code_fields;
|
||||
prog_section_function *code_functions;
|
||||
int *code_globals;
|
||||
char *code_chars;
|
||||
|
||||
uint16_t code_crc;
|
||||
uint32_t code_entfields;
|
||||
uint16_t code_crc;
|
||||
uint32_t code_entfields;
|
||||
|
||||
void code_push_statement(prog_section_statement *stmt, int linenum)
|
||||
{
|
||||
vec_push(code_statements, *stmt);
|
||||
vec_push(code_linenums, linenum);
|
||||
}
|
||||
|
||||
void code_init() {
|
||||
prog_section_function empty_function = {0,0,0,0,0,0,0,{0}};
|
||||
|
@ -54,7 +61,7 @@ void code_init() {
|
|||
|
||||
vec_push(code_chars, '\0');
|
||||
vec_push(code_functions, empty_function);
|
||||
vec_push(code_statements, empty_statement);
|
||||
code_push_statement(&empty_statement, 0);
|
||||
vec_push(code_defs, empty_def);
|
||||
vec_push(code_fields, empty_def);
|
||||
}
|
||||
|
@ -134,7 +141,7 @@ qcint code_alloc_field (size_t qcsize)
|
|||
return pos;
|
||||
}
|
||||
|
||||
bool code_write(const char *filename) {
|
||||
bool code_write(const char *filename, const char *lnofile) {
|
||||
prog_header code_header;
|
||||
FILE *fp = NULL;
|
||||
size_t it = 2;
|
||||
|
@ -169,6 +176,40 @@ bool code_write(const char *filename) {
|
|||
vec_push(code_chars, '\0'); /* P */
|
||||
}
|
||||
|
||||
if (lnofile) {
|
||||
uint32_t lnotype = *(unsigned int*)"LNOF";
|
||||
uint32_t version = 1;
|
||||
|
||||
fp = util_fopen(lnofile, "wb");
|
||||
if (!fp)
|
||||
return false;
|
||||
|
||||
if (fwrite(&lnotype, sizeof(lnotype), 1, fp) != 1 ||
|
||||
fwrite(&version, sizeof(version), 1, fp) != 1 ||
|
||||
fwrite(&code_header.defs.length, sizeof(code_header.defs.length), 1, fp) != 1 ||
|
||||
fwrite(&code_header.globals.length, sizeof(code_header.globals.length), 1, fp) != 1 ||
|
||||
fwrite(&code_header.fields.length, sizeof(code_header.fields.length), 1, fp) != 1 ||
|
||||
fwrite(&code_header.statements.length, sizeof(code_header.statements.length), 1, fp) != 1 ||
|
||||
fwrite(code_linenums, sizeof(code_linenums[0]), vec_size(code_linenums), fp) != vec_size(code_linenums))
|
||||
{
|
||||
con_err("failed to write lno file\n");
|
||||
}
|
||||
/*
|
||||
h = SafeOpenWrite (destfile, 2*1024*1024);
|
||||
SafeWrite (h, &lnotype, sizeof(int));
|
||||
SafeWrite (h, &version, sizeof(int));
|
||||
SafeWrite (h, &numglobaldefs, sizeof(int));
|
||||
SafeWrite (h, &numpr_globals, sizeof(int));
|
||||
SafeWrite (h, &numfielddefs, sizeof(int));
|
||||
SafeWrite (h, &numstatements, sizeof(int));
|
||||
SafeWrite (h, statement_linenums, numstatements*sizeof(int));
|
||||
SafeClose (h);
|
||||
*/
|
||||
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
}
|
||||
|
||||
/* ensure all data is in LE format */
|
||||
util_endianswap(&code_header, 1, sizeof(prog_header));
|
||||
util_endianswap(code_statements, vec_size(code_statements), sizeof(prog_section_statement));
|
||||
|
|
6
gmqcc.h
6
gmqcc.h
|
@ -537,6 +537,7 @@ enum {
|
|||
};
|
||||
|
||||
extern prog_section_statement *code_statements;
|
||||
extern int *code_linenums;
|
||||
extern prog_section_def *code_defs;
|
||||
extern prog_section_field *code_fields;
|
||||
extern prog_section_function *code_functions;
|
||||
|
@ -551,12 +552,15 @@ typedef int32_t qcint;
|
|||
* code_write -- writes out the compiled file
|
||||
* code_init -- prepares the code file
|
||||
*/
|
||||
bool code_write (const char *filename);
|
||||
bool code_write (const char *filename, const char *lno);
|
||||
void code_init ();
|
||||
uint32_t code_genstring (const char *string);
|
||||
uint32_t code_cachedstring(const char *string);
|
||||
qcint code_alloc_field (size_t qcsize);
|
||||
|
||||
/* this function is used to keep statements and linenumbers together */
|
||||
void code_push_statement(prog_section_statement *stmt, int linenum);
|
||||
|
||||
/*
|
||||
* A shallow copy of a lex_file to remember where which ast node
|
||||
* came from.
|
||||
|
|
146
ir.c
146
ir.c
|
@ -594,12 +594,12 @@ bool ir_function_pass_tailcall(ir_function *self)
|
|||
/* emite parameter-stores */
|
||||
for (p = 0; p < vec_size(call->params); ++p) {
|
||||
/* assert(call->params_count <= self->locals_count); */
|
||||
if (!ir_block_create_store(block, self->locals[p], call->params[p])) {
|
||||
if (!ir_block_create_store(block, call->context, self->locals[p], call->params[p])) {
|
||||
irerror(call->context, "failed to create tailcall store instruction for parameter %i", (int)p);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!ir_block_create_jump(block, self->blocks[0])) {
|
||||
if (!ir_block_create_jump(block, call->context, self->blocks[0])) {
|
||||
irerror(call->context, "failed to create tailcall jump");
|
||||
return false;
|
||||
}
|
||||
|
@ -727,7 +727,7 @@ bool ir_block_set_label(ir_block *self, const char *name)
|
|||
*IR Instructions
|
||||
*/
|
||||
|
||||
ir_instr* ir_instr_new(ir_block* owner, int op)
|
||||
ir_instr* ir_instr_new(lex_ctx ctx, ir_block* owner, int op)
|
||||
{
|
||||
ir_instr *self;
|
||||
self = (ir_instr*)mem_a(sizeof(*self));
|
||||
|
@ -735,8 +735,7 @@ ir_instr* ir_instr_new(ir_block* owner, int op)
|
|||
return NULL;
|
||||
|
||||
self->owner = owner;
|
||||
self->context.file = "<@no context>";
|
||||
self->context.line = 0;
|
||||
self->context = ctx;
|
||||
self->opcode = op;
|
||||
self->_ops[0] = NULL;
|
||||
self->_ops[1] = NULL;
|
||||
|
@ -1228,14 +1227,14 @@ bool ir_values_overlap(const ir_value *a, const ir_value *b)
|
|||
*IR main operations
|
||||
*/
|
||||
|
||||
bool ir_block_create_store_op(ir_block *self, int op, ir_value *target, ir_value *what)
|
||||
bool ir_block_create_store_op(ir_block *self, lex_ctx ctx, int op, ir_value *target, ir_value *what)
|
||||
{
|
||||
ir_instr *in;
|
||||
if (self->final) {
|
||||
irerror(self->context, "unreachable statement (%s)", self->label);
|
||||
return false;
|
||||
}
|
||||
in = ir_instr_new(self, op);
|
||||
in = ir_instr_new(ctx, self, op);
|
||||
if (!in)
|
||||
return false;
|
||||
|
||||
|
@ -1257,7 +1256,7 @@ bool ir_block_create_store_op(ir_block *self, int op, ir_value *target, ir_value
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ir_block_create_store(ir_block *self, ir_value *target, ir_value *what)
|
||||
bool ir_block_create_store(ir_block *self, lex_ctx ctx, ir_value *target, ir_value *what)
|
||||
{
|
||||
int op = 0;
|
||||
int vtype;
|
||||
|
@ -1279,10 +1278,10 @@ bool ir_block_create_store(ir_block *self, ir_value *target, ir_value *what)
|
|||
op = INSTR_STORE_V;
|
||||
}
|
||||
|
||||
return ir_block_create_store_op(self, op, target, what);
|
||||
return ir_block_create_store_op(self, ctx, op, target, what);
|
||||
}
|
||||
|
||||
bool ir_block_create_storep(ir_block *self, ir_value *target, ir_value *what)
|
||||
bool ir_block_create_storep(ir_block *self, lex_ctx ctx, ir_value *target, ir_value *what)
|
||||
{
|
||||
int op = 0;
|
||||
int vtype;
|
||||
|
@ -1301,10 +1300,10 @@ bool ir_block_create_storep(ir_block *self, ir_value *target, ir_value *what)
|
|||
op = INSTR_STOREP_V;
|
||||
}
|
||||
|
||||
return ir_block_create_store_op(self, op, target, what);
|
||||
return ir_block_create_store_op(self, ctx, op, target, what);
|
||||
}
|
||||
|
||||
bool ir_block_create_return(ir_block *self, ir_value *v)
|
||||
bool ir_block_create_return(ir_block *self, lex_ctx ctx, ir_value *v)
|
||||
{
|
||||
ir_instr *in;
|
||||
if (self->final) {
|
||||
|
@ -1313,7 +1312,7 @@ bool ir_block_create_return(ir_block *self, ir_value *v)
|
|||
}
|
||||
self->final = true;
|
||||
self->is_return = true;
|
||||
in = ir_instr_new(self, INSTR_RETURN);
|
||||
in = ir_instr_new(ctx, self, INSTR_RETURN);
|
||||
if (!in)
|
||||
return false;
|
||||
|
||||
|
@ -1324,7 +1323,7 @@ bool ir_block_create_return(ir_block *self, ir_value *v)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ir_block_create_if(ir_block *self, ir_value *v,
|
||||
bool ir_block_create_if(ir_block *self, lex_ctx ctx, ir_value *v,
|
||||
ir_block *ontrue, ir_block *onfalse)
|
||||
{
|
||||
ir_instr *in;
|
||||
|
@ -1333,8 +1332,8 @@ bool ir_block_create_if(ir_block *self, ir_value *v,
|
|||
return false;
|
||||
}
|
||||
self->final = true;
|
||||
/*in = ir_instr_new(self, (v->vtype == TYPE_STRING ? INSTR_IF_S : INSTR_IF_F));*/
|
||||
in = ir_instr_new(self, VINSTR_COND);
|
||||
/*in = ir_instr_new(ctx, self, (v->vtype == TYPE_STRING ? INSTR_IF_S : INSTR_IF_F));*/
|
||||
in = ir_instr_new(ctx, self, VINSTR_COND);
|
||||
if (!in)
|
||||
return false;
|
||||
|
||||
|
@ -1355,7 +1354,7 @@ bool ir_block_create_if(ir_block *self, ir_value *v,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ir_block_create_jump(ir_block *self, ir_block *to)
|
||||
bool ir_block_create_jump(ir_block *self, lex_ctx ctx, ir_block *to)
|
||||
{
|
||||
ir_instr *in;
|
||||
if (self->final) {
|
||||
|
@ -1363,7 +1362,7 @@ bool ir_block_create_jump(ir_block *self, ir_block *to)
|
|||
return false;
|
||||
}
|
||||
self->final = true;
|
||||
in = ir_instr_new(self, VINSTR_JUMP);
|
||||
in = ir_instr_new(ctx, self, VINSTR_JUMP);
|
||||
if (!in)
|
||||
return false;
|
||||
|
||||
|
@ -1375,7 +1374,7 @@ bool ir_block_create_jump(ir_block *self, ir_block *to)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ir_block_create_goto(ir_block *self, ir_block *to)
|
||||
bool ir_block_create_goto(ir_block *self, lex_ctx ctx, ir_block *to)
|
||||
{
|
||||
ir_instr *in;
|
||||
if (self->final) {
|
||||
|
@ -1383,7 +1382,7 @@ bool ir_block_create_goto(ir_block *self, ir_block *to)
|
|||
return false;
|
||||
}
|
||||
self->final = true;
|
||||
in = ir_instr_new(self, INSTR_GOTO);
|
||||
in = ir_instr_new(ctx, self, INSTR_GOTO);
|
||||
if (!in)
|
||||
return false;
|
||||
|
||||
|
@ -1395,11 +1394,11 @@ bool ir_block_create_goto(ir_block *self, ir_block *to)
|
|||
return true;
|
||||
}
|
||||
|
||||
ir_instr* ir_block_create_phi(ir_block *self, const char *label, int ot)
|
||||
ir_instr* ir_block_create_phi(ir_block *self, lex_ctx ctx, const char *label, int ot)
|
||||
{
|
||||
ir_value *out;
|
||||
ir_instr *in;
|
||||
in = ir_instr_new(self, VINSTR_PHI);
|
||||
in = ir_instr_new(ctx, self, VINSTR_PHI);
|
||||
if (!in)
|
||||
return NULL;
|
||||
out = ir_value_out(self->owner, label, store_value, ot);
|
||||
|
@ -1440,11 +1439,11 @@ void ir_phi_add(ir_instr* self, ir_block *b, ir_value *v)
|
|||
}
|
||||
|
||||
/* call related code */
|
||||
ir_instr* ir_block_create_call(ir_block *self, const char *label, ir_value *func)
|
||||
ir_instr* ir_block_create_call(ir_block *self, lex_ctx ctx, const char *label, ir_value *func)
|
||||
{
|
||||
ir_value *out;
|
||||
ir_instr *in;
|
||||
in = ir_instr_new(self, INSTR_CALL0);
|
||||
in = ir_instr_new(ctx, self, INSTR_CALL0);
|
||||
if (!in)
|
||||
return NULL;
|
||||
out = ir_value_out(self->owner, label, (func->outtype == TYPE_VOID) ? store_return : store_value, func->outtype);
|
||||
|
@ -1476,7 +1475,7 @@ void ir_call_param(ir_instr* self, ir_value *v)
|
|||
|
||||
/* binary op related code */
|
||||
|
||||
ir_value* ir_block_create_binop(ir_block *self,
|
||||
ir_value* ir_block_create_binop(ir_block *self, lex_ctx ctx,
|
||||
const char *label, int opcode,
|
||||
ir_value *left, ir_value *right)
|
||||
{
|
||||
|
@ -1565,10 +1564,10 @@ ir_value* ir_block_create_binop(ir_block *self,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
return ir_block_create_general_instr(self, label, opcode, left, right, ot);
|
||||
return ir_block_create_general_instr(self, ctx, label, opcode, left, right, ot);
|
||||
}
|
||||
|
||||
ir_value* ir_block_create_unary(ir_block *self,
|
||||
ir_value* ir_block_create_unary(ir_block *self, lex_ctx ctx,
|
||||
const char *label, int opcode,
|
||||
ir_value *operand)
|
||||
{
|
||||
|
@ -1598,10 +1597,10 @@ ir_value* ir_block_create_unary(ir_block *self,
|
|||
}
|
||||
|
||||
/* let's use the general instruction creator and pass NULL for OPB */
|
||||
return ir_block_create_general_instr(self, label, opcode, operand, NULL, ot);
|
||||
return ir_block_create_general_instr(self, ctx, label, opcode, operand, NULL, ot);
|
||||
}
|
||||
|
||||
ir_value* ir_block_create_general_instr(ir_block *self, const char *label,
|
||||
ir_value* ir_block_create_general_instr(ir_block *self, lex_ctx ctx, const char *label,
|
||||
int op, ir_value *a, ir_value *b, int outype)
|
||||
{
|
||||
ir_instr *instr;
|
||||
|
@ -1611,7 +1610,7 @@ ir_value* ir_block_create_general_instr(ir_block *self, const char *label,
|
|||
if (!out)
|
||||
return NULL;
|
||||
|
||||
instr = ir_instr_new(self, op);
|
||||
instr = ir_instr_new(ctx, self, op);
|
||||
if (!instr) {
|
||||
ir_value_delete(out);
|
||||
return NULL;
|
||||
|
@ -1633,7 +1632,7 @@ on_error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
ir_value* ir_block_create_fieldaddress(ir_block *self, const char *label, ir_value *ent, ir_value *field)
|
||||
ir_value* ir_block_create_fieldaddress(ir_block *self, lex_ctx ctx, const char *label, ir_value *ent, ir_value *field)
|
||||
{
|
||||
ir_value *v;
|
||||
|
||||
|
@ -1644,12 +1643,12 @@ ir_value* ir_block_create_fieldaddress(ir_block *self, const char *label, ir_val
|
|||
if (field->vtype != TYPE_FIELD)
|
||||
return NULL;
|
||||
|
||||
v = ir_block_create_general_instr(self, label, INSTR_ADDRESS, ent, field, TYPE_POINTER);
|
||||
v = ir_block_create_general_instr(self, ctx, label, INSTR_ADDRESS, ent, field, TYPE_POINTER);
|
||||
v->fieldtype = field->fieldtype;
|
||||
return v;
|
||||
}
|
||||
|
||||
ir_value* ir_block_create_load_from_ent(ir_block *self, const char *label, ir_value *ent, ir_value *field, int outype)
|
||||
ir_value* ir_block_create_load_from_ent(ir_block *self, lex_ctx ctx, const char *label, ir_value *ent, ir_value *field, int outype)
|
||||
{
|
||||
int op;
|
||||
if (ent->vtype != TYPE_ENTITY)
|
||||
|
@ -1676,10 +1675,10 @@ ir_value* ir_block_create_load_from_ent(ir_block *self, const char *label, ir_va
|
|||
return NULL;
|
||||
}
|
||||
|
||||
return ir_block_create_general_instr(self, label, op, ent, field, outype);
|
||||
return ir_block_create_general_instr(self, ctx, label, op, ent, field, outype);
|
||||
}
|
||||
|
||||
ir_value* ir_block_create_add(ir_block *self,
|
||||
ir_value* ir_block_create_add(ir_block *self, lex_ctx ctx,
|
||||
const char *label,
|
||||
ir_value *left, ir_value *right)
|
||||
{
|
||||
|
@ -1716,10 +1715,10 @@ ir_value* ir_block_create_add(ir_block *self,
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
return ir_block_create_binop(self, label, op, left, right);
|
||||
return ir_block_create_binop(self, ctx, label, op, left, right);
|
||||
}
|
||||
|
||||
ir_value* ir_block_create_sub(ir_block *self,
|
||||
ir_value* ir_block_create_sub(ir_block *self, lex_ctx ctx,
|
||||
const char *label,
|
||||
ir_value *left, ir_value *right)
|
||||
{
|
||||
|
@ -1757,10 +1756,10 @@ ir_value* ir_block_create_sub(ir_block *self,
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
return ir_block_create_binop(self, label, op, left, right);
|
||||
return ir_block_create_binop(self, ctx, label, op, left, right);
|
||||
}
|
||||
|
||||
ir_value* ir_block_create_mul(ir_block *self,
|
||||
ir_value* ir_block_create_mul(ir_block *self, lex_ctx ctx,
|
||||
const char *label,
|
||||
ir_value *left, ir_value *right)
|
||||
{
|
||||
|
@ -1805,10 +1804,10 @@ ir_value* ir_block_create_mul(ir_block *self,
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
return ir_block_create_binop(self, label, op, left, right);
|
||||
return ir_block_create_binop(self, ctx, label, op, left, right);
|
||||
}
|
||||
|
||||
ir_value* ir_block_create_div(ir_block *self,
|
||||
ir_value* ir_block_create_div(ir_block *self, lex_ctx ctx,
|
||||
const char *label,
|
||||
ir_value *left, ir_value *right)
|
||||
{
|
||||
|
@ -1845,7 +1844,7 @@ ir_value* ir_block_create_div(ir_block *self,
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
return ir_block_create_binop(self, label, op, left, right);
|
||||
return ir_block_create_binop(self, ctx, label, op, left, right);
|
||||
}
|
||||
|
||||
/* PHI resolving breaks the SSA, and must thus be the last
|
||||
|
@ -1921,7 +1920,7 @@ static bool ir_block_naive_phi(ir_block *self)
|
|||
vec_pop(b->instr);
|
||||
b->final = false;
|
||||
instr->_ops[0]->store = store_global;
|
||||
if (!ir_block_create_store(b, instr->_ops[0], v))
|
||||
if (!ir_block_create_store(b, instr->context, instr->_ops[0], v))
|
||||
return false;
|
||||
instr->_ops[0]->store = store_value;
|
||||
vec_push(b->instr, prevjump);
|
||||
|
@ -2560,7 +2559,7 @@ tailcall:
|
|||
stmt.o1.s1 = (target->code_start) - vec_size(code_statements);
|
||||
stmt.o2.s1 = 0;
|
||||
stmt.o3.s1 = 0;
|
||||
vec_push(code_statements, stmt);
|
||||
code_push_statement(&stmt, instr->context.line);
|
||||
|
||||
/* no further instructions can be in this block */
|
||||
return true;
|
||||
|
@ -2580,12 +2579,12 @@ tailcall:
|
|||
if (ontrue->generated) {
|
||||
stmt.opcode = INSTR_IF;
|
||||
stmt.o2.s1 = (ontrue->code_start) - vec_size(code_statements);
|
||||
vec_push(code_statements, stmt);
|
||||
code_push_statement(&stmt, instr->context.line);
|
||||
}
|
||||
if (onfalse->generated) {
|
||||
stmt.opcode = INSTR_IFNOT;
|
||||
stmt.o2.s1 = (onfalse->code_start) - vec_size(code_statements);
|
||||
vec_push(code_statements, stmt);
|
||||
code_push_statement(&stmt, instr->context.line);
|
||||
}
|
||||
if (!ontrue->generated) {
|
||||
if (onfalse->generated) {
|
||||
|
@ -2609,7 +2608,7 @@ tailcall:
|
|||
ontrue = tmp;
|
||||
}
|
||||
stidx = vec_size(code_statements);
|
||||
vec_push(code_statements, stmt);
|
||||
code_push_statement(&stmt, instr->context.line);
|
||||
/* on false we jump, so add ontrue-path */
|
||||
if (!gen_blocks_recursive(func, ontrue))
|
||||
return false;
|
||||
|
@ -2634,7 +2633,7 @@ tailcall:
|
|||
stmt.o1.s1 = (onfalse->code_start) - vec_size(code_statements);
|
||||
stmt.o2.s1 = 0;
|
||||
stmt.o3.s1 = 0;
|
||||
vec_push(code_statements, stmt);
|
||||
code_push_statement(&stmt, instr->context.line);
|
||||
return true;
|
||||
}
|
||||
/* if not, generate now */
|
||||
|
@ -2675,7 +2674,7 @@ tailcall:
|
|||
stmt.opcode = type_store_instr[param->vtype];
|
||||
stmt.o1.u1 = ir_value_code_addr(param);
|
||||
stmt.o2.u1 = OFS_PARM0 + 3 * p;
|
||||
vec_push(code_statements, stmt);
|
||||
code_push_statement(&stmt, instr->context.line);
|
||||
}
|
||||
/* Now handle extparams */
|
||||
first = vec_size(instr->params);
|
||||
|
@ -2701,7 +2700,7 @@ tailcall:
|
|||
stmt.opcode = type_store_instr[param->vtype];
|
||||
stmt.o1.u1 = ir_value_code_addr(param);
|
||||
stmt.o2.u1 = ir_value_code_addr(targetparam);
|
||||
vec_push(code_statements, stmt);
|
||||
code_push_statement(&stmt, instr->context.line);
|
||||
}
|
||||
|
||||
stmt.opcode = INSTR_CALL0 + vec_size(instr->params);
|
||||
|
@ -2710,7 +2709,7 @@ tailcall:
|
|||
stmt.o1.u1 = ir_value_code_addr(instr->_ops[1]);
|
||||
stmt.o2.u1 = 0;
|
||||
stmt.o3.u1 = 0;
|
||||
vec_push(code_statements, stmt);
|
||||
code_push_statement(&stmt, instr->context.line);
|
||||
|
||||
retvalue = instr->_ops[0];
|
||||
if (retvalue && retvalue->store != store_return && vec_size(retvalue->life))
|
||||
|
@ -2723,7 +2722,7 @@ tailcall:
|
|||
stmt.o1.u1 = OFS_RETURN;
|
||||
stmt.o2.u1 = ir_value_code_addr(retvalue);
|
||||
stmt.o3.u1 = 0;
|
||||
vec_push(code_statements, stmt);
|
||||
code_push_statement(&stmt, instr->context.line);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@ -2763,7 +2762,7 @@ tailcall:
|
|||
stmt.o3.u1 = 0;
|
||||
}
|
||||
|
||||
vec_push(code_statements, stmt);
|
||||
code_push_statement(&stmt, instr->context.line);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -2795,7 +2794,7 @@ static bool gen_function_code(ir_function *self)
|
|||
stmt.o1.u1 = 0;
|
||||
stmt.o2.u1 = 0;
|
||||
stmt.o3.u1 = 0;
|
||||
vec_push(code_statements, stmt);
|
||||
code_push_statement(&stmt, vec_last(code_linenums));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2937,7 +2936,7 @@ static bool gen_function_extparam_copy(ir_function *self)
|
|||
}
|
||||
stmt.o1.u1 = ir_value_code_addr(ep);
|
||||
stmt.o2.u1 = ir_value_code_addr(self->locals[i]);
|
||||
vec_push(code_statements, stmt);
|
||||
code_push_statement(&stmt, self->context.line);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -3190,6 +3189,7 @@ bool ir_builder_generate(ir_builder *self, const char *filename)
|
|||
{
|
||||
prog_section_statement stmt;
|
||||
size_t i;
|
||||
char *lnofile = NULL;
|
||||
|
||||
code_init();
|
||||
|
||||
|
@ -3230,11 +3230,39 @@ bool ir_builder_generate(ir_builder *self, const char *filename)
|
|||
stmt.o1.u1 = 0;
|
||||
stmt.o2.u1 = 0;
|
||||
stmt.o3.u1 = 0;
|
||||
vec_push(code_statements, stmt);
|
||||
code_push_statement(&stmt, vec_last(code_linenums));
|
||||
|
||||
if (!opts_pp_only)
|
||||
con_out("writing '%s'...\n", filename);
|
||||
return code_write(filename);
|
||||
if (opts_pp_only)
|
||||
return true;
|
||||
|
||||
if (vec_size(code_statements) != vec_size(code_linenums)) {
|
||||
con_err("Linecounter wrong: %lu != %lu\n",
|
||||
(unsigned long)vec_size(code_statements),
|
||||
(unsigned long)vec_size(code_linenums));
|
||||
} else if (OPTS_FLAG(LNO)) {
|
||||
char *dot;
|
||||
size_t filelen = strlen(filename);
|
||||
|
||||
memcpy(vec_add(lnofile, filelen+1), filename, filelen+1);
|
||||
dot = strrchr(lnofile, '.');
|
||||
if (!dot) {
|
||||
vec_pop(lnofile);
|
||||
} else {
|
||||
vec_shrinkto(lnofile, dot - lnofile);
|
||||
}
|
||||
memcpy(vec_add(lnofile, 5), ".lno", 5);
|
||||
}
|
||||
|
||||
if (lnofile)
|
||||
con_out("writing '%s' and '%s'...\n", filename, lnofile);
|
||||
else
|
||||
con_out("writing '%s'\n", filename);
|
||||
if (!code_write(filename, lnofile)) {
|
||||
vec_free(lnofile);
|
||||
return false;
|
||||
}
|
||||
vec_free(lnofile);
|
||||
return true;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
|
38
ir.h
38
ir.h
|
@ -141,7 +141,7 @@ typedef struct ir_instr_s
|
|||
struct ir_block_s *owner;
|
||||
} ir_instr;
|
||||
|
||||
ir_instr* ir_instr_new(struct ir_block_s *owner, int opcode);
|
||||
ir_instr* ir_instr_new(lex_ctx ctx, struct ir_block_s *owner, int opcode);
|
||||
void ir_instr_delete(ir_instr*);
|
||||
|
||||
bool GMQCC_WARN vec_ir_instr_find(ir_instr **vec, ir_instr *what, size_t *idx);
|
||||
|
@ -178,39 +178,39 @@ void ir_block_delete(ir_block*);
|
|||
|
||||
bool ir_block_set_label(ir_block*, const char *label);
|
||||
|
||||
ir_value* ir_block_create_binop(ir_block*, const char *label, int op,
|
||||
ir_value* ir_block_create_binop(ir_block*, lex_ctx, const char *label, int op,
|
||||
ir_value *left, ir_value *right);
|
||||
ir_value* ir_block_create_unary(ir_block*, const char *label, int op,
|
||||
ir_value* ir_block_create_unary(ir_block*, lex_ctx, const char *label, int op,
|
||||
ir_value *operand);
|
||||
bool GMQCC_WARN ir_block_create_store_op(ir_block*, int op, ir_value *target, ir_value *what);
|
||||
bool GMQCC_WARN ir_block_create_store(ir_block*, ir_value *target, ir_value *what);
|
||||
bool GMQCC_WARN ir_block_create_storep(ir_block*, ir_value *target, ir_value *what);
|
||||
bool GMQCC_WARN ir_block_create_store_op(ir_block*, lex_ctx, int op, ir_value *target, ir_value *what);
|
||||
bool GMQCC_WARN ir_block_create_store(ir_block*, lex_ctx, ir_value *target, ir_value *what);
|
||||
bool GMQCC_WARN ir_block_create_storep(ir_block*, lex_ctx, ir_value *target, ir_value *what);
|
||||
|
||||
/* field must be of TYPE_FIELD */
|
||||
ir_value* ir_block_create_load_from_ent(ir_block*, const char *label, ir_value *ent, ir_value *field, int outype);
|
||||
ir_value* ir_block_create_load_from_ent(ir_block*, lex_ctx, const char *label, ir_value *ent, ir_value *field, int outype);
|
||||
|
||||
ir_value* ir_block_create_fieldaddress(ir_block*, const char *label, ir_value *entity, ir_value *field);
|
||||
ir_value* ir_block_create_fieldaddress(ir_block*, lex_ctx, const char *label, ir_value *entity, ir_value *field);
|
||||
|
||||
/* This is to create an instruction of the form
|
||||
* <outtype>%label := opcode a, b
|
||||
*/
|
||||
ir_value* ir_block_create_general_instr(ir_block *self, const char *label,
|
||||
ir_value* ir_block_create_general_instr(ir_block *self, lex_ctx, const char *label,
|
||||
int op, ir_value *a, ir_value *b, int outype);
|
||||
|
||||
ir_value* ir_block_create_add(ir_block*, const char *label, ir_value *l, ir_value *r);
|
||||
ir_value* ir_block_create_sub(ir_block*, const char *label, ir_value *l, ir_value *r);
|
||||
ir_value* ir_block_create_mul(ir_block*, const char *label, ir_value *l, ir_value *r);
|
||||
ir_value* ir_block_create_div(ir_block*, const char *label, ir_value *l, ir_value *r);
|
||||
ir_instr* ir_block_create_phi(ir_block*, const char *label, int vtype);
|
||||
ir_value* ir_block_create_add(ir_block*, lex_ctx, const char *label, ir_value *l, ir_value *r);
|
||||
ir_value* ir_block_create_sub(ir_block*, lex_ctx, const char *label, ir_value *l, ir_value *r);
|
||||
ir_value* ir_block_create_mul(ir_block*, lex_ctx, const char *label, ir_value *l, ir_value *r);
|
||||
ir_value* ir_block_create_div(ir_block*, lex_ctx, const char *label, ir_value *l, ir_value *r);
|
||||
ir_instr* ir_block_create_phi(ir_block*, lex_ctx, const char *label, int vtype);
|
||||
ir_value* ir_phi_value(ir_instr*);
|
||||
void ir_phi_add(ir_instr*, ir_block *b, ir_value *v);
|
||||
ir_instr* ir_block_create_call(ir_block*, const char *label, ir_value *func);
|
||||
ir_instr* ir_block_create_call(ir_block*, lex_ctx, const char *label, ir_value *func);
|
||||
ir_value* ir_call_value(ir_instr*);
|
||||
void ir_call_param(ir_instr*, ir_value*);
|
||||
|
||||
bool GMQCC_WARN ir_block_create_return(ir_block*, ir_value *opt_value);
|
||||
bool GMQCC_WARN ir_block_create_return(ir_block*, lex_ctx, ir_value *opt_value);
|
||||
|
||||
bool GMQCC_WARN ir_block_create_if(ir_block*, ir_value *cond,
|
||||
bool GMQCC_WARN ir_block_create_if(ir_block*, lex_ctx, ir_value *cond,
|
||||
ir_block *ontrue, ir_block *onfalse);
|
||||
/* A 'goto' is an actual 'goto' coded in QC, whereas
|
||||
* a 'jump' is a virtual construct which simply names the
|
||||
|
@ -218,8 +218,8 @@ bool GMQCC_WARN ir_block_create_if(ir_block*, ir_value *cond,
|
|||
* A goto usually becomes an OP_GOTO in the resulting code,
|
||||
* whereas a 'jump' usually doesn't add any actual instruction.
|
||||
*/
|
||||
bool GMQCC_WARN ir_block_create_jump(ir_block*, ir_block *to);
|
||||
bool GMQCC_WARN ir_block_create_goto(ir_block*, ir_block *to);
|
||||
bool GMQCC_WARN ir_block_create_jump(ir_block*, lex_ctx, ir_block *to);
|
||||
bool GMQCC_WARN ir_block_create_goto(ir_block*, lex_ctx, ir_block *to);
|
||||
|
||||
void ir_block_dump(ir_block*, char *ind, int (*oprintf)(const char*,...));
|
||||
|
||||
|
|
1
opts.def
1
opts.def
|
@ -38,6 +38,7 @@
|
|||
GMQCC_DEFINE_FLAG(TRANSLATABLE_STRINGS)
|
||||
GMQCC_DEFINE_FLAG(INITIALIZED_NONCONSTANTS)
|
||||
GMQCC_DEFINE_FLAG(ASSIGN_FUNCTION_TYPES)
|
||||
GMQCC_DEFINE_FLAG(LNO)
|
||||
#endif
|
||||
|
||||
/* warning flags */
|
||||
|
|
Loading…
Reference in a new issue