diff options
author | Brian <brian@yutani.localnet.net> | 2006-12-18 10:05:24 -0700 |
---|---|---|
committer | Brian <brian@yutani.localnet.net> | 2006-12-18 10:05:24 -0700 |
commit | 1aee657b0f0fb34a0d6717e47f3bdfd67de8bfc2 (patch) | |
tree | a963e0a23653cb87240994c90cd7500e6e112e73 /src/mesa/shader/slang/slang_codegen.c | |
parent | 34ae99d6049b10115ca64daecdd1d879d3b5140d (diff) |
Implement if-conditionals and while loops, added temporary resolve-branches function in linker.
Diffstat (limited to 'src/mesa/shader/slang/slang_codegen.c')
-rw-r--r-- | src/mesa/shader/slang/slang_codegen.c | 149 |
1 files changed, 103 insertions, 46 deletions
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 2f2b2b2a4e..9cfcfd45d3 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -122,10 +122,10 @@ new_seq(slang_ir_node *left, slang_ir_node *right) } static slang_ir_node * -new_label(const char *name) +new_label(slang_atom labName) { slang_ir_node *n = new_node(IR_LABEL, NULL, NULL); - n->Target = _mesa_strdup(name); + n->Target = (char *) labName; /*_mesa_strdup(name);*/ return n; } @@ -141,20 +141,20 @@ new_float_literal(float x, float y, float z, float w) } static slang_ir_node * -new_cjump(slang_ir_node *cond, const char *target) +new_cjump(slang_atom target) { - slang_ir_node *n = new_node(IR_CJUMP, cond, NULL); - n->Target = _mesa_strdup(target); + slang_ir_node *n = new_node(IR_CJUMP, NULL, NULL); + if (n) + n->Target = (char *) target; return n; } static slang_ir_node * -new_jump(const char *target) +new_jump(slang_atom target) { slang_ir_node *n = new_node(IR_JUMP, NULL, NULL); - if (n) { - n->Target = _mesa_strdup(target); - } + if (n) + n->Target = (char *) target; return n; } @@ -893,6 +893,16 @@ slang_assemble_asm(slang_assemble_ctx *A, slang_operation *oper, +static GLboolean +_slang_is_noop(const slang_operation *oper) +{ + if (!oper || + oper->type == slang_oper_void || + (oper->num_children == 1 && oper->children[0].type == slang_oper_void)) + return GL_TRUE; + else + return GL_FALSE; +} /** @@ -923,6 +933,88 @@ slang_assemble_function_call_name(slang_assemble_ctx *A, const char *name, static slang_ir_node * +_slang_gen_while(slang_assemble_ctx * A, const slang_operation *oper) +{ + /* + * label "__whileStart" + * eval expr (child[0]), updating condcodes + * branch if false to "__endWhile" + * code body + * jump "__whileStart" + * label "__endWhile" + */ + slang_atom startAtom = slang_atom_pool_gen(A->atoms, "__startWhile"); + slang_atom endAtom = slang_atom_pool_gen(A->atoms, "__endWhile"); + slang_ir_node *startLab, *cond, *bra, *body, *jump, *endLab, *tree; + + startLab = new_label(startAtom); + cond = slang_assemble_operation(A, &oper->children[0]); + tree = new_seq(startLab, cond); + + bra = new_cjump(endAtom); + tree = new_seq(tree, bra); + + body = slang_assemble_operation(A, &oper->children[1]); + tree = new_seq(tree, body); + + jump = new_jump(startAtom); + tree = new_seq(tree, jump); + + endLab = new_label(endAtom); + tree = new_seq(tree, endLab); + + return tree; +} + + +static slang_ir_node * +_slang_gen_if(slang_assemble_ctx * A, const slang_operation *oper) +{ + /* + * eval expr (child[0]), updating condcodes + * branch if false to _else or _endif + * "true" code block + * if haveElseClause clause: + * jump "__endif" + * label "__else" + * "false" code block + * label "__endif" + */ + const GLboolean haveElseClause = !_slang_is_noop(&oper->children[2]); + slang_ir_node *cond, *bra, *trueBody, *endifLab, *tree; + slang_atom elseAtom = slang_atom_pool_gen(A->atoms, "__else"); + slang_atom endifAtom = slang_atom_pool_gen(A->atoms, "__endif"); + + cond = slang_assemble_operation(A, &oper->children[0]); + /*assert(cond->Store);*/ + bra = new_cjump(haveElseClause ? elseAtom : endifAtom); + tree = new_seq(cond, bra); + + trueBody = slang_assemble_operation(A, &oper->children[1]); + tree = new_seq(tree, trueBody); + + if (haveElseClause) { + /* else clause */ + slang_ir_node *jump, *elseLab, *falseBody; + jump = new_jump(endifAtom); + tree = new_seq(tree, jump); + + elseLab = new_label(elseAtom); + tree = new_seq(tree, elseLab); + + falseBody = slang_assemble_operation(A, &oper->children[2]); + tree = new_seq(tree, falseBody); + } + + endifLab = new_label(endifAtom); + tree = new_seq(tree, endifLab); + + return tree; +} + + + +static slang_ir_node * slang_assemble_operation(slang_assemble_ctx * A, slang_operation *oper) { switch (oper->type) { @@ -944,25 +1036,7 @@ slang_assemble_operation(slang_assemble_ctx * A, slang_operation *oper) return slang_assemble_operation(A, &oper->children[0]); break; case slang_oper_while: - { - slang_ir_node *tree; - slang_ir_node *nStartLabel = new_label("while-start"); - slang_ir_node *nCond = slang_assemble_operation(A, &oper->children[0]); - slang_ir_node *nNotCond = new_node(IR_NOT, nCond, NULL); - slang_ir_node *nBody = slang_assemble_operation(A, &oper->children[1]); - slang_ir_node *nEndLabel = new_label("while-end"); - slang_ir_node *nCJump = new_cjump(nNotCond, "while-end"); - slang_ir_node *nJump = new_jump("while-start"); - - tree = new_seq(nStartLabel, nCond); - tree = new_seq(tree, nNotCond); - tree = new_seq(tree, nBody); - tree = new_seq(tree, nEndLabel); - tree = new_seq(tree, nCJump); - tree = new_seq(tree, nJump); - return tree; - } - break; + return _slang_gen_while(A, oper); case slang_oper_equal: return new_node(IR_SEQUAL, slang_assemble_operation(A, &oper->children[0]), @@ -1145,24 +1219,7 @@ slang_assemble_operation(slang_assemble_ctx * A, slang_operation *oper) } break; case slang_oper_if: - { - slang_ir_node *cond, *bra, *body, *endif, *tree; - - cond = slang_assemble_operation(A, &oper->children[0]); - /*assert(cond->Store);*/ - bra = new_node(IR_CJUMP, NULL, NULL); - bra->Target = _mesa_strdup("__endif"); - - body = slang_assemble_operation(A, &oper->children[1]); - - endif = new_label("__endif"); - - tree = new_seq(cond, bra); - tree = new_seq(tree, body); - tree = new_seq(tree, endif); - return tree; - } - break; + return _slang_gen_if(A, oper); case slang_oper_field: { slang_assembly_typeinfo ti; |