summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2011-04-30 01:17:52 -0700
committerKenneth Graunke <[email protected]>2011-05-17 23:33:02 -0700
commit77397ef96edbc17a698ae2a02ec4807b1059c036 (patch)
tree2c615872b079086141d9303383c51e72117762f9 /src
parent64ce592679a5b08d66e3cbbf964f9e695e14aee1 (diff)
i965: Add support for loops on Ivybridge.
Signed-off-by: Kenneth Graunke <[email protected]> Reviewed-by: Eric Anholt <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/mesa/drivers/dri/i965/brw_eu_emit.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c
index fb03b62a4c9..6cfa8fb052c 100644
--- a/src/mesa/drivers/dri/i965/brw_eu_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c
@@ -1319,7 +1319,17 @@ struct brw_instruction *brw_WHILE(struct brw_compile *p,
if (intel->gen >= 5)
br = 2;
- if (intel->gen >= 6) {
+ if (intel->gen >= 7) {
+ insn = next_insn(p, BRW_OPCODE_WHILE);
+
+ brw_set_dest(p, insn, retype(brw_null_reg(), BRW_REGISTER_TYPE_D));
+ brw_set_src0(p, insn, retype(brw_null_reg(), BRW_REGISTER_TYPE_D));
+ brw_set_src1(p, insn, brw_imm_ud(0));
+ insn->bits3.break_cont.jip = br * (do_insn - insn);
+
+ insn->header.execution_size = do_insn->header.execution_size;
+ assert(insn->header.execution_size == BRW_EXECUTE_8);
+ } else if (intel->gen == 6) {
insn = next_insn(p, BRW_OPCODE_WHILE);
brw_set_dest(p, insn, brw_imm_w(0));
@@ -2277,6 +2287,7 @@ brw_find_next_block_end(struct brw_compile *p, int start)
static int
brw_find_loop_end(struct brw_compile *p, int start)
{
+ struct intel_context *intel = &p->brw->intel;
int ip;
int br = 2;
@@ -2284,7 +2295,9 @@ brw_find_loop_end(struct brw_compile *p, int start)
struct brw_instruction *insn = &p->store[ip];
if (insn->header.opcode == BRW_OPCODE_WHILE) {
- if (ip + insn->bits1.branch_gen6.jump_count / br < start)
+ int jip = intel->gen == 6 ? insn->bits1.branch_gen6.jump_count
+ : insn->bits3.break_cont.jip;
+ if (ip + jip / br < start)
return ip;
}
}
@@ -2311,7 +2324,9 @@ brw_set_uip_jip(struct brw_compile *p)
switch (insn->header.opcode) {
case BRW_OPCODE_BREAK:
insn->bits3.break_cont.jip = br * (brw_find_next_block_end(p, ip) - ip);
- insn->bits3.break_cont.uip = br * (brw_find_loop_end(p, ip) - ip + 1);
+ /* Gen7 UIP points to WHILE; Gen6 points just after it */
+ insn->bits3.break_cont.uip =
+ br * (brw_find_loop_end(p, ip) - ip + (intel->gen == 6 ? 1 : 0));
break;
case BRW_OPCODE_CONTINUE:
/* JIP is set at CONTINUE emit time, since that's when we