diff options
| author | Eric Anholt <eric@anholt.net> | 2010-05-07 11:31:47 -0700 | 
|---|---|---|
| committer | Eric Anholt <eric@anholt.net> | 2010-06-24 15:05:20 -0700 | 
| commit | c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627b (patch) | |
| tree | c5b9f049c56ba710f7f7b925bccb354b85765b45 | |
| parent | 38315079571512dc5b502d9522d7a8c3eaf2cc8f (diff) | |
ir_to_mesa: Add support for ir_if.
| -rw-r--r-- | ir_to_mesa.cpp | 138 | ||||
| -rw-r--r-- | ir_to_mesa.h | 9 | ||||
| -rw-r--r-- | mesa_codegen.brg | 8 | 
3 files changed, 125 insertions, 30 deletions
| diff --git a/ir_to_mesa.cpp b/ir_to_mesa.cpp index 465a8e1916..487e24986f 100644 --- a/ir_to_mesa.cpp +++ b/ir_to_mesa.cpp @@ -54,8 +54,13 @@ ir_to_mesa_src_reg ir_to_mesa_undef = {     PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP  }; +ir_to_mesa_dst_reg ir_to_mesa_undef_dst = { +   PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP +}; +  ir_to_mesa_instruction * -ir_to_mesa_emit_op3(struct mbtree *tree, enum prog_opcode op, +ir_to_mesa_emit_op3(ir_to_mesa_visitor *v, ir_instruction *ir, +		    enum prog_opcode op,  		    ir_to_mesa_dst_reg dst,  		    ir_to_mesa_src_reg src0,  		    ir_to_mesa_src_reg src1, @@ -68,45 +73,48 @@ ir_to_mesa_emit_op3(struct mbtree *tree, enum prog_opcode op,     inst->src_reg[0] = src0;     inst->src_reg[1] = src1;     inst->src_reg[2] = src2; -   inst->ir = tree->ir; +   inst->ir = ir; -   tree->v->instructions.push_tail(inst); +   v->instructions.push_tail(inst);     return inst;  }  ir_to_mesa_instruction * -ir_to_mesa_emit_op2_full(struct mbtree *tree, enum prog_opcode op, +ir_to_mesa_emit_op2_full(ir_to_mesa_visitor *v, ir_instruction *ir, +			 enum prog_opcode op,  			 ir_to_mesa_dst_reg dst,  			 ir_to_mesa_src_reg src0,  			 ir_to_mesa_src_reg src1)  { -   return ir_to_mesa_emit_op3(tree, op, dst, src0, src1, ir_to_mesa_undef); +   return ir_to_mesa_emit_op3(v, ir, +			      op, dst, src0, src1, ir_to_mesa_undef);  }  ir_to_mesa_instruction *  ir_to_mesa_emit_op2(struct mbtree *tree, enum prog_opcode op)  { -   return ir_to_mesa_emit_op2_full(tree, op, +   return ir_to_mesa_emit_op2_full(tree->v, tree->ir, op,  				   tree->dst_reg,  				   tree->left->src_reg,  				   tree->right->src_reg);  }  ir_to_mesa_instruction * -ir_to_mesa_emit_op1_full(struct mbtree *tree, enum prog_opcode op, +ir_to_mesa_emit_op1_full(ir_to_mesa_visitor *v, ir_instruction *ir, +			 enum prog_opcode op,  			 ir_to_mesa_dst_reg dst,  			 ir_to_mesa_src_reg src0)  { -   return ir_to_mesa_emit_op3(tree, op, +   return ir_to_mesa_emit_op3(v, ir, op,  			      dst, src0, ir_to_mesa_undef, ir_to_mesa_undef);  }  ir_to_mesa_instruction *  ir_to_mesa_emit_op1(struct mbtree *tree, enum prog_opcode op)  { -   return ir_to_mesa_emit_op1_full(tree, op, +   return ir_to_mesa_emit_op1_full(tree->v, tree->ir, op,  				   tree->dst_reg,  				   tree->left->src_reg);  } @@ -148,7 +156,7 @@ ir_to_mesa_emit_scalar_op1(struct mbtree *tree, enum prog_opcode op,        src.swizzle = MAKE_SWIZZLE4(src_swiz, src_swiz,  				  src_swiz, src_swiz); -      inst = ir_to_mesa_emit_op1_full(tree, op, +      inst = ir_to_mesa_emit_op1_full(tree->v, tree->ir, op,  				      dst,  				      src);        inst->dst_reg.writemask = this_mask; @@ -703,9 +711,29 @@ ir_to_mesa_visitor::visit(ir_return *ir)  void  ir_to_mesa_visitor::visit(ir_if *ir)  { -   (void)ir; -   printf("Can't support conditionals, should be flattened before here.\n"); -   exit(1); +   ir_to_mesa_instruction *if_inst, *else_inst = NULL; + +   ir->condition->accept(this); +   assert(this->result); + +   if_inst = ir_to_mesa_emit_op1_full(this, ir->condition, +				      OPCODE_IF, ir_to_mesa_undef_dst, +				      this->result->src_reg); + +   this->instructions.push_tail(if_inst); + +   visit_exec_list(&ir->then_instructions, this); + +   if (!ir->else_instructions.is_empty()) { +      else_inst = ir_to_mesa_emit_op1_full(this, ir->condition, +					   OPCODE_ELSE, ir_to_mesa_undef_dst, +					   ir_to_mesa_undef); +      visit_exec_list(&ir->then_instructions, this); +   } + +   if_inst = ir_to_mesa_emit_op1_full(this, ir->condition, +				      OPCODE_ENDIF, ir_to_mesa_undef_dst, +				      ir_to_mesa_undef);  }  ir_to_mesa_visitor::ir_to_mesa_visitor() @@ -728,12 +756,74 @@ mesa_src_reg_from_ir_src_reg(ir_to_mesa_src_reg reg)     return mesa_reg;  } +static void +set_branchtargets(struct prog_instruction *mesa_instructions, +		  int num_instructions) +{ +   int if_count = 0; +   struct prog_instruction **if_stack; +   int if_stack_pos = 0; +   int i; + +   for (i = 0; i < num_instructions; i++) { +      if (mesa_instructions[i].Opcode == OPCODE_IF) +	 if_count++; +   } + +   if_stack = (struct prog_instruction **)calloc(if_count, sizeof(*if_stack)); + +   for (i = 0; i < num_instructions; i++) { +      switch (mesa_instructions[i].Opcode) { +      case OPCODE_IF: +	 if_stack[if_stack_pos] = mesa_instructions + i; +	 if_stack_pos++; +	 break; +      case OPCODE_ELSE: +	 if_stack[if_stack_pos - 1]->BranchTarget = i; +	 if_stack[if_stack_pos - 1] = mesa_instructions + i; +	 break; +      case OPCODE_ENDIF: +	 if_stack[if_stack_pos - 1]->BranchTarget = i; +	 if_stack_pos--; +	 break; +      default: +	 break; +      } +   } + +   free(if_stack); +} + +static void +print_program(struct prog_instruction *mesa_instructions, +	      ir_instruction **mesa_instruction_annotation, +	      int num_instructions) +{ +   ir_instruction *last_ir = NULL; +   int i; + +   for (i = 0; i < num_instructions; i++) { +      struct prog_instruction *mesa_inst = mesa_instructions + i; +      ir_instruction *ir = mesa_instruction_annotation[i]; + +      if (last_ir != ir) { +	 ir_print_visitor print; +	 ir->accept(&print); +	 printf("\n"); +	 last_ir = ir; +      } + +      _mesa_print_instruction(mesa_inst); +   } +} +  void  do_ir_to_mesa(exec_list *instructions)  {     ir_to_mesa_visitor v;     struct prog_instruction *mesa_instructions, *mesa_inst; -   ir_instruction *last_ir = NULL; +   ir_instruction **mesa_instruction_annotation; +   int i;     visit_exec_list(instructions, &v); @@ -745,18 +835,15 @@ do_ir_to_mesa(exec_list *instructions)     mesa_instructions =        (struct prog_instruction *)calloc(num_instructions,  					sizeof(*mesa_instructions)); +   mesa_instruction_annotation = +      (ir_instruction **)calloc(num_instructions, +				sizeof(*mesa_instruction_annotation));     mesa_inst = mesa_instructions; +   i = 0;     foreach_iter(exec_list_iterator, iter, v.instructions) {        ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get(); -      if (last_ir != inst->ir) { -	 ir_print_visitor print; -	 inst->ir->accept(&print); -	 printf("\n"); -	 last_ir = inst->ir; -      } -        mesa_inst->Opcode = inst->op;        mesa_inst->DstReg.File = inst->dst_reg.file;        mesa_inst->DstReg.Index = inst->dst_reg.index; @@ -765,9 +852,14 @@ do_ir_to_mesa(exec_list *instructions)        mesa_inst->SrcReg[0] = mesa_src_reg_from_ir_src_reg(inst->src_reg[0]);        mesa_inst->SrcReg[1] = mesa_src_reg_from_ir_src_reg(inst->src_reg[1]);        mesa_inst->SrcReg[2] = mesa_src_reg_from_ir_src_reg(inst->src_reg[2]); - -      _mesa_print_instruction(mesa_inst); +      mesa_instruction_annotation[i] = inst->ir;        mesa_inst++; +      i++;     } + +   set_branchtargets(mesa_instructions, num_instructions); +   print_program(mesa_instructions, mesa_instruction_annotation, num_instructions); + +   free(mesa_instruction_annotation);  } diff --git a/ir_to_mesa.h b/ir_to_mesa.h index ffa27dbd00..3aa88bcdc4 100644 --- a/ir_to_mesa.h +++ b/ir_to_mesa.h @@ -148,7 +148,8 @@ ir_to_mesa_instruction *  ir_to_mesa_emit_op1(struct mbtree *tree, enum prog_opcode op);  ir_to_mesa_instruction * -ir_to_mesa_emit_op1_full(struct mbtree *tree, enum prog_opcode op, +ir_to_mesa_emit_op1_full(ir_to_mesa_visitor *v, ir_instruction *ir, +			 enum prog_opcode op,  			 ir_to_mesa_dst_reg dst,  			 ir_to_mesa_src_reg src0); @@ -156,7 +157,8 @@ ir_to_mesa_instruction *  ir_to_mesa_emit_op2(struct mbtree *tree, enum prog_opcode op);  ir_to_mesa_instruction * -ir_to_mesa_emit_op2_full(struct mbtree *tree, enum prog_opcode op, +ir_to_mesa_emit_op2_full(ir_to_mesa_visitor *v, ir_instruction *ir, +			 enum prog_opcode op,  			 ir_to_mesa_dst_reg dst,  			 ir_to_mesa_src_reg src0,  			 ir_to_mesa_src_reg src1); @@ -165,7 +167,8 @@ ir_to_mesa_instruction *  ir_to_mesa_emit_simple_op2(struct mbtree *tree, enum prog_opcode op);  ir_to_mesa_instruction * -ir_to_mesa_emit_op3(struct mbtree *tree, enum prog_opcode op, +ir_to_mesa_emit_op3(ir_to_mesa_visitor *v, ir_instruction *ir, +		    enum prog_opcode op,  		    ir_to_mesa_dst_reg dst,  		    ir_to_mesa_src_reg src0,  		    ir_to_mesa_src_reg src1, diff --git a/mesa_codegen.brg b/mesa_codegen.brg index 4e761343ae..a906542dd5 100644 --- a/mesa_codegen.brg +++ b/mesa_codegen.brg @@ -116,7 +116,7 @@ vec4: reference_vec4 0  # which would clean these up.  stmt: assign(vec4, vec4) 1  { -	ir_to_mesa_emit_op1_full(tree, OPCODE_MOV, +	ir_to_mesa_emit_op1_full(tree->v, tree->ir, OPCODE_MOV,  				 tree->left->dst_reg,  				 tree->right->src_reg);  } @@ -137,7 +137,7 @@ vec4: swizzle_vec4(vec4) 1  	}  	reg.swizzle = MAKE_SWIZZLE4(swiz[0], swiz[1], swiz[2], swiz[3]); -	ir_to_mesa_emit_op1_full(tree, OPCODE_MOV, +	ir_to_mesa_emit_op1_full(tree->v, tree->ir, OPCODE_MOV,  				 tree->dst_reg,  				 reg);  } @@ -171,7 +171,7 @@ vec4: div_vec4_vec4(vec4, vec4) 1  				   tree->dst_reg,  				   tree->right->src_reg); -	ir_to_mesa_emit_op2_full(tree, OPCODE_MUL, +	ir_to_mesa_emit_op2_full(tree->v, tree->ir, OPCODE_MUL,  				 tree->dst_reg,  				 tree->src_reg,  				 tree->left->src_reg); @@ -190,7 +190,7 @@ vec4: sqrt_vec4(vec4) 1  				   tree->dst_reg,  				   tree->left->src_reg); -	ir_to_mesa_emit_op1_full(tree, OPCODE_RCP, +	ir_to_mesa_emit_op1_full(tree->v, tree->ir, OPCODE_RCP,  				 tree->dst_reg,  				 tree->src_reg);  } | 
