]> git.xonotic.org Git - xonotic/gmqcc.git/commitdiff
Merge branch 'master' into blub/bc3
authorWolfgang (Blub) Bumiller <blub@speed.at>
Fri, 10 Aug 2012 18:48:42 +0000 (20:48 +0200)
committerWolfgang (Blub) Bumiller <blub@speed.at>
Fri, 10 Aug 2012 18:48:42 +0000 (20:48 +0200)
1  2 
ast.c
ast.h
ir.c
ir.h

diff --combined ast.c
index 65c6934b000d2ce65dec16a0ffed4a0f897a7d80,c19fad2656ba70d43a2d3d3b242c512548bc9ce4..5f947b0e02903709cde800090c03f877a1b31048
--- 1/ast.c
--- 2/ast.c
+++ b/ast.c
@@@ -202,18 -202,6 +202,18 @@@ ast_binary* ast_binary_new(lex_ctx ctx
      self->left = left;
      self->right = right;
  
 +    if (op >= INSTR_EQ_F && op <= INSTR_GT)
 +        self->expression.vtype = TYPE_FLOAT;
 +    else if (op == INSTR_AND || op == INSTR_OR ||
 +             op == INSTR_BITAND || op == INSTR_BITOR)
 +        self->expression.vtype = TYPE_FLOAT;
 +    else if (op == INSTR_MUL_VF || op == INSTR_MUL_FV)
 +        self->expression.vtype = TYPE_VECTOR;
 +    else if (op == INSTR_MUL_V)
 +        self->expression.vtype = TYPE_FLOAT;
 +    else
 +        self->expression.vtype = left->expression.vtype;
 +
      return self;
  }
  
@@@ -298,6 -286,32 +298,32 @@@ void ast_entfield_delete(ast_entfield *
      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);
@@@ -603,10 -617,8 +629,10 @@@ bool ast_global_codegen(ast_value *self
      }
  
      v = ir_builder_create_global(ir, self->name, self->expression.vtype);
 -    if (!v)
 +    if (!v) {
 +        printf("ir_builder_create_global failed\n");
          return false;
 +    }
  
      if (self->isconst) {
          switch (self->expression.vtype)
@@@ -925,6 -937,23 +951,23 @@@ bool ast_entfield_codegen(ast_entfield 
      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;
diff --combined ast.h
index c96484f66b933e24143714e5d808d26fd29dff06,5a09b434764598f282d7ecf10f8981a8b65d2eb7..3b7ebdca0c22aceea61ead4ec6baceeb5ab3c0e7
--- 1/ast.h
--- 2/ast.h
+++ b/ast.h
@@@ -43,6 -43,7 +43,7 @@@ typedef struct ast_loop_s       ast_loo
  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 +59,8 @@@
      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) )
@@@ -131,8 -133,6 +133,8 @@@ struct ast_value_
          const char   *vstring;
          int           ventity;
          ast_function *vfunc;
 +        quaternion    vquat;
 +        matrix        vmat;
      } constval;
  
      ir_value *ir_v;
@@@ -231,6 -231,22 +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.
diff --combined ir.c
index fb6f4e90ca330bde92f830b4590abdfa0df265c1,42999c53564770bb53e3910993b630d57568f7ae..f31c224343ccf09d9c721c0b6b1b5d89d3245e1b
--- 1/ir.c
--- 2/ir.c
+++ b/ir.c
   * Type sizes used at multiple points in the IR codegen
   */
  
 +const char *type_name[TYPE_COUNT] = {
 +    "void",
 +    "string",
 +    "float",
 +    "vector",
 +    "entity",
 +    "field",
 +    "function",
 +    "pointer",
 +#if 0
 +    "integer",
 +#endif
 +    "quaternion",
 +    "matrix",
 +    "variant"
 +};
 +
  size_t type_sizeof[TYPE_COUNT] = {
      1, /* TYPE_VOID     */
      1, /* TYPE_STRING   */
@@@ -58,9 -41,7 +58,9 @@@
  #if 0
      1, /* TYPE_INTEGER  */
  #endif
 -    3, /* TYPE_VARIANT  */
 +    4, /* TYPE_QUATERNION */
 +    16, /* TYPE_MATRIX */
 +    16, /* TYPE_VARIANT  */
  };
  
  uint16_t type_store_instr[TYPE_COUNT] = {
      INSTR_STORE_FNC,
      INSTR_STORE_ENT, /* should use I */
  #if 0
 -    INSTR_STORE_ENT, /* integer type */
 +    INSTR_STORE_I, /* integer type */
  #endif
 -    INSTR_STORE_V, /* variant, should never be accessed */
 +    INSTR_STORE_Q,
 +    INSTR_STORE_M,
 +
 +    INSTR_STORE_M, /* variant, should never be accessed */
  };
  
  uint16_t type_storep_instr[TYPE_COUNT] = {
  #if 0
      INSTR_STOREP_ENT, /* integer type */
  #endif
 -    INSTR_STOREP_V, /* variant, should never be accessed */
 +    INSTR_STOREP_Q,
 +    INSTR_STOREP_M,
 +
 +    INSTR_STOREP_M, /* variant, should never be accessed */
  };
  
  MEM_VEC_FUNCTIONS(ir_value_vector, ir_value*, v)
@@@ -212,14 -187,9 +212,14 @@@ ir_value* ir_builder_get_global(ir_buil
  
  ir_value* ir_builder_create_global(ir_builder *self, const char *name, int vtype)
  {
 -    ir_value *ve = ir_builder_get_global(self, name);
 -    if (ve) {
 -        return NULL;
 +    ir_value *ve;
 +
 +    if (name && name[0] != '#')
 +    {
 +        ve = ir_builder_get_global(self, name);
 +        if (ve) {
 +            return NULL;
 +        }
      }
  
      ve = ir_value_var(name, store_global, vtype);
@@@ -549,6 -519,11 +549,11 @@@ bool ir_instr_op(ir_instr *self, int op
   *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;
      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 -586,7 +616,7 @@@ ir_value* ir_value_out(ir_function *own
  
  void ir_value_delete(ir_value* self)
  {
+     size_t i;
      if (self->name)
          mem_d((void*)self->name);
      if (self->isconst)
          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);
@@@ -637,24 -638,6 +668,24 @@@ bool ir_value_set_vector(ir_value *self
      return true;
  }
  
 +bool ir_value_set_quaternion(ir_value *self, quaternion v)
 +{
 +    if (self->vtype != TYPE_QUATERNION)
 +        return false;
 +    memcpy(&self->constval.vquat, v, sizeof(self->constval.vquat));
 +    self->isconst = true;
 +    return true;
 +}
 +
 +bool ir_value_set_matrix(ir_value *self, matrix v)
 +{
 +    if (self->vtype != TYPE_MATRIX)
 +        return false;
 +    memcpy(&self->constval.vmat, v, sizeof(self->constval.vmat));
 +    self->isconst = true;
 +    return true;
 +}
 +
  bool ir_value_set_string(ir_value *self, const char *str)
  {
      if (self->vtype != TYPE_STRING)
@@@ -958,6 -941,7 +989,6 @@@ bool ir_block_create_storep(ir_block *s
      vtype = what->vtype;
  
      op = type_storep_instr[vtype];
 -
      return ir_block_create_store_op(self, op, target, what);
  }
  
@@@ -1352,8 -1336,6 +1383,8 @@@ ir_value* ir_block_create_load_from_ent
          case TYPE_POINTER: op = INSTR_LOAD_I;   break;
          case TYPE_INTEGER: op = INSTR_LOAD_I;   break;
  #endif
 +        case TYPE_QUATERNION: op = INSTR_LOAD_Q; break;
 +        case TYPE_MATRIX:     op = INSTR_LOAD_M; break;
          default:
              return NULL;
      }
@@@ -1457,22 -1439,12 +1488,22 @@@ ir_value* ir_block_create_mul(ir_block 
              case TYPE_VECTOR:
                  op = INSTR_MUL_V;
                  break;
 +            case TYPE_QUATERNION:
 +                op = INSTR_MUL_Q;
 +                break;
 +            case TYPE_MATRIX:
 +                op = INSTR_MUL_M;
 +                break;
          }
      } else {
          if ( (l == TYPE_VECTOR && r == TYPE_FLOAT) )
              op = INSTR_MUL_VF;
          else if ( (l == TYPE_FLOAT && r == TYPE_VECTOR) )
              op = INSTR_MUL_FV;
 +        else if ( (l == TYPE_QUATERNION && r == TYPE_FLOAT) )
 +            op = INSTR_MUL_QF;
 +        else if ( (l == TYPE_MATRIX && r == TYPE_FLOAT) )
 +            op = INSTR_MUL_MF;
  #if 0
          else if ( (l == TYPE_VECTOR && r == TYPE_INTEGER) )
              op = INSTR_MUL_VI;
@@@ -2237,7 -2209,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;
  
                  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;
              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)
                  /* 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;
  
          /* 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)
          {
@@@ -2528,8 -2500,6 +2559,8 @@@ static bool ir_builder_gen_global(ir_bu
          return global->code.globaladdr >= 0;
      }
      case TYPE_VECTOR:
 +    case TYPE_QUATERNION:
 +    case TYPE_MATRIX:
      {
          size_t d;
          if (code_defs_add(def) < 0)
@@@ -2782,7 -2752,6 +2813,7 @@@ void ir_value_dump(ir_value* v, int (*o
  {
        if (v->isconst) {
                switch (v->vtype) {
 +                  default:
                        case TYPE_VOID:
                                oprintf("(void)");
                                break;
diff --combined ir.h
index bfba8faace49f1c4708369f56b6dd1fd431cfe1c,e36aa086eb04f3d4a916d713dda275d37c6ad85f..a4dddcb937ea5a151f993e599f98b9a0f5b5881b
--- 1/ir.h
--- 2/ir.h
+++ b/ir.h
@@@ -55,8 -55,6 +55,8 @@@ typedef struct ir_value_s 
          char    *vstring;
          struct ir_value_s *vpointer;
          struct ir_function_s *vfunc;
 +        quaternion vquat;
 +        matrix     vmat;
      } constval;
  
      struct {
          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 -83,7 +85,7 @@@
  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);
@@@ -91,8 -97,6 +99,8 @@@ bool GMQCC_WARN ir_value_set_string(ir_
  bool GMQCC_WARN ir_value_set_vector(ir_value*, vector v);
  /*bool   ir_value_set_pointer_v(ir_value*, ir_value* p); */
  /*bool   ir_value_set_pointer_i(ir_value*, int i);       */
 +bool GMQCC_WARN ir_value_set_quaternion(ir_value*, quaternion v);
 +bool GMQCC_WARN ir_value_set_matrix(ir_value*, matrix v);
  
  MEM_VECTOR_PROTO(ir_value, ir_life_entry_t, life);
  /* merge an instruction into the life-range */