X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=ir.h;h=c8e7e0c162f0caf5e12315cc9633e88429c7248c;hb=890ca3c782c7c8dfc666e84b0898b8766de6f1dc;hp=7b5ab5e1d095e68db18bea3eddc12bc4d723a3ea;hpb=23e0637e85df29784ae335e8bc90bde362d72c24;p=xonotic%2Fgmqcc.git diff --git a/ir.h b/ir.h index 7b5ab5e..c8e7e0c 100644 --- a/ir.h +++ b/ir.h @@ -42,12 +42,14 @@ typedef struct ir_value_s { int fieldtype; /* and the output type of a function */ int outtype; + /* 'const' vs 'var' qualifier */ + int cvq; struct ir_instr_s **reads; struct ir_instr_s **writes; /* constantvalues */ - bool isconst; + bool hasvalue; union { float vfloat; int vint; @@ -65,12 +67,17 @@ typedef struct ir_value_s { int32_t local; /* added for members */ int32_t addroffset; + /* to generate field-addresses early */ + int32_t fieldaddr; } code; /* for acessing vectors */ struct ir_value_s *members[3]; struct ir_value_s *memberof; + /* arrays will never overlap with temps */ + bool unique_life; + /* For the temp allocator */ ir_life_entry_t *life; } ir_value; @@ -139,7 +146,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); @@ -176,39 +183,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 * %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, bool noreturn); 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 @@ -216,8 +223,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*,...)); @@ -230,6 +237,8 @@ typedef struct ir_function_s int *params; ir_block **blocks; + uint32_t flags; + int builtin; ir_value *value; @@ -263,6 +272,10 @@ typedef struct ir_function_s struct ir_builder_s *owner; } ir_function; +#define IR_FLAG_HAS_ARRAYS (1<<1) +#define IR_FLAG_HAS_UNINITIALIZED (1<<2) +#define IR_FLAG_HAS_GOTO (1<<3) +#define IR_FLAG_MASK_NO_OVERLAP (IR_FLAG_HAS_ARRAYS | IR_FLAG_HAS_UNINITIALIZED) ir_function* ir_function_new(struct ir_builder_s *owner, int returntype); void ir_function_delete(ir_function*); @@ -299,6 +312,10 @@ typedef struct ir_builder_s ir_value **extparams; + /* the highest func->allocated_locals */ + size_t max_locals; + uint32_t first_common_local; + const char **filenames; qcint *filestrings; /* we cache the #IMMEDIATE string here */