diff options
author | Qiang Yu <yuq825@gmail.com> | 2017-10-21 11:48:29 +0800 |
---|---|---|
committer | Qiang Yu <yuq825@gmail.com> | 2017-10-21 12:30:27 +0800 |
commit | cedfa2b9e0f5e931396aba934e28c3a79d670f76 (patch) | |
tree | 5d28b9d15a91d4b7db9d9e7d17017a15ef76b3ee | |
parent | 815d243346bd8a368d37e26104ec2a60e8e5c670 (diff) |
lima/ppir: add neg lower
Signed-off-by: Qiang Yu <yuq825@gmail.com>
-rw-r--r-- | src/gallium/drivers/lima/ir/pp/lower.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/src/gallium/drivers/lima/ir/pp/lower.c b/src/gallium/drivers/lima/ir/pp/lower.c index fc6796cd71..797920854f 100644 --- a/src/gallium/drivers/lima/ir/pp/lower.c +++ b/src/gallium/drivers/lima/ir/pp/lower.c @@ -91,11 +91,63 @@ static bool ppir_lower_dot(ppir_block *block, ppir_node *node) return true; } +static void merge_src(ppir_src *dst, ppir_src *src) +{ + dst->type = src->type; + dst->ssa = src->ssa; + + for (int i = 0; i < 4; i++) + dst->swizzle[i] = src->swizzle[dst->swizzle[i]]; + + dst->absolute = dst->absolute || src->absolute; + dst->negate = dst->negate ^ src->negate; +} + +static bool ppir_lower_neg(ppir_block *block, ppir_node *node) +{ + ppir_alu_node *neg = ppir_node_to_alu(node); + ppir_dest *dest = &neg->dest; + + ppir_node_foreach_succ(node, entry) { + ppir_node *succ = ppir_node_from_entry(entry, succ); + + if (succ->type != ppir_node_type_alu) + continue; + + ppir_alu_node *alu = ppir_node_to_alu(succ); + for (int i = 0; i < alu->num_src; i++) { + ppir_src *src = alu->src + i; + if (ppir_node_target_equal(src, dest)) { + merge_src(src, neg->src); + src->negate = !src->negate; + } + } + + ppir_node_remove_entry(entry); + + /* TODO: may not depend on all preceeds when reg */ + ppir_node_foreach_pred(node, entry) { + ppir_node *pred = ppir_node_from_entry(entry, pred); + ppir_node_add_child(succ, pred); + } + } + + if (ppir_node_is_root(node)) + ppir_node_delete(node); + else { + node->op = ppir_op_mov; + neg->src->negate = !neg->src->negate; + } + + return true; +} + static bool (*ppir_lower_funcs[ppir_op_num])(ppir_block *, ppir_node *) = { [ppir_op_const] = ppir_lower_const, [ppir_op_dot2] = ppir_lower_dot, [ppir_op_dot3] = ppir_lower_dot, [ppir_op_dot4] = ppir_lower_dot, + [ppir_op_neg] = ppir_lower_neg, }; bool ppir_lower_prog(ppir_compiler *comp) |