diff options
author | Alyssa Rosenzweig <[email protected]> | 2019-07-29 09:15:32 -0700 |
---|---|---|
committer | Alyssa Rosenzweig <[email protected]> | 2019-07-31 09:39:16 -0700 |
commit | 13ee87c8b99e045d8610bf801f2f15544ca4f430 (patch) | |
tree | bd7d39a439ef9bb2767fb0b29e961a072c698715 /src/panfrost | |
parent | 2037478702adab5a3863a120be821626191b2e3e (diff) |
pan/midgard: Document branch combination LUT
This took way longer to figure out than it should have..
Signed-off-by: Alyssa Rosenzweig <[email protected]>
Diffstat (limited to 'src/panfrost')
-rw-r--r-- | src/panfrost/midgard/disassemble.c | 11 | ||||
-rw-r--r-- | src/panfrost/midgard/midgard.h | 13 | ||||
-rw-r--r-- | src/panfrost/midgard/midgard_compile.c | 6 |
3 files changed, 25 insertions, 5 deletions
diff --git a/src/panfrost/midgard/disassemble.c b/src/panfrost/midgard/disassemble.c index 8387e38587c..a74280fc733 100644 --- a/src/panfrost/midgard/disassemble.c +++ b/src/panfrost/midgard/disassemble.c @@ -740,15 +740,18 @@ print_extended_branch_writeout_field(uint8_t *words) print_branch_op(br.op); - /* Condition repeated 8 times in all known cases. Check this. */ + /* Condition codes are a LUT in the general case, but simply repeated 8 times for single-channel conditions.. Check this. */ - unsigned cond = br.cond & 0x3; + bool single_channel = true; for (unsigned i = 0; i < 16; i += 2) { - assert(((br.cond >> i) & 0x3) == cond); + single_channel &= (((br.cond >> i) & 0x3) == (br.cond & 0x3)); } - print_branch_cond(cond); + if (single_channel) + print_branch_cond(br.cond & 0x3); + else + printf("lut%X", br.cond); if (br.unknown) printf(".unknown%d", br.unknown); diff --git a/src/panfrost/midgard/midgard.h b/src/panfrost/midgard/midgard.h index d0e15ce86d1..6473809d10a 100644 --- a/src/panfrost/midgard/midgard.h +++ b/src/panfrost/midgard/midgard.h @@ -359,6 +359,19 @@ __attribute__((__packed__)) unsigned dest_tag : 4; /* tag of branch destination */ unsigned unknown : 2; signed offset : 23; + + /* Extended branches permit inputting up to 4 conditions loaded into + * r31 (two in r31.w and two in r31.x). In the most general case, we + * specify a function f(A, B, C, D) mapping 4 1-bit conditions to a + * single 1-bit branch criteria. Note that the domain of f has 2^(2^4) + * elements, each mapping to 1-bit of output, so we can trivially + * construct a Godel numbering of f as a (2^4)=16-bit integer. This + * 16-bit integer serves as a lookup table to compute f, subject to + * some swaps for ordering. + * + * Interesting, the standard 2-bit condition codes are also a LUT with + * the same format (2^1-bit), but it's usually easier to use enums. */ + unsigned cond : 16; } midgard_branch_extended; diff --git a/src/panfrost/midgard/midgard_compile.c b/src/panfrost/midgard/midgard_compile.c index f3842820f3d..1efc5538b42 100644 --- a/src/panfrost/midgard/midgard_compile.c +++ b/src/panfrost/midgard/midgard_compile.c @@ -224,7 +224,11 @@ midgard_create_branch_extended( midgard_condition cond, unsigned dest_tag, signed quadword_offset) { - /* For unclear reasons, the condition code is repeated 8 times */ + /* The condition code is actually a LUT describing a function to + * combine multiple condition codes. However, we only support a single + * condition code at the moment, so we just duplicate over a bunch of + * times. */ + uint16_t duplicated_cond = (cond << 14) | (cond << 12) | |