diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/mesa/shader/slang/slang_codegen.c | 106 | ||||
| -rw-r--r-- | src/mesa/shader/slang/slang_emit.c | 44 | 
2 files changed, 88 insertions, 62 deletions
| diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index bd7b30cd13..6671f31c47 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -617,6 +617,21 @@ new_break(slang_ir_node *loopNode)  static slang_ir_node * +new_break_if_false(slang_ir_node *loopNode, slang_ir_node *cond) +{ +   slang_ir_node *n = new_node1(IR_BREAK_IF_FALSE, cond); +   assert(loopNode); +   assert(loopNode->Opcode == IR_LOOP); +   if (n) { +      /* insert this node at head of linked list */ +      n->BranchNode = loopNode->BranchNode; +      loopNode->BranchNode = n; +   } +   return n; +} + + +static slang_ir_node *  new_cont(slang_ir_node *loopNode)  {     slang_ir_node *n = new_node0(IR_CONT); @@ -632,6 +647,14 @@ new_cont(slang_ir_node *loopNode)  static slang_ir_node * +new_cond(slang_ir_node *n) +{ +   slang_ir_node *c = new_node1(IR_COND, n); +   return c; +} + + +static slang_ir_node *  new_if(slang_ir_node *cond, slang_ir_node *ifPart, slang_ir_node *elsePart)  {     return new_node3(IR_IF, cond, ifPart, elsePart); @@ -1290,14 +1313,6 @@ _slang_is_noop(const slang_operation *oper)  } -static slang_ir_node * -_slang_gen_cond(slang_ir_node *n) -{ -   slang_ir_node *c = new_node1(IR_COND, n); -   return c; -} - -  static void  print_funcs(struct slang_function_scope_ *scope, const char *name)  { @@ -1381,12 +1396,10 @@ _slang_gen_while(slang_assemble_ctx * A, const slang_operation *oper)     slang_ir_node *prevLoop;     /*      * LOOP: -    *    eval expr (child[0]), updating condcodes -    *    IF !expr: -    *       BRK +    *    BREAK if !expr (child[0])      *    body code (child[1])      */ -   slang_ir_node *ifThen, *cond, *body, *loop; +   slang_ir_node *loop, *cond, *breakIf, *body;     loop = new_loop(NULL); @@ -1395,19 +1408,12 @@ _slang_gen_while(slang_assemble_ctx * A, const slang_operation *oper)     A->CurLoop = loop;     cond = _slang_gen_operation(A, &oper->children[0]); -   cond = new_node1(IR_NOT, cond); -   cond = _slang_gen_cond(cond); - -   ifThen = new_if(cond, -                   new_break(A->CurLoop), -                   NULL); - +   breakIf = new_break_if_false(A->CurLoop, cond);     body = _slang_gen_operation(A, &oper->children[1]); +   loop->Children[0] = new_seq(breakIf, body); -   loop->Children[0] = new_seq(ifThen, body); - - -   A->CurLoop = prevLoop; /* pop loop, restore prev */ +   /* pop loop, restore prev */ +   A->CurLoop = prevLoop;     return loop;  } @@ -1423,11 +1429,9 @@ _slang_gen_do(slang_assemble_ctx * A, const slang_operation *oper)     /*      * LOOP:      *    body code (child[0]) -    *    eval expr (child[1]), updating condcodes -    *    IF !expr: -    *       BRK +    *    BREAK if !expr (child[1])      */ -   slang_ir_node *ifThen, *cond, *body, *loop; +   slang_ir_node *loop, *cond, *breakIf, *body;     loop = new_loop(NULL); @@ -1436,18 +1440,12 @@ _slang_gen_do(slang_assemble_ctx * A, const slang_operation *oper)     A->CurLoop = loop;     body = _slang_gen_operation(A, &oper->children[0]); -     cond = _slang_gen_operation(A, &oper->children[1]); -   cond = new_node1(IR_NOT, cond); -   cond = _slang_gen_cond(cond); +   breakIf = new_break_if_false(A->CurLoop, cond); +   loop->Children[0] = new_seq(body, breakIf); -   ifThen = new_if(cond, -                   new_break(A->CurLoop), -                   NULL); - -   loop->Children[0] = new_seq(body, ifThen); - -   A->CurLoop = prevLoop; /* pop loop, restore prev */ +   /* pop loop, restore prev */ +   A->CurLoop = prevLoop;     return loop;  } @@ -1463,13 +1461,11 @@ _slang_gen_for(slang_assemble_ctx * A, const slang_operation *oper)     /*      * init (child[0])      * LOOP: -    *    eval expr (child[1]), updating condcodes -    *    IF !expr: -    *       BRK +    *    BREAK if !expr (child[1])      *    body code (child[3])      *    incr code (child[2])   // XXX continue here      */ -   slang_ir_node *init, *ifThen, *cond, *body, *loop, *incr; +   slang_ir_node *loop, *cond, *breakIf, *body, *init, *incr;     init = _slang_gen_operation(A, &oper->children[0]);     loop = new_loop(NULL); @@ -1479,21 +1475,14 @@ _slang_gen_for(slang_assemble_ctx * A, const slang_operation *oper)     A->CurLoop = loop;     cond = _slang_gen_operation(A, &oper->children[1]); -   cond = new_node1(IR_NOT, cond); -   cond = _slang_gen_cond(cond); - -   ifThen = new_if(cond, -                   new_break(A->CurLoop), -                   NULL); - +   breakIf = new_break_if_false(A->CurLoop, cond);     body = _slang_gen_operation(A, &oper->children[3]); -     incr = _slang_gen_operation(A, &oper->children[2]); +   loop->Children[0] = new_seq(breakIf, +                               new_seq(body, incr)); -   loop->Children[0] = new_seq(ifThen, -                               new_seq(body,incr)); - -   A->CurLoop = prevLoop; /* pop loop, restore prev */ +   /* pop loop, restore prev */ +   A->CurLoop = prevLoop;     return new_seq(init, loop);  } @@ -1521,7 +1510,7 @@ _slang_gen_if(slang_assemble_ctx * A, const slang_operation *oper)     slang_atom endifAtom = slang_atom_pool_gen(A->atoms, "__endif");     cond = _slang_gen_operation(A, &oper->children[0]); -   cond = _slang_gen_cond(cond); +   cond = new_cond(cond);     /*assert(cond->Store);*/     bra = new_cjump(haveElseClause ? elseAtom : endifAtom, 0);     tree = new_seq(cond, bra); @@ -1572,7 +1561,7 @@ _slang_gen_hl_if(slang_assemble_ctx * A, const slang_operation *oper)     slang_ir_node *ifNode, *cond, *ifBody, *elseBody;     cond = _slang_gen_operation(A, &oper->children[0]); -   cond = _slang_gen_cond(cond); +   cond = new_cond(cond);     ifBody = _slang_gen_operation(A, &oper->children[1]);     if (haveElseClause)        elseBody = _slang_gen_operation(A, &oper->children[2]); @@ -1662,7 +1651,7 @@ _slang_gen_select(slang_assemble_ctx *A, slang_operation *oper)     /* eval condition */     cond = _slang_gen_operation(A, &oper->children[0]); -   cond = _slang_gen_cond(cond); +   cond = new_cond(cond);     tree = new_seq(tmpDecl, cond);     /* jump if false to "alt" label */ @@ -2245,9 +2234,6 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper)     case slang_oper_block_no_new_scope:        /* list of operations */ -      /* -      assert(oper->num_children > 0); -      */        if (oper->num_children > 0)        {           slang_ir_node *n, *tree = NULL; @@ -2287,7 +2273,7 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper)        break;     case slang_oper_expression:        return _slang_gen_operation(A, &oper->children[0]); -      break; +     case slang_oper_for:        return _slang_gen_for(A, oper);     case slang_oper_do: diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 6e2394f265..d83880a26f 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -332,6 +332,9 @@ slang_print_ir(const slang_ir_node *n, int indent)     case IR_BREAK:        printf("BREAK\n");        break; +   case IR_BREAK_IF_FALSE: +      printf("BREAK_IF_FALSE\n"); +      break;     case IR_VAR:        printf("VAR %s%s at %s  store %p\n", @@ -1153,13 +1156,17 @@ emit_loop(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)      */     for (ir = n->BranchNode; ir; ir = ir->BranchNode) {        struct prog_instruction *inst = prog->Instructions + ir->InstLocation; -      if (ir->Opcode == IR_BREAK) { +      if (ir->Opcode == IR_BREAK || +          ir->Opcode == IR_BREAK_IF_FALSE || +          ir->Opcode == IR_BREAK_IF_TRUE) {           assert(inst->Opcode == OPCODE_BRK ||                  inst->Opcode == OPCODE_BRA);           inst->BranchTarget = endInstLoc + 1;        }        else { -         assert(ir->Opcode == IR_CONT); +         assert(ir->Opcode == IR_CONT || +                ir->Opcode == IR_CONT_IF_FALSE || +                ir->Opcode == IR_CONT_IF_TRUE);           assert(inst->Opcode == OPCODE_CONT ||                  inst->Opcode == OPCODE_BRA);           /* XXX goto top of loop instead! */ @@ -1192,6 +1199,35 @@ emit_cont_break(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)  /** + * Conditional loop continue/break. + */ +static struct prog_instruction * +emit_cont_break_if(slang_var_table *vt, slang_ir_node *n, +                   struct gl_program *prog, GLboolean breakTrue) +{ +   gl_inst_opcode opcode; +   struct prog_instruction *inst; + +   /* evaluate condition expr, setting cond codes */ +   inst = emit(vt, n->Children[0], prog); +   assert(inst); +   inst->CondUpdate = GL_TRUE; + +   n->InstLocation = prog->NumInstructions; +   if (EmitHighLevelInstructions) { +      opcode = (n->Opcode == IR_CONT) ? OPCODE_CONT : OPCODE_BRK; +   } +   else { +      opcode = OPCODE_BRA; +   } +   inst = new_instruction(prog, opcode); +   inst->DstReg.CondMask = breakTrue ? COND_NE : COND_EQ; +   return inst; +} + + + +/**   * Remove any SWIZZLE_NIL terms from given swizzle mask (smear prev term).   * Ex: fix_swizzle("zyNN") -> "zyyy"   */ @@ -1407,6 +1443,10 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)     case IR_LOOP:        return emit_loop(vt, n, prog); +   case IR_BREAK_IF_FALSE: +      return emit_cont_break_if(vt, n, prog, GL_FALSE); +   case IR_BREAK_IF_TRUE: +      return emit_cont_break_if(vt, n, prog, GL_TRUE);     case IR_BREAK:        /* fall-through */     case IR_CONT: | 
