Merge branch 'master' into blub/bc3

This commit is contained in:
Wolfgang (Blub) Bumiller 2012-08-10 20:48:42 +02:00
commit 55743936d9
4 changed files with 108 additions and 8 deletions

43
ast.c
View file

@ -298,6 +298,32 @@ void ast_entfield_delete(ast_entfield *self)
mem_d(self);
}
ast_member* ast_member_new(lex_ctx ctx, ast_expression *owner, unsigned int field)
{
ast_instantiate(ast_member, ctx, ast_member_delete);
if (field >= 3) {
mem_d(self);
return NULL;
}
ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_member_codegen);
self->expression.vtype = TYPE_FLOAT;
self->expression.next = NULL;
self->owner = owner;
self->field = field;
return self;
}
void ast_member_delete(ast_member *self)
{
ast_unref(self->owner);
ast_expression_delete((ast_expression*)self);
mem_d(self);
}
ast_ifthen* ast_ifthen_new(lex_ctx ctx, ast_expression *cond, ast_expression *ontrue, ast_expression *onfalse)
{
ast_instantiate(ast_ifthen, ctx, ast_ifthen_delete);
@ -925,6 +951,23 @@ bool ast_entfield_codegen(ast_entfield *self, ast_function *func, bool lvalue, i
return true;
}
bool ast_member_codegen(ast_member *self, ast_function *func, bool lvalue, ir_value **out)
{
ast_expression_codegen *cgen;
ir_value *vec, *field;
cgen = self->owner->expression.codegen;
if (!(*cgen)((ast_expression*)(self->owner), func, true, &vec))
return false;
if (vec->vtype != TYPE_VECTOR)
return false;
*out = ir_value_vector_member(vec, self->field);
return (*out != NULL);
}
bool ast_ifthen_codegen(ast_ifthen *self, ast_function *func, bool lvalue, ir_value **out)
{
ast_expression_codegen *cgen;

20
ast.h
View file

@ -43,6 +43,7 @@ typedef struct ast_loop_s ast_loop;
typedef struct ast_call_s ast_call;
typedef struct ast_unary_s ast_unary;
typedef struct ast_return_s ast_return;
typedef struct ast_member_s ast_member;
enum {
TYPE_ast_node,
@ -58,7 +59,8 @@ enum {
TYPE_ast_loop,
TYPE_ast_call,
TYPE_ast_unary,
TYPE_ast_return
TYPE_ast_return,
TYPE_ast_member
};
#define ast_istype(x, t) ( ((ast_node_common*)x)->nodetype == (t) )
@ -231,6 +233,22 @@ void ast_entfield_delete(ast_entfield*);
bool ast_entfield_codegen(ast_entfield*, ast_function*, bool lvalue, ir_value**);
/* Member access:
*
* For now used for vectors. If we get structs or unions
* we can have them handled here as well.
*/
struct ast_member_s
{
ast_expression_common expression;
ast_expression *owner;
unsigned int field;
};
ast_member* ast_member_new(lex_ctx ctx, ast_expression *owner, unsigned int field);
void ast_member_delete(ast_member*);
bool ast_member_codegen(ast_member*, ast_function*, bool lvalue, ir_value**);
/* Store
*
* Stores left<-right and returns left.

45
ir.c
View file

@ -549,6 +549,11 @@ bool ir_instr_op(ir_instr *self, int op, ir_value *v, bool writing)
*IR Value
*/
int32_t ir_value_code_addr(const ir_value *self)
{
return self->code.globaladdr + self->code.addroffset;
}
ir_value* ir_value_var(const char *name, int storetype, int vtype)
{
ir_value *self;
@ -571,6 +576,27 @@ ir_value* ir_value_var(const char *name, int storetype, int vtype)
MEM_VECTOR_INIT(self, life);
return self;
}
ir_value* ir_value_vector_member(ir_value *self, unsigned int member)
{
ir_value *m;
if (member >= 3)
return NULL;
if (self->members[member])
return self->members[member];
m = ir_value_var(self->name, self->store, TYPE_FLOAT);
if (!m)
return NULL;
m->context = self->context;
self->members[member] = m;
m->code.addroffset = member;
return m;
}
MEM_VEC_FUNCTIONS(ir_value, ir_life_entry_t, life)
MEM_VEC_FUNCTIONS_ALL(ir_value, ir_instr*, reads)
MEM_VEC_FUNCTIONS_ALL(ir_value, ir_instr*, writes)
@ -590,6 +616,7 @@ ir_value* ir_value_out(ir_function *owner, const char *name, int storetype, int
void ir_value_delete(ir_value* self)
{
size_t i;
if (self->name)
mem_d((void*)self->name);
if (self->isconst)
@ -597,6 +624,10 @@ void ir_value_delete(ir_value* self)
if (self->vtype == TYPE_STRING)
mem_d((void*)self->constval.vstring);
}
for (i = 0; i < 3; ++i) {
if (self->members[i])
ir_value_delete(self->members[i]);
}
MEM_VECTOR_CLEAR(self, reads);
MEM_VECTOR_CLEAR(self, writes);
MEM_VECTOR_CLEAR(self, life);
@ -2237,7 +2268,7 @@ tailcall:
* come first: eg. optimize IFs without ELSE...
*/
stmt.o1.u1 = instr->_ops[0]->code.globaladdr;
stmt.o1.u1 = ir_value_code_addr(instr->_ops[0]);
stmt.o2.u1 = 0;
stmt.o3.s1 = 0;
@ -2316,7 +2347,7 @@ tailcall:
stmt.o3.u1 = 0;
stmt.opcode = type_store_instr[param->vtype];
stmt.o1.u1 = param->code.globaladdr;
stmt.o1.u1 = ir_value_code_addr(param);
stmt.o2.u1 = OFS_PARM0 + 3 * p;
if (code_statements_add(stmt) < 0)
return false;
@ -2324,7 +2355,7 @@ tailcall:
stmt.opcode = INSTR_CALL0 + instr->params_count;
if (stmt.opcode > INSTR_CALL8)
stmt.opcode = INSTR_CALL8;
stmt.o1.u1 = instr->_ops[1]->code.globaladdr;
stmt.o1.u1 = ir_value_code_addr(instr->_ops[1]);
stmt.o2.u1 = 0;
stmt.o3.u1 = 0;
if (code_statements_add(stmt) < 0)
@ -2336,7 +2367,7 @@ tailcall:
/* not to be kept in OFS_RETURN */
stmt.opcode = type_store_instr[retvalue->vtype];
stmt.o1.u1 = OFS_RETURN;
stmt.o2.u1 = retvalue->code.globaladdr;
stmt.o2.u1 = ir_value_code_addr(retvalue);
stmt.o3.u1 = 0;
if (code_statements_add(stmt) < 0)
return false;
@ -2356,13 +2387,13 @@ tailcall:
/* This is the general order of operands */
if (instr->_ops[0])
stmt.o3.u1 = instr->_ops[0]->code.globaladdr;
stmt.o3.u1 = ir_value_code_addr(instr->_ops[0]);
if (instr->_ops[1])
stmt.o1.u1 = instr->_ops[1]->code.globaladdr;
stmt.o1.u1 = ir_value_code_addr(instr->_ops[1]);
if (instr->_ops[2])
stmt.o2.u1 = instr->_ops[2]->code.globaladdr;
stmt.o2.u1 = ir_value_code_addr(instr->_ops[2]);
if (stmt.opcode == INSTR_RETURN || stmt.opcode == INSTR_DONE)
{

8
ir.h
View file

@ -64,12 +64,19 @@ typedef struct ir_value_s {
int32_t name;
/* filled by the local-allocator */
int32_t local;
/* added for members */
int32_t addroffset;
} code;
/* for acessing vectors */
struct ir_value_s *members[3];
/* For the temp allocator */
MEM_VECTOR_MAKE(ir_life_entry_t, life);
} ir_value;
int32_t ir_value_code_addr(const ir_value*);
/* ir_value can be a variable, or created by an operation */
ir_value* ir_value_var(const char *name, int st, int vtype);
/* if a result of an operation: the function should store
@ -78,6 +85,7 @@ ir_value* ir_value_var(const char *name, int st, int vtype);
ir_value* ir_value_out(struct ir_function_s *owner, const char *name, int st, int vtype);
void ir_value_delete(ir_value*);
void ir_value_set_name(ir_value*, const char *name);
ir_value* ir_value_vector_member(ir_value*, unsigned int member);
MEM_VECTOR_PROTO_ALL(ir_value, struct ir_instr_s*, reads);
MEM_VECTOR_PROTO_ALL(ir_value, struct ir_instr_s*, writes);