From f7159552ae12f6a47641f3325c9ece6f1c052feb Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 16 Dec 2006 12:52:19 -0700 Subject: [PATCH] Initial code for conditional constructs. --- src/mesa/shader/slang/slang_codegen.c | 67 +++++++++++++++++++++++++++-------- src/mesa/shader/slang/slang_emit.c | 28 +++++++++++++-- 2 files changed, 79 insertions(+), 16 deletions(-) diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index f62ff01..2f2b2b2 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -931,13 +931,13 @@ slang_assemble_operation(slang_assemble_ctx * A, slang_operation *oper) /* list of operations */ assert(oper->num_children > 0); { - slang_ir_node *n, *first = NULL; + slang_ir_node *n, *tree = NULL; GLuint i; for (i = 0; i < oper->num_children; i++) { n = slang_assemble_operation(A, &oper->children[i]); - first = first ? new_seq(first, n) : n; + tree = tree ? new_seq(tree, n) : n; } - return first; + return tree; } break; case slang_oper_expression: @@ -945,6 +945,7 @@ slang_assemble_operation(slang_assemble_ctx * A, slang_operation *oper) 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); @@ -953,14 +954,13 @@ slang_assemble_operation(slang_assemble_ctx * A, slang_operation *oper) slang_ir_node *nCJump = new_cjump(nNotCond, "while-end"); slang_ir_node *nJump = new_jump("while-start"); - return new_seq(nStartLabel, - new_seq(nCJump, - new_seq(nBody, - new_seq(nJump, - nEndLabel) - ) - ) - ); + 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; case slang_oper_equal: @@ -977,9 +977,20 @@ slang_assemble_operation(slang_assemble_ctx * A, slang_operation *oper) slang_assemble_operation(A, &oper->children[1])); case slang_oper_less: /* child[0] < child[1] ----> child[1] > child[0] */ +#if 0 + { + slang_ir_node *n; + assert(oper->num_children == 2); + /* XXX tranpose children */ + n = slang_assemble_function_call_name(A, "<", oper, NULL); + return n; + } +#else + /** the operands must be ints or floats, not vectors */ return new_node(IR_SGT, slang_assemble_operation(A, &oper->children[1]), slang_assemble_operation(A, &oper->children[0])); +#endif case slang_oper_greaterequal: return new_node(IR_SGE, slang_assemble_operation(A, &oper->children[0]), @@ -1101,6 +1112,15 @@ slang_assemble_operation(slang_assemble_ctx * A, slang_operation *oper) return n; } break; + case slang_oper_mulassign: + { + slang_ir_node *n; + assert(oper->num_children == 2); + /* XXX tranpose children */ + n = slang_assemble_function_call_name(A, "*=", oper, NULL); + return n; + } + break; case slang_oper_asm: return slang_assemble_asm(A, oper, NULL); case slang_oper_call: @@ -1124,6 +1144,25 @@ slang_assemble_operation(slang_assemble_ctx * A, slang_operation *oper) return n; } 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; case slang_oper_field: { slang_assembly_typeinfo ti; @@ -1214,13 +1253,13 @@ slang_assemble_operation(slang_assemble_ctx * A, slang_operation *oper) break; case slang_oper_sequence: { - slang_ir_node *top = NULL; + slang_ir_node *tree = NULL; GLuint i; for (i = 0; i < oper->num_children; i++) { slang_ir_node *n = slang_assemble_operation(A, &oper->children[i]); - top = top ? new_seq(top, n) : n; + tree = tree ? new_seq(tree, n) : n; } - return top; + return tree; } break; case slang_oper_none: diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 3d9d525..fbee314 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -930,6 +930,29 @@ emit_unop(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog) static struct prog_instruction * +emit_label(const char *target, struct gl_program *prog) +{ + struct prog_instruction *inst; + inst = new_instruction(prog, OPCODE_NOP); + inst->Comment = _mesa_strdup(target); + return inst; +} + + +static struct prog_instruction * +emit_cjump(const char *target, struct gl_program *prog) +{ + struct prog_instruction *inst; + inst = new_instruction(prog, OPCODE_BRA); + inst->DstReg.CondMask = COND_EQ; /* branch if equal to zero */ + inst->DstReg.CondSwizzle = SWIZZLE_X; + inst->Comment = _mesa_strdup(target); + return inst; +} + + + +static struct prog_instruction * emit(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog) { struct prog_instruction *inst; @@ -1045,8 +1068,7 @@ emit(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog) return emit_unop(gc, n, prog); break; case IR_LABEL: - /*printf("LAB: %s\n", n->Target);*/ - break; + return emit_label(n->Target, prog); case IR_JUMP: #if 0 inst = new_instruction(prog, OPCODE_BRA); @@ -1056,6 +1078,8 @@ emit(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog) case IR_FLOAT: n->Store = alloc_constant(n->Value, 4, prog); /*XXX fix size */ break; + case IR_CJUMP: + return emit_cjump(n->Target, prog); default: printf("emit: ?\n"); abort(); -- 2.7.4